1 /* 2 * dvbsi.h 3 * 4 * Copyright (C) 2008-2011 Christoph Pfister <christophpfister@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #ifndef DVBSI_H 22 #define DVBSI_H 23 24 #include <QPair> 25 #include <QObject> 26 #include <QByteArray> 27 #include <QString> 28 #include <QTextCodec> 29 #include "dvbbackenddevice.h" 30 31 class DvbPmtSection; 32 33 class DvbSectionData 34 { 35 public: isValid()36 bool isValid() const 37 { 38 return (length > 0); 39 } 40 at(int index)41 unsigned char at(int index) const 42 { 43 return data[index]; 44 } 45 getData()46 const char *getData() const 47 { 48 return data; 49 } 50 getLength()51 int getLength() const 52 { 53 return length; 54 } 55 toByteArray()56 QByteArray toByteArray() const 57 { 58 return QByteArray(data, length); 59 } 60 61 protected: DvbSectionData()62 DvbSectionData() { } ~DvbSectionData()63 ~DvbSectionData() { } 64 initSectionData()65 void initSectionData() 66 { 67 data = NULL; 68 length = 0; 69 size = 0; 70 } 71 initSectionData(const char * data_,int length_,int size_)72 void initSectionData(const char *data_, int length_, int size_) 73 { 74 data = data_; 75 length = length_; 76 size = size_; 77 } 78 getSize()79 int getSize() const 80 { 81 return size; 82 } 83 84 private: 85 const char *data; 86 int length; 87 int size; 88 }; 89 90 class DvbSection : public DvbSectionData 91 { 92 public: getSectionLength()93 int getSectionLength() const 94 { 95 return getLength(); 96 } 97 tableId()98 int tableId() const 99 { 100 return at(0); 101 } 102 isStandardSection()103 bool isStandardSection() const 104 { 105 return (at(1) & 0x80) != 0; 106 } 107 108 protected: DvbSection()109 DvbSection() { } ~DvbSection()110 ~DvbSection() { } 111 112 void initSection(const char *data, int size); 113 114 private: 115 Q_DISABLE_COPY(DvbSection) 116 }; 117 118 class DvbStandardSection : public DvbSection 119 { 120 public: 121 tableIdExtension()122 int tableIdExtension() const 123 { 124 return (at(3) << 8 | at(4)); 125 } 126 versionNumber()127 int versionNumber() const 128 { 129 return (at(5) >> 1) & ((1 << 5) - 1); 130 } 131 currentNextIndicator()132 bool currentNextIndicator() const 133 { 134 return (at(5) & 0x01) != 0; 135 } 136 sectionNumber()137 int sectionNumber() const 138 { 139 return at(6); 140 } 141 lastSectionNumber()142 int lastSectionNumber() const 143 { 144 return at(7); 145 } 146 147 static int verifyCrc32(const char *data, int size); 148 static const unsigned int crc32Table[]; 149 150 protected: DvbStandardSection()151 DvbStandardSection() { } ~DvbStandardSection()152 ~DvbStandardSection() { } 153 154 void initStandardSection(const char *data, int size); 155 156 private: 157 Q_DISABLE_COPY(DvbStandardSection) 158 }; 159 160 class DvbSiText 161 { 162 public: 163 static QString convertText(const char *data, int size); 164 static void setOverride6937(bool override); 165 166 private: 167 enum TextEncoding 168 { 169 Iso6937 = 0, 170 Iso8859_1 = 1, 171 Iso8859_2 = 2, 172 Iso8859_3 = 3, 173 Iso8859_4 = 4, 174 Iso8859_5 = 5, 175 Iso8859_6 = 6, 176 Iso8859_7 = 7, 177 Iso8859_8 = 8, 178 Iso8859_9 = 9, 179 Iso8859_10 = 10, 180 Iso8859_11 = 11, 181 Iso8859_13 = 12, 182 Iso8859_14 = 13, 183 Iso8859_15 = 14, 184 Iso2022_kr = 15, 185 Iso10646_ucs2 = 16, 186 Gb2312 = 17, 187 Utf_16be = 18, 188 Utf_8 = 19, 189 EncodingTypeMax = 19 190 }; 191 192 static QTextCodec *codecTable[EncodingTypeMax + 1]; 193 static bool override6937; 194 }; 195 196 class DvbDescriptor : public DvbSectionData 197 { 198 public: DvbDescriptor(const char * data,int size)199 DvbDescriptor(const char *data, int size) 200 { 201 initDescriptor(data, size); 202 } 203 ~DvbDescriptor()204 ~DvbDescriptor() { } 205 descriptorTag()206 int descriptorTag() const 207 { 208 return at(0); 209 } 210 advance()211 void advance() 212 { 213 initDescriptor(getData() + getLength(), getSize() - getLength()); 214 } 215 bcdToInt(unsigned int bcd,int multiplier)216 static int bcdToInt(unsigned int bcd, int multiplier) 217 { 218 int value = 0; 219 220 while (bcd != 0) { 221 value += (bcd & 0xf) * multiplier; 222 multiplier *= 10; 223 bcd >>= 4; 224 } 225 226 return value; 227 } 228 229 private: 230 void initDescriptor(const char *data, int size); 231 }; 232 233 // ATSC "Multiple String Structure". See A/65C Section 6.10 234 class AtscPsipText 235 { 236 public: 237 static QString convertText(const char *data, int size); 238 239 private: 240 static QString interpretTextData(const char *data, unsigned int len, 241 unsigned int mode); 242 }; 243 244 // ATSC Huffman compressed string support, conforming to A/65C Annex C 245 class AtscHuffmanString 246 { 247 public: 248 static QString convertText(const char *data_, int size, int table); 249 private: 250 AtscHuffmanString(const char *data_, int size, int table); 251 ~AtscHuffmanString(); 252 bool hasBits(); 253 unsigned char getBit(); 254 unsigned char getByte(); 255 void decompress(); 256 257 const char *data; 258 int bitsLeft; 259 260 QString result; 261 const unsigned short *offsets; 262 const unsigned char *tableBase; 263 264 static const unsigned short Huffman1Offsets[128]; 265 static const unsigned char Huffman1Tables[]; 266 267 static const unsigned short Huffman2Offsets[128]; 268 static const unsigned char Huffman2Tables[]; 269 }; 270 271 class DvbPmtFilter : public QObject, public DvbSectionFilter 272 { 273 Q_OBJECT 274 public: DvbPmtFilter()275 DvbPmtFilter() : programNumber(-1) { } ~DvbPmtFilter()276 ~DvbPmtFilter() { } 277 setProgramNumber(int programNumber_)278 void setProgramNumber(int programNumber_) 279 { 280 programNumber = programNumber_; 281 } 282 283 signals: 284 void pmtSectionChanged(const QByteArray &pmtSectionData); 285 286 private: 287 void processSection(const char *data, int size); 288 289 int programNumber; 290 QByteArray lastPmtSectionData; 291 }; 292 293 class DvbSectionGenerator 294 { 295 public: DvbSectionGenerator()296 DvbSectionGenerator() : versionNumber(0), continuityCounter(0) { } ~DvbSectionGenerator()297 ~DvbSectionGenerator() { } 298 299 void initPat(int transportStreamId, int programNumber, int pmtPid); 300 void initPmt(int pmtPid, const DvbPmtSection §ion, const QList<int> &pids); 301 reset()302 void reset() 303 { 304 packets.clear(); 305 versionNumber = 0; 306 continuityCounter = 0; 307 } 308 309 QByteArray generatePackets(); 310 311 private: 312 char *startSection(int sectionLength); 313 void endSection(int sectionLength, int pid); 314 315 QByteArray packets; 316 int versionNumber; 317 int continuityCounter; 318 }; 319 320 class DvbPmtParser 321 { 322 public: 323 explicit DvbPmtParser(const DvbPmtSection §ion); ~DvbPmtParser()324 ~DvbPmtParser() { } 325 326 int videoPid; 327 QList<QPair<int, QString> > audioPids; // QString = language code (may be empty) 328 QList<QPair<int, QString> > subtitlePids; // QString = language code 329 int teletextPid; 330 }; 331 332 class AtscEitSectionEntry : public DvbSectionData 333 { 334 public: AtscEitSectionEntry(const char * data,int size)335 AtscEitSectionEntry(const char *data, int size) 336 { 337 initEitSectionEntry(data, size); 338 } 339 ~AtscEitSectionEntry()340 ~AtscEitSectionEntry() { } 341 advance()342 void advance() 343 { 344 initEitSectionEntry(getData() + getLength(), getSize() - getLength()); 345 } 346 eventId()347 int eventId() const 348 { 349 return ((at(0) & 0x3f) << 8) | at(1); 350 } 351 startTime()352 int startTime() const 353 { 354 return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5); 355 } 356 duration()357 int duration() const 358 { 359 return ((at(6) & 0xf) << 16) | (at(7) << 8) | at(8); 360 } 361 title()362 QString title() const 363 { 364 return AtscPsipText::convertText(getData() + 10, titleLength); 365 } 366 367 private: 368 void initEitSectionEntry(const char *data, int size); 369 370 int titleLength; 371 }; 372 373 // everything below this line is automatically generated 374 375 class DvbPatSectionEntry : public DvbSectionData 376 { 377 public: DvbPatSectionEntry(const char * data,int size)378 DvbPatSectionEntry(const char *data, int size) 379 { 380 initPatSectionEntry(data, size); 381 } 382 ~DvbPatSectionEntry()383 ~DvbPatSectionEntry() { } 384 advance()385 void advance() 386 { 387 initPatSectionEntry(getData() + getLength(), getSize() - getLength()); 388 } 389 programNumber()390 int programNumber() const 391 { 392 return (at(0) << 8) | at(1); 393 } 394 pid()395 int pid() const 396 { 397 return ((at(2) & 0x1f) << 8) | at(3); 398 } 399 400 private: 401 void initPatSectionEntry(const char *data, int size); 402 }; 403 404 class DvbPmtSectionEntry : public DvbSectionData 405 { 406 public: DvbPmtSectionEntry(const char * data,int size)407 DvbPmtSectionEntry(const char *data, int size) 408 { 409 initPmtSectionEntry(data, size); 410 } 411 ~DvbPmtSectionEntry()412 ~DvbPmtSectionEntry() { } 413 advance()414 void advance() 415 { 416 initPmtSectionEntry(getData() + getLength(), getSize() - getLength()); 417 } 418 streamType()419 int streamType() const 420 { 421 return at(0); 422 } 423 pid()424 int pid() const 425 { 426 return ((at(1) & 0x1f) << 8) | at(2); 427 } 428 descriptors()429 DvbDescriptor descriptors() const 430 { 431 return DvbDescriptor(getData() + 5, getLength() - 5); 432 } 433 434 private: 435 void initPmtSectionEntry(const char *data, int size); 436 }; 437 438 class DvbSdtSectionEntry : public DvbSectionData 439 { 440 public: DvbSdtSectionEntry(const char * data,int size)441 DvbSdtSectionEntry(const char *data, int size) 442 { 443 initSdtSectionEntry(data, size); 444 } 445 ~DvbSdtSectionEntry()446 ~DvbSdtSectionEntry() { } 447 advance()448 void advance() 449 { 450 initSdtSectionEntry(getData() + getLength(), getSize() - getLength()); 451 } 452 serviceId()453 int serviceId() const 454 { 455 return (at(0) << 8) | at(1); 456 } 457 isScrambled()458 bool isScrambled() const 459 { 460 return ((at(3) & 0x10) != 0); 461 } 462 descriptors()463 DvbDescriptor descriptors() const 464 { 465 return DvbDescriptor(getData() + 5, getLength() - 5); 466 } 467 468 private: 469 void initSdtSectionEntry(const char *data, int size); 470 }; 471 472 class DvbEitSectionEntry : public DvbSectionData 473 { 474 public: DvbEitSectionEntry(const char * data,int size)475 DvbEitSectionEntry(const char *data, int size) 476 { 477 initEitSectionEntry(data, size); 478 } 479 ~DvbEitSectionEntry()480 ~DvbEitSectionEntry() { } 481 advance()482 void advance() 483 { 484 initEitSectionEntry(getData() + getLength(), getSize() - getLength()); 485 } 486 startDate()487 int startDate() const 488 { 489 return (at(2) << 8) | at(3); 490 } 491 startTime()492 int startTime() const 493 { 494 return (at(4) << 16) | (at(5) << 8) | at(6); 495 } 496 duration()497 int duration() const 498 { 499 return (at(7) << 16) | (at(8) << 8) | at(9); 500 } 501 descriptors()502 DvbDescriptor descriptors() const 503 { 504 return DvbDescriptor(getData() + 12, getLength() - 12); 505 } 506 507 private: 508 void initEitSectionEntry(const char *data, int size); 509 }; 510 511 class DvbEitContentEntry : public DvbSectionData 512 { 513 public: DvbEitContentEntry(const char * data,int size)514 DvbEitContentEntry(const char *data, int size) 515 { 516 initEitContentEntry(data, size); 517 } 518 ~DvbEitContentEntry()519 ~DvbEitContentEntry() { } 520 advance()521 void advance() 522 { 523 initEitContentEntry(getData() + getLength(), getSize() - getLength()); 524 } 525 contentNibbleLevel1()526 int contentNibbleLevel1() const 527 { 528 return (at(0) >> 4); 529 } 530 contentNibbleLevel2()531 int contentNibbleLevel2() const 532 { 533 return (at(0) & 0xf); 534 } 535 userByte()536 int userByte() const 537 { 538 return at(1); 539 } 540 541 private: 542 void initEitContentEntry(const char *data, int size); 543 }; 544 545 class DvbParentalRatingEntry : public DvbSectionData 546 { 547 public: DvbParentalRatingEntry(const char * data,int size)548 DvbParentalRatingEntry(const char *data, int size) 549 { 550 initParentalRatingEntry(data, size); 551 } 552 ~DvbParentalRatingEntry()553 ~DvbParentalRatingEntry() { } 554 advance()555 void advance() 556 { 557 initParentalRatingEntry(getData() + getLength(), getSize() - getLength()); 558 } 559 languageCode1()560 int languageCode1() const 561 { 562 return at(0); 563 } 564 languageCode2()565 int languageCode2() const 566 { 567 return at(1); 568 } 569 languageCode3()570 int languageCode3() const 571 { 572 return at(2); 573 } 574 rating()575 int rating() const 576 { 577 return at(3); 578 } 579 580 private: 581 void initParentalRatingEntry(const char *data, int size); 582 }; 583 584 class DvbNitSectionEntry : public DvbSectionData 585 { 586 public: DvbNitSectionEntry(const char * data,int size)587 DvbNitSectionEntry(const char *data, int size) 588 { 589 initNitSectionEntry(data, size); 590 } 591 ~DvbNitSectionEntry()592 ~DvbNitSectionEntry() { } 593 advance()594 void advance() 595 { 596 initNitSectionEntry(getData() + getLength(), getSize() - getLength()); 597 } 598 descriptors()599 DvbDescriptor descriptors() const 600 { 601 return DvbDescriptor(getData() + 6, getLength() - 6); 602 } 603 604 private: 605 void initNitSectionEntry(const char *data, int size); 606 }; 607 608 class AtscMgtSectionEntry : public DvbSectionData 609 { 610 public: AtscMgtSectionEntry(const char * data,int size)611 AtscMgtSectionEntry(const char *data, int size) 612 { 613 initMgtSectionEntry(data, size); 614 } 615 ~AtscMgtSectionEntry()616 ~AtscMgtSectionEntry() { } 617 advance()618 void advance() 619 { 620 initMgtSectionEntry(getData() + getLength(), getSize() - getLength()); 621 } 622 tableType()623 int tableType() const 624 { 625 return (at(0) << 8) | at(1); 626 } 627 pid()628 int pid() const 629 { 630 return ((at(2) & 0x1f) << 8) | at(3); 631 } 632 descriptors()633 DvbDescriptor descriptors() const 634 { 635 return DvbDescriptor(getData() + 11, getLength() - 11); 636 } 637 638 private: 639 void initMgtSectionEntry(const char *data, int size); 640 }; 641 642 class AtscVctSectionEntry : public DvbSectionData 643 { 644 public: AtscVctSectionEntry(const char * data,int size)645 AtscVctSectionEntry(const char *data, int size) 646 { 647 initVctSectionEntry(data, size); 648 } 649 ~AtscVctSectionEntry()650 ~AtscVctSectionEntry() { } 651 advance()652 void advance() 653 { 654 initVctSectionEntry(getData() + getLength(), getSize() - getLength()); 655 } 656 shortName1()657 int shortName1() const 658 { 659 return (at(0) << 8) | at(1); 660 } 661 shortName2()662 int shortName2() const 663 { 664 return (at(2) << 8) | at(3); 665 } 666 shortName3()667 int shortName3() const 668 { 669 return (at(4) << 8) | at(5); 670 } 671 shortName4()672 int shortName4() const 673 { 674 return (at(6) << 8) | at(7); 675 } 676 shortName5()677 int shortName5() const 678 { 679 return (at(8) << 8) | at(9); 680 } 681 shortName6()682 int shortName6() const 683 { 684 return (at(10) << 8) | at(11); 685 } 686 shortName7()687 int shortName7() const 688 { 689 return (at(12) << 8) | at(13); 690 } 691 majorNumber()692 int majorNumber() const 693 { 694 return ((at(14) & 0xf) << 6) | (at(15) >> 2); 695 } 696 minorNumber()697 int minorNumber() const 698 { 699 return ((at(15) & 0x3) << 8) | at(16); 700 } 701 programNumber()702 int programNumber() const 703 { 704 return (at(24) << 8) | at(25); 705 } 706 isScrambled()707 bool isScrambled() const 708 { 709 return ((at(26) & 0x20) != 0); 710 } 711 sourceId()712 int sourceId() const 713 { 714 return (at(28) << 8) | at(29); 715 } 716 descriptors()717 DvbDescriptor descriptors() const 718 { 719 return DvbDescriptor(getData() + 32, getLength() - 32); 720 } 721 722 private: 723 void initVctSectionEntry(const char *data, int size); 724 }; 725 726 class DvbLanguageDescriptor : public DvbDescriptor 727 { 728 public: 729 explicit DvbLanguageDescriptor(const DvbDescriptor &descriptor); ~DvbLanguageDescriptor()730 ~DvbLanguageDescriptor() { } 731 languageCode1()732 int languageCode1() const 733 { 734 return at(2); 735 } 736 languageCode2()737 int languageCode2() const 738 { 739 return at(3); 740 } 741 languageCode3()742 int languageCode3() const 743 { 744 return at(4); 745 } 746 747 private: 748 Q_DISABLE_COPY(DvbLanguageDescriptor) 749 }; 750 751 class DvbSubtitleDescriptor : public DvbDescriptor 752 { 753 public: 754 explicit DvbSubtitleDescriptor(const DvbDescriptor &descriptor); ~DvbSubtitleDescriptor()755 ~DvbSubtitleDescriptor() { } 756 languageCode1()757 int languageCode1() const 758 { 759 return at(2); 760 } 761 languageCode2()762 int languageCode2() const 763 { 764 return at(3); 765 } 766 languageCode3()767 int languageCode3() const 768 { 769 return at(4); 770 } 771 subtitleType()772 int subtitleType() const 773 { 774 return at(5); 775 } 776 777 private: 778 Q_DISABLE_COPY(DvbSubtitleDescriptor) 779 }; 780 781 class DvbServiceDescriptor : public DvbDescriptor 782 { 783 public: 784 explicit DvbServiceDescriptor(const DvbDescriptor &descriptor); ~DvbServiceDescriptor()785 ~DvbServiceDescriptor() { } 786 providerName()787 QString providerName() const 788 { 789 return DvbSiText::convertText(getData() + 4, providerNameLength); 790 } 791 serviceName()792 QString serviceName() const 793 { 794 return DvbSiText::convertText(getData() + 5 + providerNameLength, serviceNameLength); 795 } 796 797 private: 798 Q_DISABLE_COPY(DvbServiceDescriptor) 799 800 int providerNameLength; 801 int serviceNameLength; 802 }; 803 804 class DvbShortEventDescriptor : public DvbDescriptor 805 { 806 public: 807 explicit DvbShortEventDescriptor(const DvbDescriptor &descriptor); ~DvbShortEventDescriptor()808 ~DvbShortEventDescriptor() { } 809 languageCode1()810 int languageCode1() const 811 { 812 return at(2); 813 } 814 languageCode2()815 int languageCode2() const 816 { 817 return at(3); 818 } 819 languageCode3()820 int languageCode3() const 821 { 822 return at(4); 823 } 824 eventName()825 QString eventName() const 826 { 827 return DvbSiText::convertText(getData() + 6, eventNameLength); 828 } 829 text()830 QString text() const 831 { 832 return DvbSiText::convertText(getData() + 7 + eventNameLength, textLength); 833 } 834 835 private: 836 Q_DISABLE_COPY(DvbShortEventDescriptor) 837 838 int eventNameLength; 839 int textLength; 840 }; 841 842 class DvbExtendedEventDescriptor : public DvbDescriptor 843 { 844 public: 845 explicit DvbExtendedEventDescriptor(const DvbDescriptor &descriptor); ~DvbExtendedEventDescriptor()846 ~DvbExtendedEventDescriptor() { } 847 languageCode1()848 int languageCode1() const 849 { 850 return at(3); 851 } 852 languageCode2()853 int languageCode2() const 854 { 855 return at(4); 856 } 857 languageCode3()858 int languageCode3() const 859 { 860 return at(5); 861 } 862 text()863 QString text() const 864 { 865 return DvbSiText::convertText(getData() + 8 + itemsLength, textLength); 866 } 867 868 private: 869 Q_DISABLE_COPY(DvbExtendedEventDescriptor) 870 871 int itemsLength; 872 int textLength; 873 }; 874 875 class DvbContentDescriptor : public DvbDescriptor 876 { 877 public: 878 explicit DvbContentDescriptor(const DvbDescriptor &descriptor); ~DvbContentDescriptor()879 ~DvbContentDescriptor() { } 880 contents()881 DvbEitContentEntry contents() const 882 { 883 return DvbEitContentEntry(getData() + 2, getLength() - 2); 884 } 885 886 private: 887 Q_DISABLE_COPY(DvbContentDescriptor) 888 }; 889 890 class DvbParentalRatingDescriptor : public DvbDescriptor 891 { 892 public: 893 explicit DvbParentalRatingDescriptor(const DvbDescriptor &descriptor); ~DvbParentalRatingDescriptor()894 ~DvbParentalRatingDescriptor() { } 895 contents()896 DvbParentalRatingEntry contents() const 897 { 898 return DvbParentalRatingEntry(getData() + 2, getLength() - 2); 899 } 900 901 private: 902 Q_DISABLE_COPY(DvbParentalRatingDescriptor) 903 }; 904 905 class DvbCableDescriptor : public DvbDescriptor 906 { 907 public: 908 explicit DvbCableDescriptor(const DvbDescriptor &descriptor); ~DvbCableDescriptor()909 ~DvbCableDescriptor() { } 910 frequency()911 int frequency() const 912 { 913 return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5); 914 } 915 modulation()916 int modulation() const 917 { 918 return at(8); 919 } 920 symbolRate()921 int symbolRate() const 922 { 923 return (at(9) << 20) | (at(10) << 12) | (at(11) << 4) | (at(12) >> 4); 924 } 925 fecRate()926 int fecRate() const 927 { 928 return (at(12) & 0xf); 929 } 930 931 private: 932 Q_DISABLE_COPY(DvbCableDescriptor) 933 }; 934 935 class DvbSatelliteDescriptor : public DvbDescriptor 936 { 937 public: 938 explicit DvbSatelliteDescriptor(const DvbDescriptor &descriptor); ~DvbSatelliteDescriptor()939 ~DvbSatelliteDescriptor() { } 940 frequency()941 int frequency() const 942 { 943 return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5); 944 } 945 polarization()946 int polarization() const 947 { 948 return ((at(8) & 0x7f) >> 5); 949 } 950 rollOff()951 int rollOff() const 952 { 953 return ((at(8) & 0x1f) >> 3); 954 } 955 isDvbS2()956 bool isDvbS2() const 957 { 958 return ((at(8) & 0x4) != 0); 959 } 960 modulation()961 int modulation() const 962 { 963 return (at(8) & 0x3); 964 } 965 symbolRate()966 int symbolRate() const 967 { 968 return (at(9) << 20) | (at(10) << 12) | (at(11) << 4) | (at(12) >> 4); 969 } 970 fecRate()971 int fecRate() const 972 { 973 return (at(12) & 0xf); 974 } 975 976 private: 977 Q_DISABLE_COPY(DvbSatelliteDescriptor) 978 }; 979 980 class DvbTerrestrialDescriptor : public DvbDescriptor 981 { 982 public: 983 explicit DvbTerrestrialDescriptor(const DvbDescriptor &descriptor); ~DvbTerrestrialDescriptor()984 ~DvbTerrestrialDescriptor() { } 985 frequency()986 int frequency() const 987 { 988 return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5); 989 } 990 bandwidth()991 int bandwidth() const 992 { 993 return (at(6) >> 5); 994 } 995 constellation()996 int constellation() const 997 { 998 return (at(7) >> 6); 999 } 1000 hierarchy()1001 int hierarchy() const 1002 { 1003 return ((at(7) & 0x3f) >> 3); 1004 } 1005 fecRateHigh()1006 int fecRateHigh() const 1007 { 1008 return (at(7) & 0x7); 1009 } 1010 fecRateLow()1011 int fecRateLow() const 1012 { 1013 return (at(8) >> 5); 1014 } 1015 guardInterval()1016 int guardInterval() const 1017 { 1018 return ((at(8) & 0x1f) >> 3); 1019 } 1020 transmissionMode()1021 int transmissionMode() const 1022 { 1023 return ((at(8) & 0x7) >> 1); 1024 } 1025 1026 private: 1027 Q_DISABLE_COPY(DvbTerrestrialDescriptor) 1028 }; 1029 1030 class IsdbTerrestrialDescriptor : public DvbDescriptor 1031 { 1032 public: 1033 explicit IsdbTerrestrialDescriptor(const DvbDescriptor &descriptor); ~IsdbTerrestrialDescriptor()1034 ~IsdbTerrestrialDescriptor() { } 1035 areaCode()1036 int areaCode() const 1037 { 1038 return (at(2) << 4) | (at(3) >> 4); 1039 } 1040 guardInterval()1041 int guardInterval() const 1042 { 1043 return ((at(3) & 0xf) >> 2); 1044 } 1045 transmissionMode()1046 int transmissionMode() const 1047 { 1048 return (at(3) & 0x3); 1049 } 1050 frequencyLength()1051 int frequencyLength() const 1052 { 1053 return (getLength() - 4) / 2; 1054 } 1055 frequency(int idx)1056 int frequency(int idx) const 1057 { 1058 int pos = (idx * 2) + 4; 1059 return (at(pos) << 8) | at(pos + 1); 1060 } 1061 1062 private: 1063 Q_DISABLE_COPY(IsdbTerrestrialDescriptor) 1064 }; 1065 1066 class AtscChannelNameDescriptor : public DvbDescriptor 1067 { 1068 public: 1069 explicit AtscChannelNameDescriptor(const DvbDescriptor &descriptor); ~AtscChannelNameDescriptor()1070 ~AtscChannelNameDescriptor() { } 1071 name()1072 QString name() const 1073 { 1074 return AtscPsipText::convertText(getData() + 2, getLength() - 2); 1075 } 1076 1077 private: 1078 Q_DISABLE_COPY(AtscChannelNameDescriptor) 1079 }; 1080 1081 class DvbPatSection : public DvbStandardSection 1082 { 1083 public: DvbPatSection(const char * data,int size)1084 DvbPatSection(const char *data, int size) 1085 { 1086 initPatSection(data, size); 1087 } 1088 DvbPatSection(const QByteArray & byteArray)1089 explicit DvbPatSection(const QByteArray &byteArray) 1090 { 1091 initPatSection(byteArray.constData(), byteArray.size()); 1092 } 1093 ~DvbPatSection()1094 ~DvbPatSection() { } 1095 transportStreamId()1096 int transportStreamId() const 1097 { 1098 return (at(3) << 8) | at(4); 1099 } 1100 entries()1101 DvbPatSectionEntry entries() const 1102 { 1103 return DvbPatSectionEntry(getData() + 8, getLength() - 12); 1104 } 1105 1106 private: 1107 Q_DISABLE_COPY(DvbPatSection) 1108 void initPatSection(const char *data, int size); 1109 }; 1110 1111 class DvbPmtSection : public DvbStandardSection 1112 { 1113 public: DvbPmtSection(const char * data,int size)1114 DvbPmtSection(const char *data, int size) 1115 { 1116 initPmtSection(data, size); 1117 } 1118 DvbPmtSection(const QByteArray & byteArray)1119 explicit DvbPmtSection(const QByteArray &byteArray) 1120 { 1121 initPmtSection(byteArray.constData(), byteArray.size()); 1122 } 1123 ~DvbPmtSection()1124 ~DvbPmtSection() { } 1125 programNumber()1126 int programNumber() const 1127 { 1128 return (at(3) << 8) | at(4); 1129 } 1130 pcrPid()1131 int pcrPid() const 1132 { 1133 return ((at(8) & 0x1f) << 8) | at(9); 1134 } 1135 descriptors()1136 DvbDescriptor descriptors() const 1137 { 1138 return DvbDescriptor(getData() + 12, descriptorsLength); 1139 } 1140 entries()1141 DvbPmtSectionEntry entries() const 1142 { 1143 return DvbPmtSectionEntry(getData() + 12 + descriptorsLength, getLength() - (16 + descriptorsLength)); 1144 } 1145 1146 private: 1147 Q_DISABLE_COPY(DvbPmtSection) 1148 void initPmtSection(const char *data, int size); 1149 1150 int descriptorsLength; 1151 }; 1152 1153 class DvbSdtSection : public DvbStandardSection 1154 { 1155 public: DvbSdtSection(const char * data,int size)1156 DvbSdtSection(const char *data, int size) 1157 { 1158 initSdtSection(data, size); 1159 } 1160 DvbSdtSection(const QByteArray & byteArray)1161 explicit DvbSdtSection(const QByteArray &byteArray) 1162 { 1163 initSdtSection(byteArray.constData(), byteArray.size()); 1164 } 1165 ~DvbSdtSection()1166 ~DvbSdtSection() { } 1167 originalNetworkId()1168 int originalNetworkId() const 1169 { 1170 return (at(8) << 8) | at(9); 1171 } 1172 entries()1173 DvbSdtSectionEntry entries() const 1174 { 1175 return DvbSdtSectionEntry(getData() + 11, getLength() - 15); 1176 } 1177 1178 private: 1179 Q_DISABLE_COPY(DvbSdtSection) 1180 void initSdtSection(const char *data, int size); 1181 }; 1182 1183 class DvbEitSection : public DvbStandardSection 1184 { 1185 public: DvbEitSection(const char * data,int size)1186 DvbEitSection(const char *data, int size) 1187 { 1188 initEitSection(data, size); 1189 } 1190 DvbEitSection(const QByteArray & byteArray)1191 explicit DvbEitSection(const QByteArray &byteArray) 1192 { 1193 initEitSection(byteArray.constData(), byteArray.size()); 1194 } 1195 ~DvbEitSection()1196 ~DvbEitSection() { } 1197 serviceId()1198 int serviceId() const 1199 { 1200 return (at(3) << 8) | at(4); 1201 } 1202 transportStreamId()1203 int transportStreamId() const 1204 { 1205 return (at(8) << 8) | at(9); 1206 } 1207 originalNetworkId()1208 int originalNetworkId() const 1209 { 1210 return (at(10) << 8) | at(11); 1211 } 1212 entries()1213 DvbEitSectionEntry entries() const 1214 { 1215 return DvbEitSectionEntry(getData() + 14, getLength() - 18); 1216 } 1217 1218 private: 1219 Q_DISABLE_COPY(DvbEitSection) 1220 void initEitSection(const char *data, int size); 1221 }; 1222 1223 class DvbNitSection : public DvbStandardSection 1224 { 1225 public: DvbNitSection(const char * data,int size)1226 DvbNitSection(const char *data, int size) 1227 { 1228 initNitSection(data, size); 1229 } 1230 DvbNitSection(const QByteArray & byteArray)1231 explicit DvbNitSection(const QByteArray &byteArray) 1232 { 1233 initNitSection(byteArray.constData(), byteArray.size()); 1234 } 1235 ~DvbNitSection()1236 ~DvbNitSection() { } 1237 descriptors()1238 DvbDescriptor descriptors() const 1239 { 1240 return DvbDescriptor(getData() + 10, descriptorsLength); 1241 } 1242 entries()1243 DvbNitSectionEntry entries() const 1244 { 1245 return DvbNitSectionEntry(getData() + 12 + descriptorsLength, entriesLength); 1246 } 1247 1248 private: 1249 Q_DISABLE_COPY(DvbNitSection) 1250 void initNitSection(const char *data, int size); 1251 1252 int descriptorsLength; 1253 int entriesLength; 1254 }; 1255 1256 class AtscMgtSection : public DvbStandardSection 1257 { 1258 public: AtscMgtSection(const char * data,int size)1259 AtscMgtSection(const char *data, int size) 1260 { 1261 initMgtSection(data, size); 1262 } 1263 AtscMgtSection(const QByteArray & byteArray)1264 explicit AtscMgtSection(const QByteArray &byteArray) 1265 { 1266 initMgtSection(byteArray.constData(), byteArray.size()); 1267 } 1268 ~AtscMgtSection()1269 ~AtscMgtSection() { } 1270 entryCount()1271 int entryCount() const 1272 { 1273 return (at(9) << 8) | at(10); 1274 } 1275 entries()1276 AtscMgtSectionEntry entries() const 1277 { 1278 return AtscMgtSectionEntry(getData() + 11, getLength() - 17); 1279 } 1280 1281 private: 1282 Q_DISABLE_COPY(AtscMgtSection) 1283 void initMgtSection(const char *data, int size); 1284 }; 1285 1286 class AtscVctSection : public DvbStandardSection 1287 { 1288 public: AtscVctSection(const char * data,int size)1289 AtscVctSection(const char *data, int size) 1290 { 1291 initVctSection(data, size); 1292 } 1293 AtscVctSection(const QByteArray & byteArray)1294 explicit AtscVctSection(const QByteArray &byteArray) 1295 { 1296 initVctSection(byteArray.constData(), byteArray.size()); 1297 } 1298 ~AtscVctSection()1299 ~AtscVctSection() { } 1300 entryCount()1301 int entryCount() const 1302 { 1303 return at(9); 1304 } 1305 entries()1306 AtscVctSectionEntry entries() const 1307 { 1308 return AtscVctSectionEntry(getData() + 10, getLength() - 14); 1309 } 1310 1311 private: 1312 Q_DISABLE_COPY(AtscVctSection) 1313 void initVctSection(const char *data, int size); 1314 }; 1315 1316 class AtscEitSection : public DvbStandardSection 1317 { 1318 public: AtscEitSection(const char * data,int size)1319 AtscEitSection(const char *data, int size) 1320 { 1321 initEitSection(data, size); 1322 } 1323 AtscEitSection(const QByteArray & byteArray)1324 explicit AtscEitSection(const QByteArray &byteArray) 1325 { 1326 initEitSection(byteArray.constData(), byteArray.size()); 1327 } 1328 ~AtscEitSection()1329 ~AtscEitSection() { } 1330 sourceId()1331 int sourceId() const 1332 { 1333 return (at(3) << 8) | at(4); 1334 } 1335 entryCount()1336 int entryCount() const 1337 { 1338 return at(9); 1339 } 1340 entries()1341 AtscEitSectionEntry entries() const 1342 { 1343 return AtscEitSectionEntry(getData() + 10, getLength() - 14); 1344 } 1345 1346 private: 1347 Q_DISABLE_COPY(AtscEitSection) 1348 void initEitSection(const char *data, int size); 1349 }; 1350 1351 class AtscEttSection : public DvbStandardSection 1352 { 1353 public: AtscEttSection(const char * data,int size)1354 AtscEttSection(const char *data, int size) 1355 { 1356 initEttSection(data, size); 1357 } 1358 AtscEttSection(const QByteArray & byteArray)1359 explicit AtscEttSection(const QByteArray &byteArray) 1360 { 1361 initEttSection(byteArray.constData(), byteArray.size()); 1362 } 1363 ~AtscEttSection()1364 ~AtscEttSection() { } 1365 sourceId()1366 int sourceId() const 1367 { 1368 return (at(9) << 8) | at(10); 1369 } 1370 eventId()1371 int eventId() const 1372 { 1373 return (at(11) << 6) | (at(12) >> 2); 1374 } 1375 messageType()1376 int messageType() const 1377 { 1378 return (at(12) & 0x3); 1379 } 1380 text()1381 QString text() const 1382 { 1383 return AtscPsipText::convertText(getData() + 13, getLength() - 17); 1384 } 1385 1386 private: 1387 Q_DISABLE_COPY(AtscEttSection) 1388 void initEttSection(const char *data, int size); 1389 }; 1390 1391 #endif /* DVBSI_H */ 1392