StreamInfo::StreamInfo(pByte data, int index)throw(std::invalid_argument)
{
- if (NULL == data) {
- throw std::invalid_argument("stream data is NULL");
- }
+ if(NULL == data)
+ throw std::invalid_argument("stream data is NULL");
- if (std::strlen(data.get()) + index < 5) {
- throw std::invalid_argument("stream data too short");
- }
+ if(std::strlen(reinterpret_cast<char*>(data.get())) + index < 5)
+ throw std::invalid_argument("stream data too short");
uint descLength = (uint)((data[3 + index] & 0x0f) << 8) + data[4 + index];
- if (descLength > Constants::TS_SIZE) {
- throw std::invalid_argument("descriptors data too long");
- }
+ if(descLength > Constants::TS_SIZE)
+ throw std::invalid_argument("descriptors data too long");
- if (5 + descLength > std::strlen(data.get()) - index) {
- throw std::invalid_argument("stream data too short");
+ if(5 + descLength
+ > std::strlen(reinterpret_cast<char*>(data.get())) - index)
+ {
+ throw std::invalid_argument("stream data too short");
}
mData.clear();
pByte StreamInfo::GetElementaryDescriptors(void)
{
- if(mData.size() == 5) return (pByte)NULL;
- pByte descriptors = pByte(new byte[mData.size() - 5]);
- for (int i = 0; i < (mData.size() - 5); i++)
+ pByte descriptors;
+ if(mData.size() == 5)
{
- descriptors[i] = mData[i + 5];
+ descriptors.reset();
+ }
+ else
+ {
+ descriptors = pByte(new byte[mData.size() - 5]);
+ for (int i = 0; i < (mData.size() - 5); i++)
+ {
+ descriptors[i] = mData[i + 5];
+ }
}
return descriptors;
}
data.push_back(mData.at(1));
data.push_back(mData.at(2));
data.push_back(
- (byte)(0xf0 | (byte)((std::strlen(value.get()) >> 8) & 0x0f)));
- data.push_back(std::strlen(value.get()) & 0xff);
- for (int i = 0; i < std::strlen(value.get()); i++)
+ (byte)(0xf0
+ | (byte)((std::strlen(reinterpret_cast<char*>(value.get())) >> 8)
+ & 0x0f)));
+ data.push_back(std::strlen(reinterpret_cast<char*>(value.get())) & 0xff);
+ for (int i = 0;
+ i < std::strlen(reinterpret_cast<char*>(value.get())); i++)
{
data.push_back(value[i]);
}
{
if (NULL == data)
throw std::invalid_argument("NULL packet");
- else if (Constants::TS_SIZE > std::strlen(data.get()) - startIndex)
+ else if (Constants::TS_SIZE
+ > std::strlen(reinterpret_cast<char*>(data.get())) - startIndex)
throw std::invalid_argument("small packet");
else if (Constants::SYNC_BYTE != data[0 + startIndex])
throw std::invalid_argument("sync byte missing");
pByte TsPacket::Payload(void)
{
+ pByte ret;
+ ret.reset();
int offset = 4;
if ((mData[3] & 0x20) > 0)
{
// adaptation field present
offset += (1 + mData[4]);
if (offset >= Constants::TS_SIZE)
- return (pByte)NULL;
+ return ret;
}
if ((mData[3] & 0x10) > 0)
{
// payload present
- pByte ret = pByte(new byte[Constants::TS_SIZE - offset]);
+ ret = pByte(new byte[Constants::TS_SIZE - offset]);
for (int i = 0; i < sizeof(ret); i++)
ret[i] = mData[i + offset];
ret[Constants::TS_SIZE - offset] = '\0';
return ret;
}
- return (pByte)NULL;
+ return ret;
}
void TsPacket::IncrementContinuityCounter(void)
Descriptor::Descriptor(pByte data, int startIndex)throw(std::invalid_argument)
{
- if (strlen(data.get()) < 2)
+ if (strlen(reinterpret_cast<char*>(data.get())) < 2)
throw std::invalid_argument("Invalid descriptor");
- if (startIndex + 2 + data[startIndex + 1] > strlen(data.get()))
+ if (startIndex + 2 + data[startIndex + 1]
+ > strlen(reinterpret_cast<char*>(data.get())))
throw std::invalid_argument("Invalid descriptor");
mData.clear();
for (int i = 0; i < (2 + data[startIndex + 1]); i++)
{
boost::shared_ptr<PesHeader> ph = GetHeader();
if(ph == NULL) return GetData();
- pByte buff = pByte(new byte[mData.size()-(9 + ph->HeaderLength)+1]);
- for(int i=(9 + ph->HeaderLength); i < mData.size(); i++)
+ pByte buff = pByte(new byte[mData.size() - 9 + ph.get()->GetHeaderLength() + 1]);
+ for(int i=(9 + ph.get()->GetHeaderLength()); i < mData.size(); i++)
buff[i] = mData.at(i);
- buff[mData.size()-(9 + ph->HeaderLength)] = '\0';
+ buff[mData.size()-(9 + ph.get()->GetHeaderLength())] = '\0';
return buff;
}
boost::shared_ptr<PesHeader> PesPacket::GetHeader(void)
{
+ boost::shared_ptr<PesHeader> ph;
try
{
- boost::shared_ptr<PesHeader> ph
- = boost::shared_ptr<PesHeader>(
+ ph = boost::shared_ptr<PesHeader>(
new PesHeader(Utility::ToArray(mData)));
return ph;
}
catch(...)
{
// no valid header (yet)
- return (boost::shared_ptr<PesHeader>)NULL;
+ ph.reset();
+ return ph;
}
}
return 0;
}
+PesHeader::PesHeader(pByte data)throw(std::invalid_argument)
+{
+ if (sizeof(data.get()) < 9)
+ throw std::invalid_argument("Invalid PES header length");
+ if (data[0] != 0x00 || data[1] != 0x00 || data[2] != 0x01)
+ throw std::invalid_argument("Invalid PES prefix");
+ int hlen = 9 + data[8];
+ int plen = 6 + (data[4] << 8) + data[5];
+ if (plen != 6 && hlen > plen)
+ throw new std::invalid_argument("Invalid PES header/packet length");
+ if (sizeof(data.get()) < hlen)
+ throw std::invalid_argument("PES Header too short");
+ mData.clear();
+ for (int i = 0; i < hlen; i++)
+ mData.push_back(data[i]);
+}
+
+byte PesHeader::GetStreamId(void)
+{
+ return mData[3];
+}
+
+byte PesHeader::GetByte(int i)
+{
+ return mData.at(i);
+}
+
+void PesHeader::SetByte(int i, byte data)
+{
+ mData[i] = data;
+}
+
+byte PesHeader::GetHeaderLength(void)
+{
+ return mData.at(8);
+}
+
+int PesHeader::GetTotalHeaderLength(void)
+{
+ return 9 + GetHeaderLength();
+}
+
+ushort PesHeader::GetPacketLength(void)
+{
+ return (ushort)((mData.at(4) << 8) + mData.at(5));
+}
+
+bool PesHeader::HasPts(void)
+{
+ if(mData.size() > 13)
+ return (mData.at(7) & 0x80) > 0;
+ return false;
+}
+
+bool PesHeader::HasDts(void)
+{
+ if(mData.size() > 18 )
+ return (mData.at(7) & 0x40) > 0;
+ return false;
+}
+
+Int64 PesHeader::GetPts(void)throw(std::invalid_argument)
+{
+ if (HasPts() == false)
+ throw std::invalid_argument("No Pts available");
+ Int64 ret = 0;
+ ret += ((Int64)(mData[9] & 0x0e)) << 29;
+ ret += ((Int64)(mData[10])) << 22;
+ ret += ((Int64)(mData[11] & 0xfe)) << 14;
+ ret += ((Int64)(mData[12])) << 7;
+ ret += ((Int64)(mData[13] & 0xfe)) >> 1;
+ return ret;
+}
+
+void PesHeader::SetPts(Int64 value)throw(std::invalid_argument)
+{
+ if (HasPts() == false)
+ throw std::invalid_argument("No Pts available");
+ byte old = (byte)(mData.at(9) & 0xf1);
+ mData[9] = (byte)(((value & 0x1C0000000LL) >> 29) | old);
+ mData[10] = (byte)((value & 0x3fC00000LL) >> 22);
+ mData[11] = (byte)(((value & 0x3f8000LL) >> 14) | 0x01);
+ mData[12] = (byte)((value & 0x7f80LL) >> 7);
+ mData[13] = (byte)(((value & 0x7fLL) << 1) | 0x01);
+}
+
+Int64 PesHeader::GetDts(void)throw(std::invalid_argument)
+{
+ if (HasDts() == false)
+ throw std::invalid_argument("No Dts available");
+ Int64 ret = 0;
+ ret += ((Int64)(mData[14] & 0x0e)) << 29;
+ ret += ((Int64)(mData[15])) << 22;
+ ret += ((Int64)(mData[16] & 0xfe)) << 14;
+ ret += ((Int64)(mData[17])) << 7;
+ ret += ((Int64)(mData[18] & 0xfe)) >> 1;
+ return ret;
+}
+
+void PesHeader::SetDts(Int64 value)throw(std::invalid_argument)
+{
+ if (HasDts() == false)
+ throw std::invalid_argument("No Dts available");
+ byte old = (byte)(mData[14] & 0xf1);
+ mData[14] = (byte)(((value & 0x1C0000000LL) >> 29) | old);
+ mData[15] = (byte)((value & 0x3fC00000LL) >> 22);
+ mData[16] = (byte)(((value & 0x3f8000LL) >> 14) | 0x01);
+ mData[17] = (byte)((value & 0x7f80LL) >> 7);
+ mData[18] = (byte)(((value & 0x7fLL) << 1) | 0x01);
+}
+
+byte PesHeader::GetExtention2(void)
+{
+ int offset = 6;
+ if((mData.at(offset) & 0xc0) != 0x80)
+ return 0; // first two bits must be '10'
+ byte PTS_DTS_flags = (byte)(mData.at(offset + 1) & 0xc0);
+ byte ESCR_flag = (byte)(mData.at(offset + 1) & 0x20);
+ byte ES_rate_flag = (byte)(mData.at(offset + 1) & 0x10);
+ byte DSM_trick_mode_flag = (byte)(mData.at(offset + 1) & 0x08);
+ byte additional_copy_info_flag = (byte)(mData.at(offset + 1) & 0x04);
+ byte PES_CRC_flag = (byte)(mData.at(offset + 1) & 0x02);
+ byte PES_extension_flag = (byte)(mData.at(offset + 1) & 0x01);
+ if(mData.at(offset + 2) == 0)
+ return 0;
+ int length = offset + mData.at(offset + 2) + 3;
+ if(mData.size() < length)
+ return 0;
+ offset += 3;
+ if(PTS_DTS_flags == 0x80)
+ offset += 5;
+ if(PTS_DTS_flags == 0xc0)
+ offset += 10;
+ if(ESCR_flag > 0)
+ offset += 6;
+ if(ES_rate_flag > 0)
+ offset += 3;
+ if(DSM_trick_mode_flag > 0)
+ offset += 1;
+ if(additional_copy_info_flag > 0)
+ offset += 1;
+ if(PES_CRC_flag > 0)
+ offset += 2;
+ if(PES_extension_flag == 0)
+ return 0;
+ byte PES_private_data_flag = (byte)(mData.at(offset) & 0x80);
+ byte pack_header_field_flag = (byte)(mData.at(offset) & 0x40);
+ byte program_packet_sequence_counter_flag
+ = (byte)(mData.at(offset) & 0x20);
+ byte PSTD_mDataer_flag = (byte)(mData.at(offset) & 0x10);
+ byte PES_extension_flag_2 = (byte)(mData.at(offset) & 0x01);
+ offset++;
+ if(PES_private_data_flag > 0)
+ offset += 25;
+ if(pack_header_field_flag > 0)
+ offset += (mData.at(offset) + 1);
+ if(program_packet_sequence_counter_flag > 0)
+ offset += 2;
+ if(PSTD_mDataer_flag > 0)
+ offset += 2;
+ if(PES_extension_flag_2 == 0)
+ return 0;
+ if(mData[offset] != 0x81)
+ return 0;
+ return mData.at(offset + 1);
+}
+
+pByte PesHeader::GetData(void)
+{
+ return Utility::ToArray(mData);
+}
+
+// implement class BluRayOutput
+// implement class DTCP_Descriptor : Descriptor
+// implement class PatPacket : TsTable
+// implement class SitPacket : TsTable
+// implement class PmPacket : TsTable
+// implement class VC1SequenceInfo
+// implement class H264Info
+// implement class AC3Info : ElementaryParse
+// implement class DtsInfo : ElementaryParse
+// implement class MlpInfo : ElementaryParse
+// implement class Mpeg2Info : ElementaryParse
+
+
} // namespace