00001
00002
00003 #ifndef _MPEG_TABLES_H_
00004 #define _MPEG_TABLES_H_
00005
00006 #include <cassert>
00007 #include "mpegdescriptors.h"
00008 #include "pespacket.h"
00009 #include "mythtvexp.h"
00010 #include "mythmiscutil.h"
00011
00028 #define GPS_EPOCH 315964800
00029
00031 #define GPS_LEAP_SECONDS 14
00032
00033
00037 class MTV_PUBLIC PESStreamID
00038 {
00039 public:
00040 enum
00041 {
00042 PictureStartCode = 0x00,
00043 SliceStartCodeBegin = 0x01,
00044 SliceStartCodeEnd = 0xaf,
00045 DVBECMData = 0xb0,
00046 DVBEMMData = 0xb1,
00047 UserData = 0xb2,
00049 SequenceStartCode = 0xb3,
00050 SequenceError = 0xb4,
00052 MPEG2ExtensionStartCode = 0xb5,
00053 MPEGReservedB6 = 0xb6,
00054 SEQEndCode = 0xb7,
00058 GOPStartCode = 0xb8,
00059 ProgramEndCode = 0xb9,
00060 PackHeader = 0xba,
00061 SystemHeader = 0xbb,
00062 ProgramStreamMap = 0xbc,
00064 NonMPEGAudioVideo = 0xbd,
00065 PaddingStream = 0xbe,
00067 DVDNavigation = 0xbf,
00069 MPEGAudioStreamBegin = 0xc0,
00071 MPEGAudioStreamEnd = 0xdf,
00073 MPEGVideoStreamBegin = 0xe0,
00075 MPEGVideoStreamEnd = 0xef,
00076 ECMData = 0xf0,
00077 EMMData = 0xf1,
00078 DSMCCData = 0xf2,
00080 Data13522 = 0xf3,
00082 DataH2221Begin = 0xf4,
00084 DataH2221End = 0xf8,
00085 AncillaryData = 0xf9,
00086 MPEGReservedFA = 0xfa,
00087 FlexMux = 0xfb,
00088 MPEGReservedFC = 0xfc,
00089 MPEGReservedFD = 0xfd,
00090 MPEGReservedFE = 0xfe,
00091 ProgramStreamDirectory = 0xff,
00092 };
00093 };
00094
00095
00102 class MTV_PUBLIC StreamID
00103 {
00104 public:
00105 enum
00106 {
00107
00108 MPEG1Video = 0x01,
00109 MPEG2Video = 0x02,
00110 MPEG4Video = 0x10,
00111 H264Video = 0x1b,
00112 OpenCableVideo = 0x80,
00113 VC1Video = 0xea,
00114
00115
00116 MPEG1Audio = 0x03,
00117 MPEG2Audio = 0x04,
00118 MPEG2AACAudio = 0x0f,
00119 MPEG2AudioAmd1 = 0x11,
00120 AC3Audio = 0x81,
00121 DTSAudio = 0x8a,
00122
00123
00124 DSMCC = 0x08,
00125 DSMCC_A = 0x0a,
00126 DSMCC_B = 0x0b,
00127 DSMCC_C = 0x0c,
00128 DSMCC_D = 0x0d,
00129 DSMCC_DL = 0x14,
00130 MetaDataPES = 0x15,
00131 MetaDataSec = 0x16,
00132 MetaDataDC = 0x17,
00133 MetaDataOC = 0x18,
00134 MetaDataDL = 0x19,
00135
00136
00137 PrivSec = 0x05,
00138 PrivData = 0x06,
00139
00140 MHEG = 0x07,
00141 H222_1 = 0x09,
00142
00143 MPEG2Aux = 0x0e,
00144
00145 FlexMuxPES = 0x12,
00146 FlexMuxSec = 0x13,
00147
00148 MPEG2IPMP = 0x1a,
00149 MPEG2IPMP2 = 0x7f,
00150
00151 Splice = 0x86,
00152
00153
00154 AnyMask = 0xFFFF0000,
00155 AnyVideo = 0xFFFF0001,
00156 AnyAudio = 0xFFFF0002,
00157 };
00159 static bool IsVideo(uint type)
00160 {
00161 return ((StreamID::MPEG1Video == type) ||
00162 (StreamID::MPEG2Video == type) ||
00163 (StreamID::MPEG4Video == type) ||
00164 (StreamID::H264Video == type) ||
00165 (StreamID::VC1Video == type) ||
00166 (StreamID::OpenCableVideo == type));
00167 }
00169 static bool IsAudio(uint type)
00170 {
00171 return ((StreamID::MPEG1Audio == type) ||
00172 (StreamID::MPEG2Audio == type) ||
00173 (StreamID::MPEG2AudioAmd1 == type) ||
00174 (StreamID::MPEG2AACAudio == type) ||
00175 (StreamID::AC3Audio == type) ||
00176 (StreamID::DTSAudio == type));
00177 }
00179 static bool IsObjectCarousel(uint type)
00180 {
00181 return ((StreamID::DSMCC_A == type) ||
00182 (StreamID::DSMCC_B == type) ||
00183 (StreamID::DSMCC_C == type) ||
00184 (StreamID::DSMCC_D == type));
00185 }
00186 static uint Normalize(uint stream_id, const desc_list_t &desc,
00187 const QString &sistandard);
00188 static const char* toString(uint streamID);
00189 static QString GetDescription(uint streamID);
00190 };
00191
00192 enum
00193 {
00194 MPEG_PAT_PID = 0x0000,
00195 MPEG_CAT_PID = 0x0001,
00196 MPEG_TSDT_PID = 0x0002,
00197
00198 DVB_NIT_PID = 0x0010,
00199 DVB_SDT_PID = 0x0011,
00200 DVB_EIT_PID = 0x0012,
00201 DVB_RST_PID = 0x0013,
00202 DVB_TDT_PID = 0x0014,
00203
00204
00205 DVB_DNLONG_EIT_PID = 0x0300,
00206
00207
00208 DVB_BVLONG_EIT_PID = 0x0441,
00209
00210
00211 PREMIERE_EIT_DIREKT_PID = 0x0b11,
00212 PREMIERE_EIT_SPORT_PID = 0x0b12,
00213
00214 ATSC_PSIP_PID = 0x1ffb,
00215
00216 SCTE_PSIP_PID = 0x1ffc,
00217
00218
00219 FREESAT_SI_PID = 0x0f01,
00220 FREESAT_EIT_PID = 0x0f02,
00221 FREESAT_ST_EIT_PID = 0x0f03,
00222 };
00223
00227 class MTV_PUBLIC TableID
00228 {
00229 public:
00230 enum
00231 {
00232 PAT = 0x00,
00233 CAT = 0x01,
00234 PMT = 0x02,
00235 TSDT = 0x03,
00236
00237
00238 NIT = 0x40,
00239 SDT = 0x42,
00240 PF_EIT = 0x4e,
00241 TDT = 0x70,
00242
00243
00244 NITo = 0x41,
00245 SDTo = 0x46,
00246 BAT = 0x4a,
00247 PF_EITo = 0x4f,
00248 SC_EITbeg = 0x50,
00249 SC_EITend = 0x5f,
00250 SC_EITbego = 0x60,
00251 SC_EITendo = 0x6f,
00252 RST = 0x71,
00253 ST = 0x72,
00254 TOT = 0x73,
00255 RNT = 0x74,
00256 CT = 0x75,
00257 RCT = 0x76,
00258 CIT = 0x77,
00259 MPEFEC = 0x78,
00260 DIT = 0x7e,
00261 SIT = 0x7f,
00262
00263
00264 DVBCAbeg = 0x80,
00265 DVBCAend = 0x8f,
00266
00267
00268 DN_EITbego = 0x80,
00269 DN_EITendo = 0xfe,
00270
00271
00272 ARIBbeg = 0x80,
00273 ARIBend = 0x8f,
00274
00275
00276 PIM = 0xC0,
00277 PNM = 0xC1,
00278
00279
00280
00281
00282
00283
00284 NIM = 0xC2,
00285 NTM = 0xC3,
00286
00287
00288
00289
00290 VCM = 0xC4,
00291 STM = 0xC5,
00292
00293
00294 NITscte = 0xC2,
00295 NTT = 0xC3,
00296 SVCTscte = 0xC4,
00297 STTscte = 0xC5,
00298
00299
00300 SM = 0xC6,
00301 CEA = 0xD8,
00302 ADET = 0xD9,
00303
00304
00305 SITscte = 0xFC,
00306
00307
00308 ECM0 = 0x80,
00309 ECM1 = 0x81,
00310 ECMbeg = 0x82,
00311 ECMend = 0x8f,
00312
00313
00314 MGT = 0xC7,
00315 TVCT = 0xC8,
00316 CVCT = 0xC9,
00317 RRT = 0xCA,
00318 EIT = 0xCB,
00319 ETT = 0xCC,
00320 STT = 0xCD,
00321 DET = 0xCE,
00322 DST = 0xCF,
00323
00324 PIT = 0xD0,
00325 NRT = 0xD1,
00326 LTST = 0xD2,
00327 DCCT = 0xD3,
00328 DCCSCT = 0xD4,
00329 SITatsc = 0xD5,
00330 AEIT = 0xD6,
00331 AETT = 0xD7,
00332 SVCT = 0xDA,
00333
00334 SRM = 0xE0,
00335
00336
00337 STUFFING = 0x80,
00338 CAPTION = 0x86,
00339 CENSOR = 0x87,
00340
00341
00342 PREMIERE_CIT = 0xA0,
00343 PREMIERE_CPT = 0xA1,
00344
00345 ECN = 0xA0,
00346 SRVLOC = 0xA1,
00347 TSS = 0xA2,
00348 CMPNAME = 0xA3,
00349 };
00350 };
00351
00356 class MTV_PUBLIC PSIPTable : public PESPacket
00357 {
00358 private:
00359
00360 PSIPTable(const PESPacket& pkt, bool)
00361 : PESPacket(reinterpret_cast<const TSPacket*>(pkt.tsheader()), false)
00362 { ; }
00363 public:
00364 PSIPTable(const PSIPTable& table) : PESPacket(table)
00365 {
00366
00367
00368 }
00369 PSIPTable(const PESPacket& table) : PESPacket(table)
00370 {
00371
00372
00373 }
00374 PSIPTable(const TSPacket& table) : PESPacket(table)
00375 {
00376
00377
00378 }
00379
00380
00381 static const PSIPTable View(const TSPacket& tspacket)
00382 { return PSIPTable(PESPacket::View(tspacket), false); }
00383
00384 static PSIPTable View(TSPacket& tspacket)
00385 { return PSIPTable(PESPacket::View(tspacket), false); }
00386
00387
00388
00389
00390 uint TableID(void) const { return StreamID(); }
00391
00392
00393 bool SectionSyntaxIndicator(void) const { return pesdata()[1] & 0x80; }
00394
00395 bool PrivateIndicator(void) const { return pesdata()[1] & 0x40; }
00396
00397
00398
00399
00400
00401 uint SectionLength(void) const { return Length() + 3; }
00402
00404
00405
00406
00407 uint TableIDExtension(void) const
00408 { return (pesdata()[3]<<8) | pesdata()[4]; }
00409
00410
00411
00412
00413
00414 uint Version(void) const { return (pesdata()[5]>>1) & 0x1f; }
00415
00416
00417
00418
00419
00420 bool IsCurrent(void) const { return bool(pesdata()[5]&1); }
00421
00422
00423 uint Section(void) const { return pesdata()[6]; }
00424
00425
00426 uint LastSection(void) const { return pesdata()[7]; }
00427
00428
00429
00430 uint ATSCProtocolVersion(void) const { return pesdata()[8]; }
00431
00432
00433 const unsigned char* psipdata(void) const
00434 { return pesdata() + PSIP_OFFSET; }
00435 unsigned char* psipdata(void)
00436 { return pesdata() + PSIP_OFFSET; }
00437
00438
00439 void SetTableID(uint id) { SetStreamID(id); }
00440
00441
00442 void SetSectionLength(uint length) { SetLength(length-3); }
00443 void SetTableIDExtension(uint len)
00444 {
00445 pesdata()[3] = (len>>8) & 0xff;
00446 pesdata()[4] = len & 0xff;
00447 }
00448 void SetVersionNumber(uint ver)
00449 { pesdata()[5] = (pesdata()[5] & 0xc1) | ((ver & 0x1f)<<1); }
00450 void SetCurrent(bool cur)
00451 { pesdata()[5] = (pesdata()[5] & 0xfe) | (cur ? 1 : 0); }
00452 void SetSection(uint num) { pesdata()[6] = num; }
00453 void SetLastSection(uint num) { pesdata()[7] = num; }
00454
00455
00456 void SetATSCProtocolVersion(int ver) { pesdata()[8] = ver; }
00457
00458 bool HasCRC(void) const;
00459 bool HasSectionNumber(void) const;
00460
00461 bool VerifyPSIP(bool verify_crc) const;
00462
00463 virtual QString toString(void) const;
00464 virtual QString toStringXML(uint indent_level) const;
00465
00466 static const uint PSIP_OFFSET = 8;
00467
00468 protected:
00469 QString XMLValues(uint indent_level) const;
00470 };
00471
00490 class MTV_PUBLIC ProgramAssociationTable : public PSIPTable
00491 {
00492 public:
00493 ProgramAssociationTable(const ProgramAssociationTable& table)
00494 : PSIPTable(table)
00495 {
00496 assert(TableID::PAT == TableID());
00497 }
00498
00499 ProgramAssociationTable(const PSIPTable &table) : PSIPTable(table)
00500 {
00501 assert(TableID::PAT == TableID());
00502 }
00503
00504
00505 static ProgramAssociationTable* Create(uint tsid, uint version,
00506 const vector<uint>& pnum,
00507 const vector<uint>& pid);
00508
00509 uint TransportStreamID(void) const { return TableIDExtension(); }
00510
00511 uint ProgramCount(void) const
00512 {
00513 if (SectionLength() > (PSIP_OFFSET+2))
00514 return (SectionLength()-PSIP_OFFSET-2)>>2;
00515 return 0;
00516 }
00517
00518 uint ProgramNumber(uint i) const
00519 { return (psipdata()[(i<<2)] << 8) | psipdata()[(i<<2) + 1]; }
00520
00521 uint ProgramPID(uint i) const
00522 {
00523 return (((psipdata()[(i<<2) + 2] & 0x1f) << 8) |
00524 psipdata()[(i<<2) + 3]);
00525 }
00526
00527 void SetTranportStreamID(uint gtsid) { SetTableIDExtension(gtsid); }
00528
00529
00530 uint FindPID(uint progNum) const
00531 {
00532 for (uint i = 0; i < ProgramCount(); i++)
00533 if (progNum==ProgramNumber(i))
00534 return ProgramPID(i);
00535 return 0;
00536 }
00537 uint FindAnyPID(void) const
00538 {
00539 for (uint i = 0; i < ProgramCount(); i++)
00540 if (0!=ProgramNumber(i))
00541 return ProgramPID(i);
00542 return 0;
00543 }
00544 uint FindProgram(uint pid) const
00545 {
00546 for (uint i = 0; i < ProgramCount(); i++)
00547 if (pid==ProgramPID(i))
00548 return ProgramNumber(i);
00549 return 0;
00550 }
00551
00552 virtual QString toString(void) const;
00553 virtual QString toStringXML(uint indent_level) const;
00554
00555 private:
00556 static ProgramAssociationTable* CreateBlank(bool smallPacket = true);
00557 };
00558
00564 class MTV_PUBLIC ProgramMapTable : public PSIPTable
00565 {
00566 public:
00567
00568 ProgramMapTable(const ProgramMapTable& table) : PSIPTable(table)
00569 {
00570 assert(TableID::PMT == TableID());
00571 Parse();
00572 }
00573
00574 ProgramMapTable(const PSIPTable& table) : PSIPTable(table)
00575 {
00576 assert(TableID::PMT == TableID());
00577 Parse();
00578 }
00579
00580 static ProgramMapTable* Create(uint programNumber, uint basepid,
00581 uint pcrpid, uint version,
00582 vector<uint> pids, vector<uint> types);
00583
00584 static ProgramMapTable* Create(uint programNumber, uint basepid,
00585 uint pcrpid, uint version,
00586 const desc_list_t &global_desc,
00587 const vector<uint> &pids,
00588 const vector<uint> &types,
00589 const vector<desc_list_t> &prog_desc);
00590
00592 uint PCRPID(void) const
00593 { return ((psipdata()[0] << 8) | psipdata()[1]) & 0x1fff; }
00594
00595 uint ProgramNumber(void) const
00596 { return TableIDExtension(); }
00597
00598 uint ProgramInfoLength(void) const
00599 { return ((psipdata()[2]<<8) | psipdata()[3]) & 0x0fff; }
00600
00601 const unsigned char* ProgramInfo(void) const
00602 { return psipdata() + 4; }
00603
00604 uint StreamType(uint i) const
00605 { return _ptrs[i][0]; }
00606
00607 uint StreamPID(uint i) const
00608 { return ((_ptrs[i][1] << 8) | _ptrs[i][2]) & 0x1fff; }
00609
00610 uint StreamInfoLength(uint i) const
00611 { return ((_ptrs[i][3] << 8) | _ptrs[i][4]) & 0x0fff; }
00612
00613 const unsigned char* StreamInfo(uint i) const
00614 { return _ptrs[i] + 5; }
00615
00616 uint StreamCount(void) const
00617 { return (_ptrs.size()) ? _ptrs.size()-1 : 0; }
00618
00619
00620 void SetPCRPID(uint pid)
00621 {
00622 psipdata()[0] = ((pid >> 8) & 0x1F) | (psipdata()[0] & 0xE0);
00623 psipdata()[1] = (pid & 0xFF);
00624 }
00625
00626 void SetProgramNumber(uint num) { SetTableIDExtension(num); }
00627
00628 void SetStreamPID(uint i, uint pid)
00629 {
00630 _ptrs[i][1] = ((pid>>8) & 0x1f) | (_ptrs[i][1] & 0xe0);
00631 _ptrs[i][2] = pid & 0xff;
00632 }
00633
00634 void SetStreamType(uint i, uint type)
00635 { _ptrs[i][0] = type; }
00636
00637
00638 bool IsVideo(uint i, QString sistandard) const;
00639 bool IsAudio(uint i, QString sistandard) const;
00640 bool IsEncrypted(QString sistandard) const;
00641 bool IsProgramEncrypted(void) const;
00642 bool IsStreamEncrypted(uint pid) const;
00644 bool IsStillPicture(QString sistandard) const;
00646 QString StreamTypeString(uint i) const
00647 { return StreamID::toString(StreamType(i)); }
00650 QString StreamDescription(uint i, QString sistandard) const;
00652 QString GetLanguage(uint i) const;
00653
00654 uint FindPIDs(uint type, vector<uint> &pids,
00655 const QString &sistandard) const;
00656 uint FindPIDs(uint type, vector<uint> &pids, vector<uint> &types,
00657 const QString &sistandard, bool normalize) const;
00658
00661 int FindPID(uint pid) const
00662 {
00663 for (uint i = 0; i < StreamCount(); i++)
00664 if (pid == StreamPID(i))
00665 return i;
00666 return -1;
00667 }
00668 uint FindUnusedPID(uint desired_pid = 0x20);
00669
00670 void RemoveAllStreams(void)
00671 {
00672 memset(psipdata(), 0xff, pmt_header);
00673 SetProgramInfoLength(0);
00674 _ptrs.clear();
00675 }
00676 void AppendStream(uint pid, uint type, unsigned char* si = 0, uint il = 0);
00677
00678 void Parse(void) const;
00679 virtual QString toString(void) const;
00680 virtual QString toStringXML(uint indent_level) const;
00681
00682 private:
00683 void SetStreamInfoLength(uint i, uint length)
00684 {
00685 _ptrs[i][3] = ((length>>8) & 0x0f) | (_ptrs[i][3] & 0xf0);
00686 _ptrs[i][4] = length & 0xff;
00687 }
00688
00689 void SetStreamProgramInfo(uint i, unsigned char* streamInfo,
00690 uint infoLength)
00691 {
00692 SetStreamInfoLength(i, infoLength);
00693 memcpy(_ptrs[i] + 5, streamInfo, infoLength);
00694 }
00695
00696 void SetProgramInfoLength(uint length)
00697 {
00698 psipdata()[2] = ((length>>8) & 0x0f) | (psipdata()[2] & 0xf0);
00699 psipdata()[3] = length & 0xff;
00700 }
00701
00702 void SetProgramInfo(unsigned char *streamInfo, uint infoLength)
00703 {
00704 SetProgramInfoLength(infoLength);
00705 memcpy(psipdata() + 4, streamInfo, infoLength);
00706 }
00707
00708 static ProgramMapTable* CreateBlank(bool smallPacket = true);
00709
00710 static const uint pmt_header = 4;
00711 mutable vector<unsigned char*> _ptrs;
00712 };
00713
00718 class MTV_PUBLIC ConditionalAccessTable : public PSIPTable
00719 {
00720 public:
00721 ConditionalAccessTable(const PSIPTable &table) : PSIPTable(table)
00722 {
00723
00724
00725
00726 assert(TableID::CAT == TableID());
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 }
00738
00739
00740
00741 uint DescriptorsLength(void) const
00742 { return SectionLength() - PSIP_OFFSET; }
00743 const unsigned char *Descriptors(void) const { return psipdata(); }
00744
00745 virtual QString toString(void) const;
00746 virtual QString toStringXML(uint indent_level) const;
00747
00748
00749 };
00750
00751 class MTV_PUBLIC SpliceTimeView
00752 {
00753 public:
00754 SpliceTimeView(const unsigned char *data) : _data(data) { }
00755
00756 bool IsTimeSpecified(void) const { return _data[0] & 0x80; }
00757
00758
00759
00760 uint64_t PTSTime(void) const
00761 {
00762 return ((uint64_t(_data[0] & 0x1) << 32) |
00763 (uint64_t(_data[1]) << 24) |
00764 (uint64_t(_data[2]) << 16) |
00765 (uint64_t(_data[3]) << 8) |
00766 (uint64_t(_data[4])));
00767 }
00768
00769
00770
00771 virtual QString toString(int64_t first, int64_t last) const;
00772 virtual QString toStringXML(
00773 uint indent_level, int64_t first, int64_t last) const;
00774
00775 uint size(void) const { return IsTimeSpecified() ? 1 : 5; }
00776 private:
00777 const unsigned char *_data;
00778 };
00779
00780 class MTV_PUBLIC SpliceScheduleView
00781 {
00782 public:
00783 SpliceScheduleView(const vector<const unsigned char*> &ptrs0,
00784 const vector<const unsigned char*> &ptrs1) :
00785 _ptrs0(ptrs0), _ptrs1(ptrs1)
00786 {
00787 }
00788
00789 uint SpliceCount(void) const { return min(_ptrs0.size(), _ptrs1.size()); }
00790
00791
00792 uint SpliceEventID(uint i) const
00793 {
00794 return ((_ptrs0[i][0] << 24) | (_ptrs0[i][1] << 16) |
00795 (_ptrs0[i][2] << 8) | (_ptrs0[i][3]));
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 private:
00824 vector<const unsigned char*> _ptrs0;
00825 vector<const unsigned char*> _ptrs1;
00826 };
00827
00828 class MTV_PUBLIC SpliceInsertView
00829 {
00830 public:
00831 SpliceInsertView(const vector<const unsigned char*> &ptrs0,
00832 const vector<const unsigned char*> &ptrs1) :
00833 _ptrs0(ptrs0), _ptrs1(ptrs1)
00834 {
00835 }
00836
00837
00838 uint SpliceEventID(void) const
00839 {
00840 return ((_ptrs1[0][0] << 24) | (_ptrs1[0][1] << 16) |
00841 (_ptrs1[0][2] << 8) | (_ptrs1[0][3]));
00842 }
00843
00844 bool IsSpliceEventCancel(void) const { return _ptrs1[0][4] & 0x80; }
00845
00846
00847
00848 bool IsOutOfNetwork(void) const { return _ptrs1[0][5] & 0x80; }
00849
00850 bool IsProgramSplice(void) const { return _ptrs1[0][5] & 0x40; }
00851
00852 bool IsDuration(void) const { return _ptrs1[0][5] & 0x20; }
00853
00854 bool IsSpliceImmediate(void) const { return _ptrs1[0][5] & 0x20; }
00855
00856
00857
00858 SpliceTimeView SpliceTime(void) const
00859 { return SpliceTimeView(_ptrs1[0]+6); }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 uint UniqueProgramID(void) const
00874 { return (_ptrs1[2][0]<<8) | _ptrs1[2][1]; }
00875
00876 uint AvailNum(void) const { return _ptrs1[2][2]; }
00877
00878 uint AvailsExpected(void) const { return _ptrs1[2][3]; }
00879
00880
00881 virtual QString toString(int64_t first, int64_t last) const;
00882 virtual QString toStringXML(
00883 uint indent_level, int64_t first, int64_t last) const;
00884
00885 private:
00886 vector<const unsigned char*> _ptrs0;
00887 vector<const unsigned char*> _ptrs1;
00888 };
00889
00890 class MTV_PUBLIC SpliceInformationTable : public PSIPTable
00891 {
00892 public:
00893 SpliceInformationTable(const SpliceInformationTable &table) :
00894 PSIPTable(table), _epilog(NULL)
00895 {
00896 assert(TableID::SITscte == TableID());
00897 Parse();
00898 }
00899 SpliceInformationTable(const PSIPTable &table) :
00900 PSIPTable(table), _epilog(NULL)
00901 {
00902 assert(TableID::SITscte == TableID());
00903 Parse();
00904 }
00905 ~SpliceInformationTable() { ; }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 uint SpliceProtocolVersion(void) const { return pesdata()[3]; }
00917 void SetSpliceProtocolVersion(uint ver) { pesdata()[3] = ver; }
00918
00919 bool IsEncryptedPacket(void) const { return pesdata()[4] & 0x80; }
00920 void SetEncryptedPacket(bool val)
00921 {
00922 pesdata()[4] = (pesdata()[4] & ~0x80) | ((val) ? 0x80 : 0);
00923 }
00924
00925 enum
00926 {
00927 kNoEncryption = 0,
00928 kECB = 1,
00929 kCBC = 2,
00930 k3DES = 3,
00931
00932
00933 };
00934 uint EncryptionAlgorithm(void) const { return (pesdata()[4] >> 1) & 0x3f; }
00935 QString EncryptionAlgorithmString(void) const;
00936 void SetEncryptionAlgorithm(uint val)
00937 {
00938 pesdata()[4] &= 0x81;
00939 pesdata()[4] |= ((val&0x3f) << 1);
00940 }
00941
00942 uint64_t PTSAdjustment(void) const
00943 {
00944 return ((uint64_t(pesdata()[4] & 0x1) << 32) |
00945 (uint64_t(pesdata()[5]) << 24) |
00946 (uint64_t(pesdata()[6]) << 16) |
00947 (uint64_t(pesdata()[7]) << 8) |
00948 (uint64_t(pesdata()[8])));
00949 }
00950 void SetPTSAdjustment(uint64_t val)
00951 {
00952 pesdata()[4] &= ~0x1;
00953 pesdata()[4] |= (val>>32) & 0x1;
00954 pesdata()[5] = ((val>>24) & 0xff);
00955 pesdata()[6] = ((val>>16) & 0xff);
00956 pesdata()[7] = ((val>>8 ) & 0xff);
00957 pesdata()[8] = ((val ) & 0xff);
00958 }
00959
00960 uint CodeWordIndex(void) const { return pesdata()[9]; }
00961 void SetCodeWordIndex(uint val) { pesdata()[9] = val; }
00962
00963
00964 uint SpliceCommandLength(void) const
00965 {
00966 return ((pesdata()[11] & 0xf) << 8) | pesdata()[12];
00967 }
00968 void SetSpliceCommandLength(uint len)
00969 {
00970 pesdata()[11] &= ~0xf;
00971 pesdata()[11] |= (len >> 8) & 0xf;
00972 pesdata()[12] = len & 0xff;
00973 }
00974
00975 enum {
00976 kSCTNull = 0x00,
00977 kSCTReserved0 = 0x01,
00978 kSCTReserved1 = 0x02,
00979 kSCTReserved2 = 0x03,
00980 kSCTSpliceSchedule = 0x04,
00981 kSCTSpliceInsert = 0x05,
00982 kSCTTimeSignal = 0x06,
00983 kSCTBandwidthReservation = 0x07,
00984
00985 kSCTPrivateCommand = 0xff,
00986 };
00987 uint SpliceCommandType(void) const { return pesdata()[13]; }
00988 QString SpliceCommandTypeString(void) const;
00989 void SetSpliceCommandType(uint type) { pesdata()[13] = type & 0xff; }
00990
00991
00992
00994
00995
00996
00998
00999
01000 SpliceScheduleView SpliceSchedule(void) const
01001 { return SpliceScheduleView(_ptrs0, _ptrs1); }
01002
01004
01005
01006 SpliceInsertView SpliceInsert(void) const
01007 { return SpliceInsertView(_ptrs0, _ptrs1); }
01008
01010
01011
01012 SpliceTimeView TimeSignal(void) const
01013 { return SpliceTimeView(pesdata()+14); }
01014
01016
01017
01018
01020
01021
01022
01023
01024
01025
01026
01028
01029
01030
01031
01032 uint SpliceDescriptorsLength(uint i) const
01033 {
01034 return (_epilog[0] << 8) | _epilog[1];
01035 }
01036
01037
01038
01039 const unsigned char *SpliceDescriptors(void) const
01040 {
01041 return (_epilog) ? _epilog + 2 : NULL;
01042 }
01043
01044
01045
01046
01047
01048
01049 SpliceInformationTable *GetDecrypted(const QString &codeWord) const;
01050 bool Parse(void);
01051
01052 virtual QString toString(void) const { return toString(-1LL, -1LL); }
01053 virtual QString toStringXML(uint indent_level) const
01054 { return toStringXML(indent_level, -1LL, -1LL); }
01055
01056 QString toString(int64_t first, int64_t last) const;
01057 QString toStringXML(uint indent_level, int64_t first, int64_t last) const;
01058
01059 private:
01060 vector<const unsigned char*> _ptrs0;
01061 vector<const unsigned char*> _ptrs1;
01062 const unsigned char *_epilog;
01063 };
01064
01074 class MTV_PUBLIC AdaptationFieldControl
01075 {
01076 public:
01077 AdaptationFieldControl(const unsigned char* packet) : _data(packet) { ; }
01078
01082 uint Length(void) const { return _data[0]; }
01083
01087 bool Discontinuity(void) const { return _data[1] & 0x80; }
01088
01089 bool RandomAccess(void) const { return bool(_data[1] & 0x40); }
01090
01091 bool Priority(void) const { return bool(_data[1] & 0x20); }
01092
01093
01094
01098 bool PCR(void) const { return bool(_data[1] & 0x10); }
01102 bool OPCR(void) const { return bool(_data[1] & 0x08); }
01110 bool SplicingPoint(void) const { return bool(_data[1] & 0x04); }
01111
01112
01113 bool PrivateTransportData(void) const { return bool(_data[1] & 0x02); }
01114
01115 bool FieldExtension(void) const { return bool(_data[1] & 0x1); }
01116
01117 uint ExtensionLength(void) const { return _data[2]; }
01118
01119
01120 bool LTW(void) const { return bool(_data[3] & 0x80); }
01121
01122 bool PiecewiseRate(void) const { return bool(_data[3] & 0x40); }
01123
01124 bool SeamlessSplice(void) const { return bool(_data[3] & 0x20); }
01125
01126
01127 private:
01128 const unsigned char* _data;
01129 };
01130
01131 #endif