+PmPacket::PmPacket(void)
+{
+ // table id = 02
+ SetTableId(Constants::PMT_TABLE_ID);
+ SetLength(13);
+ // program id = 1
+ SetProgramNumber(1);
+ // reserved, PcrPID
+ SetPcrPID(Constants::DEFAULT_PCR_PID);
+ // reserved, program info length
+ SetProgramDescriptorsLength(0);
+ SetPID(Constants::DEFAULT_PMT_PID);
+ RefreshCrc();
+}
+
+PmPacket::PmPacket(pByte data)throw(std::invalid_argument)
+{
+ if (GetTableId() != Constants::PMT_TABLE_ID)
+ throw std::invalid_argument("packet does not contain a valid PMT table ID");
+}
+
+DTCP_Descriptor PmPacket::GetDtcpInfo(void)
+{
+ pByte descriptors = GetProgramDescriptorsData();
+ if (!descriptors)
+ return reinterpret_cast<DTCP_Descriptor>(NULL);
+ DTCP_Descriptor dt = NULL;
+
+ for (int i = 0; i < sizeof(descriptors.get()); )
+ {
+ try
+ {
+ dt = new DTCP_Descriptor(descriptors, i);
+ break;
+ }
+ catch (std::invalid_argument)
+ {
+ i += (2 + descriptors[i + 1]);
+ }
+ }
+
+ return dt;
+}
+
+pByte PmPacket::GetProgramDescriptorsData(void)
+{
+ if (GetProgramDescriptorsLength() == 0)
+ return NULL;
+ pByte descriptors = pByte(new byte[GetProgramDescriptorsLength()]);
+ for (int i = 0; i < sizeof(descriptors.get()); i++)
+ {
+ descriptors[i] = mData[i + 17 + GetPointerSize()];
+ }
+ return descriptors;
+}
+
+void PmPacket::SetProgramDescriptorsData(pByte value)
+{
+ if (!value || 0 == sizeof(value.get()))
+ {
+ if (GetProgramDescriptorsLength() > 0)
+ {
+ // need to remove existing descriptors
+ pByte data = pByte(new byte[GetStreamInfoLength()]);
+ int index = 17 + GetProgramDescriptorsLength() + GetPointerSize();
+ // copy data between descriptor and crc
+ for (int i = 0; i < sizeof(data.get()); i++)
+ {
+ data[i] = mData[index + i];
+ mData[17 + i + GetPointerSize()] = data[i];
+ }
+ SetLength(GetLength() - GetProgramDescriptorsLength());
+ SetProgramDescriptorsLength(0);
+ RefreshCrc();
+ }
+ else
+ {
+ // nothing to do
+ return;
+ }
+ }
+ else
+ {
+ if (sizeof(value.get()) + GetLength() + GetPointerSize() + 5
+ - GetProgramDescriptorsLength() > Constants::TS_SIZE)
+ throw std::invalid_argument("program descriptors data too long");
+ // need to remove existing descriptors
+ pByte data = pByte(new byte[GetStreamInfoLength()]);
+ int index = 17 + GetProgramDescriptorsLength() + GetPointerSize();
+ // copy data between descriptor and crc
+ for (int i = 0; i < sizeof(data.get()); i++)
+ data[i] = mData[index + i];
+ SetLength(GetLength() - GetProgramDescriptorsLength());
+ SetLength(GetLength() + sizeof(value.get()));
+ SetProgramDescriptorsLength(sizeof(value.get()));
+ // copy the new descriptor
+ for (int i = 0; i < sizeof(value.get()); i++)
+ mData[17 + i + GetPointerSize()] = value[i];
+ // recover data between descriptor and crc
+ for (int i = 0; i < sizeof(data.get()); i++)
+ mData[17 + sizeof(value.get()) + i + GetPointerSize()] = data[i];
+ RefreshCrc();
+ }
+}
+
+
+// implement class BluRayOutput