00001
00002
00003 #ifndef _ATSC_TABLES_H_
00004 #define _ATSC_TABLES_H_
00005
00006 #include "mpegtables.h"
00007 #include "atscdescriptors.h"
00008 #include <qstring.h>
00009 #include <stdint.h>
00010
00011
00012
00013
00014
00015
00016
00048 #define secs_Between_1Jan1970_6Jan1980 315964800
00049
00051 #define GPS_LEAP_SECONDS 14
00052
00053 class TableClass
00054 {
00055 public:
00056 typedef enum
00057 {
00058 UNKNOWN = -1,
00059 TVCTc = 0,
00060 TVCTnc = 1,
00061 CVCTc = 2,
00062 CVCTnc = 3,
00063 ETTc = 4,
00064 DCCSCT = 5,
00065 EIT = 6,
00066 ETTe = 7,
00067 DCCT = 8,
00068 RRT = 9,
00069 };
00070 };
00071
00076 class MasterGuideTable : public PSIPTable
00077 {
00078 public:
00079 MasterGuideTable(const MasterGuideTable& table) : PSIPTable(table)
00080 {
00081 assert(TableID::MGT == TableID());
00082 Parse();
00083 }
00084 MasterGuideTable(const PSIPTable& table) : PSIPTable(table)
00085 {
00086 assert(TableID::MGT == TableID());
00087 Parse();
00088 }
00089 ~MasterGuideTable() { ; }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 uint TableCount() const
00105 {
00106 return (pesdata()[9]<<8) | pesdata()[10];
00107 }
00108
00109
00110 uint TableType(uint i) const
00111 {
00112 return (_ptrs[i][0]<<8) | _ptrs[i][1];
00113 }
00114 int TableClass(uint i) const;
00115 QString TableClassString(uint i) const;
00116
00117
00118 uint TablePID(uint i) const
00119 {
00120 return ((_ptrs[i][2]<<8) | (_ptrs[i][3])) & 0x1fff;
00121 }
00122
00123
00124 uint TableVersion(uint i) const
00125 {
00126 return (_ptrs[i][4]) & 0x1f;
00127 }
00128
00129 uint TableDescriptorsBytes(uint i) const
00130 {
00131 return ((_ptrs[i][5]<<24) | (_ptrs[i][6]<<16) |
00132 (_ptrs[i][7]<<8) | (_ptrs[i][8]));
00133 }
00134
00135
00136 uint TableDescriptorsLength(uint i) const
00137 {
00138 return ((_ptrs[i][9]<<8) | (_ptrs[i][10])) & 0xfff;
00139 }
00140
00141
00142
00143
00144
00145 const unsigned char* TableDescriptors(uint i) const
00146 {
00147 return _ptrs[i]+11;
00148 }
00149
00150
00151 uint GlobalDescriptorsLength() const
00152 {
00153 return ((_ptrs[TableCount()][0]<<8) |
00154 (_ptrs[TableCount()][1])) & 0xfff;
00155 }
00156
00157 const unsigned char* GlobalDescriptors() const
00158 {
00159 return _ptrs[TableCount()]+2;
00160 }
00161
00162
00163
00164
00165
00166 void Parse() const;
00167 QString toString() const;
00168 private:
00169 mutable vector<unsigned char*> _ptrs;
00170 };
00171
00178 class VirtualChannelTable : public PSIPTable
00179 {
00180 public:
00181 VirtualChannelTable(const VirtualChannelTable &table) : PSIPTable(table)
00182 {
00183 assert(TableID::TVCT == TableID() || TableID::CVCT == TableID());
00184 Parse();
00185 }
00186 VirtualChannelTable(const PSIPTable &table) : PSIPTable(table)
00187 {
00188 assert(TableID::TVCT == TableID() || TableID::CVCT == TableID());
00189 Parse();
00190 }
00191
00192 ~VirtualChannelTable() { ; }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 uint TransportStreamID() const { return TableIDExtension(); }
00208
00209
00210 uint ChannelCount() const { return pesdata()[9]; }
00211
00212
00213
00214 const QString ShortChannelName(uint i) const
00215 {
00216 QString str;
00217 const unsigned short* ustr =
00218 reinterpret_cast<const unsigned short*>(_ptrs[i]);
00219 for (int j=0; j<7; j++)
00220 {
00221 QChar c((ustr[j]<<8) | (ustr[j]>>8));
00222 if (c != QChar('\0')) str.append(c);
00223 }
00224 return str;
00225 }
00226
00227
00228
00229
00230
00231 uint MajorChannel(uint i) const
00232 {
00233 return (((_ptrs[i][14])<<6)&0x3c0) | (_ptrs[i][15]>>2);
00234 }
00235
00236 uint MinorChannel(uint i) const
00237 {
00238 return (((_ptrs[i][15])<<8)&0x300) | _ptrs[i][16];
00239 }
00240
00241 uint ModulationMode(uint i) const
00242 {
00243 return _ptrs[i][17];
00244 }
00245
00246
00247 uint ChannelTransportStreamID(uint i) const
00248 {
00249 return ((_ptrs[i][22]<<8) | _ptrs[i][23]);
00250 }
00251
00252 uint ProgramNumber(uint i) const
00253 {
00254 return ((_ptrs[i][24]<<8) | _ptrs[i][25]);
00255 }
00256
00257 uint ETMlocation(uint i) const
00258 {
00259 return (_ptrs[i][26]>>6) & 0x03;
00260 }
00261
00262 bool IsAccessControlled(uint i) const
00263 {
00264 return bool(_ptrs[i][26] & 0x20);
00265 }
00266
00267 bool IsHidden(uint i) const
00268 {
00269 return bool(_ptrs[i][26] & 0x10);
00270 }
00271
00272
00273 bool IsHiddenInGuide(uint i) const
00274 {
00275 return bool(_ptrs[i][26] & 0x2);
00276 }
00277
00278
00279 uint ServiceType(uint i) const
00280 {
00281 return _ptrs[i][27] & 0x3f;
00282 }
00283
00284 uint SourceID(uint i) const
00285 {
00286 return ((_ptrs[i][28]<<8) | _ptrs[i][29]);
00287 }
00288
00289
00290 uint DescriptorsLength(uint i) const
00291 {
00292 return ((_ptrs[i][30]<<8) | _ptrs[i][31]) & 0x03ff;
00293 }
00294
00295 const unsigned char* Descriptors(uint i) const
00296 {
00297 return _ptrs[i]+32;
00298 }
00299
00300
00301
00302 uint GlobalDescriptorsLength() const
00303 {
00304 uint i = ChannelCount();
00305 return ((_ptrs[i][0]<<8) | _ptrs[i][1]) & 0x03ff;
00306 }
00307
00308 const unsigned char* GlobalDescriptors() const
00309 {
00310 return _ptrs[ChannelCount()]+2;
00311 }
00312
00313 void Parse() const;
00314 int Find(int major, int minor) const;
00315 QString GetExtendedChannelName(uint idx) const;
00316 protected:
00317 mutable vector<unsigned char*> _ptrs;
00318 };
00319
00325 class TerrestrialVirtualChannelTable : public VirtualChannelTable
00326 {
00327 public:
00328 TerrestrialVirtualChannelTable(const TerrestrialVirtualChannelTable &table)
00329 : VirtualChannelTable(table)
00330 {
00331 assert(TableID::TVCT == TableID());
00332 }
00333 TerrestrialVirtualChannelTable(const PSIPTable &table)
00334 : VirtualChannelTable(table)
00335 {
00336 assert(TableID::TVCT == TableID());
00337 }
00338 ~TerrestrialVirtualChannelTable() { ; }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 QString toString() const;
00385 QString toString(int) const;
00386 };
00387
00388
00394 class CableVirtualChannelTable : public VirtualChannelTable
00395 {
00396 public:
00397 CableVirtualChannelTable(const CableVirtualChannelTable &table)
00398 : VirtualChannelTable(table)
00399 {
00400 assert(TableID::CVCT == TableID());
00401 }
00402 CableVirtualChannelTable(const PSIPTable &table)
00403 : VirtualChannelTable(table)
00404 {
00405 assert(TableID::CVCT == TableID());
00406 }
00407 ~CableVirtualChannelTable() { ; }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 bool IsPathSelect(uint i) const
00439 {
00440 return bool(_ptrs[i][26] & 0x8);
00441 }
00442
00443 bool IsOutOfBand(uint i) const
00444 {
00445 return bool(_ptrs[i][26] & 0x4);
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 QString toString() const;
00460 QString toString(int) const;
00461 };
00462
00468 class EventInformationTable : public PSIPTable
00469 {
00470 public:
00471 EventInformationTable(const EventInformationTable &table)
00472 : PSIPTable(table)
00473 {
00474 assert(TableID::EIT == TableID());
00475 Parse();
00476 }
00477 EventInformationTable(const PSIPTable &table) : PSIPTable(table)
00478 {
00479 assert(TableID::EIT == TableID());
00480 Parse();
00481 }
00482 ~EventInformationTable() { ; }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 uint SourceID() const { return TableIDExtension(); }
00498
00499
00500 uint EventCount() const { return psipdata()[1]; }
00501
00502
00503
00504
00505 uint EventID(uint i) const
00506 {
00507 return ((_ptrs[i][0]<<8) | _ptrs[i][1])&0x3fff;
00508 }
00509
00510 uint StartTimeRaw(uint i) const
00511 {
00512 return ((_ptrs[i][2]<<24) | (_ptrs[i][3]<<16) |
00513 (_ptrs[i][4]<<8) | (_ptrs[i][5]));
00514 }
00515 QDateTime StartTimeGPS(uint i) const
00516 {
00517
00518 QDateTime dt;
00519 dt.setTime_t(secs_Between_1Jan1970_6Jan1980 + StartTimeRaw(i));
00520 return dt;
00521 }
00522
00523
00524 uint ETMLocation(uint i) const
00525 {
00526 return (_ptrs[i][6]>>4)&3;
00527 }
00528
00529 uint LengthInSeconds(uint i) const
00530 {
00531 return ((_ptrs[i][6]<<16) | (_ptrs[i][7]<<8) |
00532 (_ptrs[i][8])) & 0xfffff;
00533 }
00534
00535 uint TitleLength(uint i) const
00536 { return _ptrs[i][9]; }
00537
00538 MultipleStringStructure title(int i) const
00539 {
00540 return MultipleStringStructure(_ptrs[i]+10);
00541 }
00542
00543
00544 uint DescriptorsLength(uint i) const
00545 {
00546 unsigned char *desc=_ptrs[i]+10+TitleLength(i);
00547 return ((desc[0]<<8)|(desc[1]))&0xfff;
00548 }
00549
00550
00551
00552 const unsigned char* Descriptors(uint i) const
00553 {
00554 return _ptrs[i]+12+TitleLength(i);
00555 }
00556
00557
00558
00559 void Parse() const;
00560 QString toString() const;
00561 private:
00562 mutable vector<unsigned char*> _ptrs;
00563 };
00564
00570 class ExtendedTextTable : public PSIPTable
00571 {
00572 public:
00573 ExtendedTextTable(const ExtendedTextTable &table) : PSIPTable(table)
00574 {
00575 assert(TableID::ETT == TableID());
00576 }
00577 ExtendedTextTable(const PSIPTable &table) : PSIPTable(table)
00578 {
00579 assert(TableID::ETT == TableID());
00580 }
00581 ~ExtendedTextTable() { ; }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 uint ExtendedTextTableID() const { return TableIDExtension(); }
00597 void SetExtendedTextTableID(uint id)
00598 { SetTableIDExtension(id); }
00599
00600
00601
00602
00603
00604 bool IsChannelETM(void) const { return 0 == (psipdata()[4] & 3); }
00605 bool IsEventETM(void) const { return 2 == (psipdata()[4] & 3); }
00606 uint SourceID(void) const
00607 { return (psipdata()[1] << 8) | psipdata()[2]; }
00608 uint EventID(void) const
00609 { return (psipdata()[3] << 6) | (psipdata()[4] >> 2); }
00610
00611
00612 const MultipleStringStructure ExtendedTextMessage() const
00613 {
00614 return MultipleStringStructure(psipdata() + 5);
00615 }
00616
00617 QString toString() const;
00618
00619 };
00620
00628 class SystemTimeTable : public PSIPTable
00629 {
00630 public:
00631 SystemTimeTable(const SystemTimeTable &table) : PSIPTable(table)
00632 {
00633 assert(TableID::STT == TableID());
00634 }
00635 SystemTimeTable(const PSIPTable &table) : PSIPTable(table)
00636 {
00637 assert(TableID::STT == TableID());
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 uint32_t GPSRaw(void) const
00656 {
00657 return ((pesdata()[9] <<24) | (pesdata()[10]<<16) |
00658 (pesdata()[11]<< 8) | pesdata()[12]);
00659 }
00660 QDateTime SystemTimeGPS(void) const
00661 {
00662 QDateTime dt;
00663 dt.setTime_t(secs_Between_1Jan1970_6Jan1980 + GPSRaw());
00664 return dt;
00665 }
00666 time_t GPSUnix(void) const
00667 { return secs_Between_1Jan1970_6Jan1980 + GPSRaw(); }
00668 time_t UTCUnix(void) const
00669 { return GPSUnix() - GPSOffset(); }
00670
00671
00672 uint GPSOffset() const { return pesdata()[13]; }
00673
00674
00675
00676
00677
00678 bool InDaylightSavingsTime() const { return pesdata()[14]&0x80; }
00679 uint DayDaylightSavingsStarts() const { return pesdata()[14]&0x1f; }
00680 uint HourDaylightSavingsStarts() const { return pesdata()[15]; }
00681
00682
00683
00684 QString toString() const
00685 {
00686 QString str =
00687 QString(" SystemTimeTable GPSTime(%1) GPS2UTC_Offset(%2) ")
00688 .arg(SystemTimeGPS().toString(Qt::LocalDate)).arg(GPSOffset());
00689 str.append(QString("DS(%3) Day(%4) Hour(%5)")
00690 .arg(InDaylightSavingsTime())
00691 .arg(DayDaylightSavingsStarts())
00692 .arg(HourDaylightSavingsStarts()));
00693 return str;
00694 }
00695 };
00696
00700 class RatingRegionTable : public PSIPTable
00701 {
00702 public:
00703 RatingRegionTable(const RatingRegionTable &table) : PSIPTable(table)
00704 {
00705 assert(TableID::RRT == TableID());
00706 }
00707 RatingRegionTable(const PSIPTable &table) : PSIPTable(table)
00708 {
00709 assert(TableID::RRT == TableID());
00710 }
00711 };
00712
00716 class DirectedChannelChangeTable : public PSIPTable
00717 {
00718 public:
00719 DirectedChannelChangeTable(const DirectedChannelChangeTable &table)
00720 : PSIPTable(table)
00721 {
00722 assert(TableID::DCCT == TableID());
00723 }
00724 DirectedChannelChangeTable(const PSIPTable &table) : PSIPTable(table)
00725 {
00726 assert(TableID::DCCT == TableID());
00727 }
00728 };
00729
00733 class DirectedChannelChangeSelectionCodeTable : public PSIPTable
00734 {
00735 public:
00736 DirectedChannelChangeSelectionCodeTable(
00737 const DirectedChannelChangeSelectionCodeTable &table)
00738 : PSIPTable(table)
00739 {
00740 assert(TableID::DCCSCT == TableID());
00741 }
00742 DirectedChannelChangeSelectionCodeTable(const PSIPTable &table)
00743 : PSIPTable(table)
00744 {
00745 assert(TableID::DCCSCT == TableID());
00746 }
00747 };
00748
00749 #endif // _ATSC_TABLES_H_