00001
00021 #include <stdint.h>
00022
00023 #include <QByteArray>
00024
00025 #include "mpegdescriptors.h"
00026
00027
00028
00029
00030 class SpliceDescriptorID
00031 {
00032
00033 public:
00034 enum
00035 {
00036 avail = 0x00,
00037 dtmf = 0x01,
00038 segmentation = 0x02,
00039 };
00040 };
00041
00042 class SpliceDescriptor
00043 {
00044 public:
00045 operator const unsigned char*(void) const { return _data; }
00046
00047 SpliceDescriptor(const unsigned char *data, int len) : _data(data)
00048 {
00049 if ((len < 2) || (int(DescriptorLength()) + 2) > len)
00050 _data = NULL;
00051 }
00052 SpliceDescriptor(const unsigned char *data,
00053 int len, uint tag) : _data(data)
00054 {
00055 if ((len < 2) || (int(DescriptorLength()) + 2) > len)
00056 _data = NULL;
00057 else if (DescriptorTag() != tag)
00058 _data = NULL;
00059 }
00060 virtual ~SpliceDescriptor(void) {}
00061
00062 bool IsValid(void) const { return _data; }
00063 uint size(void) const { return DescriptorLength() + 2; }
00064
00065
00066
00067 uint DescriptorTag(void) const { return _data[0]; }
00068 QString DescriptorTagString(void) const;
00069
00070 uint DescriptorLength(void) const { return _data[1]; }
00071
00072 uint Identifier(void) const
00073 {
00074 return (_data[2]<<24) | (_data[3]<<16) | (_data[4]<<8) | _data[5];
00075 }
00076 QString IdentifierString(void) const
00077 {
00078 return QString(QChar(_data[2])) + QChar(_data[3]) +
00079 QChar(_data[4]) + QChar(_data[5]);
00080 }
00081
00082 virtual QString toString(void) const;
00083 virtual QString toStringXML(uint indent_level) const;
00084
00085 static desc_list_t Parse(const unsigned char *data, uint len);
00086 static desc_list_t ParseAndExclude(const unsigned char *data, uint len,
00087 int descriptorid);
00088 static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len,
00089 int descriptorid);
00090
00091 static const unsigned char *Find(const desc_list_t &parsed, uint desc_tag);
00092 static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag);
00093
00094 protected:
00095 virtual bool Parse(void) { return true; }
00096
00097 const unsigned char *_data;
00098 };
00099
00100 class AvailDescriptor : SpliceDescriptor
00101 {
00102 public:
00103 AvailDescriptor(const unsigned char *data, int len = 300) :
00104 SpliceDescriptor(data, len, SpliceDescriptorID::segmentation) { }
00105
00106
00107
00108
00109
00110 uint ProviderAvailId(void) const
00111 {
00112 return (_data[2]<<24) | (_data[3]<<16) | (_data[4]<<8) | _data[5];
00113 }
00114 QString ProviderAvailIdString(void) const
00115 {
00116 return QString(QChar(_data[6])) + QChar(_data[7]) +
00117 QChar(_data[8]) + QChar(_data[9]);
00118 }
00119
00120 virtual QString toString(void) const
00121 {
00122 return QString("Splice Avail: id(%1)").arg(ProviderAvailId());
00123 }
00124 };
00125
00126 class DTMFDescriptor : SpliceDescriptor
00127 {
00128 public:
00129 DTMFDescriptor(const unsigned char *data, int len = 300) :
00130 SpliceDescriptor(data, len, SpliceDescriptorID::dtmf) { }
00131
00132
00133
00134
00135
00136
00137 uint Preroll(void) const { return _data[6]; }
00138
00139 uint DTMFCount(void) const { return _data[7]>>5; }
00140
00141
00142
00143 char DTMFChar(uint i) const { return _data[8+i]; }
00144 QString DTMFString(void) const
00145 {
00146 QByteArray ba(reinterpret_cast<const char*>(_data+8), DTMFCount());
00147 return QString(ba);
00148 }
00149
00150 static bool IsParsible(const unsigned char *data, uint safe_bytes);
00151
00152 virtual QString toString(void) const
00153 {
00154 return QString("Splice DTMF: %1").arg(DTMFString());
00155 }
00156 };
00157
00158 class SegmentationDescriptor : SpliceDescriptor
00159 {
00160 public:
00161 SegmentationDescriptor(const unsigned char *data, int len = 300) :
00162 SpliceDescriptor(data, len, SpliceDescriptorID::segmentation)
00163 {
00164 _ptrs[2] = _ptrs[1] = _ptrs[0] = NULL;
00165 if (_data && !Parse())
00166 _data = NULL;
00167 }
00168
00169
00170
00171
00172
00173
00174 uint SegmentationEventId(void) const
00175 {
00176 return (_data[2]<<24) | (_data[3]<<16) | (_data[4]<<8) | _data[5];
00177 }
00178 QString SegmentationEventIdString(void) const
00179 {
00180 return QString(QChar(_data[6])) + QChar(_data[7]) +
00181 QChar(_data[8]) + QChar(_data[9]);
00182 }
00183
00184 bool IsSegmentationEventCancel(void) const { return _data[10] & 0x80; }
00185
00186
00187
00188 bool IsProgramSegmentation(void) const { return _data[11] & 0x80; }
00189
00190 bool HasSegmentationDuration(void) const { return _data[11] & 0x40; }
00191
00192
00193
00194 uint ComponentCount(void) const { return _data[12]; }
00195
00196
00197 uint ComponentTag(uint i) const { return _data[13 + i * 6]; }
00198
00199
00200 uint64_t PTSOffset(uint i)
00201 {
00202 return ((uint64_t(_data[14+(i*6)] & 0x1) << 32) |
00203 (uint64_t(_data[15+(i*6)]) << 24) |
00204 (uint64_t(_data[16+(i*6)]) << 16) |
00205 (uint64_t(_data[17+(i*6)]) << 8) |
00206 (uint64_t(_data[18+(i*6)])));
00207 }
00208
00209
00210
00211
00212 uint64_t SegmentationDuration(void) const
00213 {
00214 return ((uint64_t(_ptrs[0][0]) << 32) |
00215 (uint64_t(_ptrs[0][1]) << 24) |
00216 (uint64_t(_ptrs[0][2]) << 16) |
00217 (uint64_t(_ptrs[0][3]) << 8) |
00218 (uint64_t(_ptrs[0][4])));
00219 }
00220
00221 enum
00222 {
00223 kNotUsed = 0x0,
00224 kVariable = 0x1,
00225 kISCI = 0x2,
00226 kAdID = 0x3,
00227 kUMID = 0x4,
00228 kISAN = 0x5,
00229 kVISAN = 0x6,
00230 kTID = 0x7,
00231 kTI = 0x8,
00232 kADI = 0x9,
00233 };
00234 uint SegmentationUPIDType(void) const { return _ptrs[1][0]; }
00235
00236 uint SegmentationUPIDLength(void) const
00237 { return _ptrs[1][1]; }
00238
00239 const unsigned char *SegmentationUPID(void) const
00240 {
00241 return _ptrs[1]+2;
00242 }
00243 QString SegmentationUPIDString(void) const
00244 {
00245 QByteArray ba(reinterpret_cast<const char*>(_ptrs[1]+2),
00246 SegmentationUPIDLength());
00247 return QString(ba);
00248 }
00249
00250 enum
00251 {
00252 kNotIndicated = 0x00,
00253 kContentIdentification = 0x01,
00254 kProgramStart = 0x10,
00255 kProgramEnd = 0x11,
00256 kProgramEarlyTermination = 0x12,
00257 kProgramBreakaway = 0x13,
00258 kProgramResumption = 0x14,
00259 kProgramRunoverPlanned = 0x15,
00260 kProgramRunoverUnplanned = 0x16,
00261 kChapterStart = 0x20,
00262 kChapterEnd = 0x21,
00263 kProviderAdvertisementStart = 0x30,
00264 kProviderAdvertisementEnd = 0x31,
00265 kDistributorAdvertisementStart = 0x32,
00266 kDistributorAdvertisementEnd = 0x33,
00267 kUnscheduledEventStart = 0x40,
00268 kUnscheduledEventEnd = 0x41,
00269 };
00270
00271 uint SegmentationTypeID(void) const { return _ptrs[2][0]; }
00272
00273 uint SegmentNum(void) const { return _ptrs[2][1]; }
00274
00275 uint SegmentsExpected(void) const { return _ptrs[2][2]; }
00276
00277
00278 virtual bool Parse(void);
00279 QString toString(void) const;
00280
00281
00282
00283
00284 unsigned char const * _ptrs[3];
00285 };