OSDN Git Service

implement PesHeader class in Utils
authorcocot <cocot@users.sourceforge.jp>
Sat, 28 Feb 2009 15:17:39 +0000 (00:17 +0900)
committercocot <cocot@users.sourceforge.jp>
Sat, 28 Feb 2009 15:17:39 +0000 (00:17 +0900)
src/Utils.cc
src/Utils.h
src/tsremuxcpp_define.h

index 0ecaa59..72623d3 100644 (file)
@@ -162,22 +162,21 @@ pByte Utility::ToArray(const Bytes vector)
 
 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();
@@ -283,11 +282,18 @@ void StreamInfo::SetElementaryPID(ushort pid)
 
 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;
 }
@@ -325,9 +331,12 @@ void StreamInfo::SetElementaryDescriptors(pByte value)
         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]);
         }
@@ -404,7 +413,8 @@ void TsPacket::SetData(pByte data, int startIndex)throw(std::invalid_argument)
 {
     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");
@@ -470,24 +480,26 @@ bool TsPacket::HasPesHeader(void)
 
 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)
@@ -604,9 +616,10 @@ void TsTable::RefreshCrc(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++)
@@ -682,10 +695,10 @@ pByte PesPacket::GetPayload(void)
 {
     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;
 }
 
@@ -732,17 +745,18 @@ void PesPacket::SetComplete(bool value)
 
 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;
     }
 }
 
@@ -789,6 +803,191 @@ UInt32 PesPacket::GetExtendedType(void)
     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
 
 
index 4babdca..93605c6 100644 (file)
@@ -358,19 +358,21 @@ class PmPacket : TsTable {
 
 class PesHeader {
  public:
-  PesHeader(pByte data);
-  byte StreamId;
+  PesHeader(pByte data)throw(std::invalid_argument);
+  byte GetStreamId(void);
   byte GetByte(int i);
-  void SetByte(byte dat);
-  byte HeaderLength;
-  int TotalHeaderLength;
-  ushort PacketLength;
-  bool HasPts;
-  bool HasDts;
-  Int64 Pts;
-  Int64 Dts;
-  byte Extention2;
-  Bytes Data;
+  void SetByte(int i, byte dat);
+  byte GetHeaderLength(void);
+  int GetTotalHeaderLength(void);
+  ushort GetPacketLength(void);
+  bool HasPts(void);
+  bool HasDts(void);
+  Int64 GetPts(void)throw(std::invalid_argument);
+  void SetPts(Int64 value)throw(std::invalid_argument);
+  Int64 GetDts(void)throw(std::invalid_argument);
+  void SetDts(Int64 value)throw(std::invalid_argument);
+  byte GetExtention2(void);
+  pByte GetData(void);
  private:
   Bytes mData;
 };
index e22e2d3..17a8428 100644 (file)
@@ -3,12 +3,13 @@
 
 #include <time.h>
 #include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
 #include <vector>
 
 #define readonly const
 
 namespace TsRemux {
-    typedef char byte;
+    typedef unsigned char byte;
     typedef unsigned short ushort;
     typedef unsigned int uint;
     typedef unsigned int UInt32;