File indexing completed on 2024-05-12 04:52:20

0001 /*
0002  * dvbsi.h
0003  *
0004  * Copyright (C) 2008-2011 Christoph Pfister <christophpfister@gmail.com>
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License as published by
0008  * the Free Software Foundation; either version 2 of the License, or
0009  * (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU General Public License along
0017  * with this program; if not, write to the Free Software Foundation, Inc.,
0018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0019  */
0020 
0021 #ifndef DVBSI_H
0022 #define DVBSI_H
0023 
0024 #include <QPair>
0025 #include <QObject>
0026 #include <QByteArray>
0027 #include <QString>
0028 #include <QTextCodec>
0029 #include "dvbbackenddevice.h"
0030 
0031 class DvbPmtSection;
0032 
0033 class DvbSectionData
0034 {
0035 public:
0036     bool isValid() const
0037     {
0038         return (length > 0);
0039     }
0040 
0041     unsigned char at(int index) const
0042     {
0043         return data[index];
0044     }
0045 
0046     const char *getData() const
0047     {
0048         return data;
0049     }
0050 
0051     int getLength() const
0052     {
0053         return length;
0054     }
0055 
0056     QByteArray toByteArray() const
0057     {
0058         return QByteArray(data, length);
0059     }
0060 
0061 protected:
0062     DvbSectionData() { }
0063     ~DvbSectionData() { }
0064 
0065     void initSectionData()
0066     {
0067         data = NULL;
0068         length = 0;
0069         size = 0;
0070     }
0071 
0072     void initSectionData(const char *data_, int length_, int size_)
0073     {
0074         data = data_;
0075         length = length_;
0076         size = size_;
0077     }
0078 
0079     int getSize() const
0080     {
0081         return size;
0082     }
0083 
0084 private:
0085     const char *data;
0086     int length;
0087     int size;
0088 };
0089 
0090 class DvbSection : public DvbSectionData
0091 {
0092 public:
0093     int getSectionLength() const
0094     {
0095         return getLength();
0096     }
0097 
0098     int tableId() const
0099     {
0100         return at(0);
0101     }
0102 
0103     bool isStandardSection() const
0104     {
0105         return (at(1) & 0x80) != 0;
0106     }
0107 
0108 protected:
0109     DvbSection() { }
0110     ~DvbSection() { }
0111 
0112     void initSection(const char *data, int size);
0113 
0114 private:
0115     Q_DISABLE_COPY(DvbSection)
0116 };
0117 
0118 class DvbStandardSection : public DvbSection
0119 {
0120 public:
0121 
0122     int tableIdExtension() const
0123     {
0124         return (at(3) << 8 | at(4));
0125     }
0126 
0127     int versionNumber() const
0128     {
0129         return (at(5) >> 1) & ((1 << 5) - 1);
0130     }
0131 
0132     bool currentNextIndicator() const
0133     {
0134         return (at(5) & 0x01) != 0;
0135     }
0136 
0137     int sectionNumber() const
0138     {
0139         return at(6);
0140     }
0141 
0142     int lastSectionNumber() const
0143     {
0144         return at(7);
0145     }
0146 
0147     static int verifyCrc32(const char *data, int size);
0148     static const unsigned int crc32Table[];
0149 
0150 protected:
0151     DvbStandardSection() { }
0152     ~DvbStandardSection() { }
0153 
0154     void initStandardSection(const char *data, int size);
0155 
0156 private:
0157     Q_DISABLE_COPY(DvbStandardSection)
0158 };
0159 
0160 class DvbSiText
0161 {
0162 public:
0163     static QString convertText(const char *data, int size);
0164     static void setOverride6937(bool override);
0165 
0166 private:
0167     enum TextEncoding
0168     {
0169         Iso6937     =  0,
0170         Iso8859_1   =  1,
0171         Iso8859_2   =  2,
0172         Iso8859_3   =  3,
0173         Iso8859_4   =  4,
0174         Iso8859_5   =  5,
0175         Iso8859_6   =  6,
0176         Iso8859_7   =  7,
0177         Iso8859_8   =  8,
0178         Iso8859_9   =  9,
0179         Iso8859_10  = 10,
0180         Iso8859_11  = 11,
0181         Iso8859_13  = 12,
0182         Iso8859_14  = 13,
0183         Iso8859_15  = 14,
0184         Iso2022_kr  = 15,
0185         Iso10646_ucs2   = 16,
0186         Gb2312      = 17,
0187         Utf_16be    = 18,
0188         Utf_8       = 19,
0189         EncodingTypeMax = 19
0190     };
0191 
0192     static QTextCodec *codecTable[EncodingTypeMax + 1];
0193     static bool override6937;
0194 };
0195 
0196 class DvbDescriptor : public DvbSectionData
0197 {
0198 public:
0199     DvbDescriptor(const char *data, int size)
0200     {
0201         initDescriptor(data, size);
0202     }
0203 
0204     ~DvbDescriptor() { }
0205 
0206     int descriptorTag() const
0207     {
0208         return at(0);
0209     }
0210 
0211     void advance()
0212     {
0213         initDescriptor(getData() + getLength(), getSize() - getLength());
0214     }
0215 
0216     static int bcdToInt(unsigned int bcd, int multiplier)
0217     {
0218         int value = 0;
0219 
0220         while (bcd != 0) {
0221             value += (bcd & 0xf) * multiplier;
0222             multiplier *= 10;
0223             bcd >>= 4;
0224         }
0225 
0226         return value;
0227     }
0228 
0229 private:
0230     void initDescriptor(const char *data, int size);
0231 };
0232 
0233 // ATSC "Multiple String Structure".  See A/65C Section 6.10
0234 class AtscPsipText
0235 {
0236 public:
0237     static QString convertText(const char *data, int size);
0238 
0239 private:
0240     static QString interpretTextData(const char *data, unsigned int len,
0241                      unsigned int mode);
0242 };
0243 
0244 // ATSC Huffman compressed string support, conforming to A/65C Annex C
0245 class AtscHuffmanString
0246 {
0247 public:
0248     static QString convertText(const char *data_, int size, int table);
0249 private:
0250     AtscHuffmanString(const char *data_, int size, int table);
0251     ~AtscHuffmanString();
0252     bool hasBits();
0253     unsigned char getBit();
0254     unsigned char getByte();
0255     void decompress();
0256 
0257     const char *data;
0258     int bitsLeft;
0259 
0260     QString result;
0261     const unsigned short *offsets;
0262     const unsigned char *tableBase;
0263 
0264     static const unsigned short Huffman1Offsets[128];
0265     static const unsigned char Huffman1Tables[];
0266 
0267     static const unsigned short Huffman2Offsets[128];
0268     static const unsigned char Huffman2Tables[];
0269 };
0270 
0271 class DvbPmtFilter : public QObject, public DvbSectionFilter
0272 {
0273     Q_OBJECT
0274 public:
0275     DvbPmtFilter() : programNumber(-1) { }
0276     ~DvbPmtFilter() { }
0277 
0278     void setProgramNumber(int programNumber_)
0279     {
0280         programNumber = programNumber_;
0281     }
0282 
0283 signals:
0284     void pmtSectionChanged(const QByteArray &pmtSectionData);
0285 
0286 private:
0287     void processSection(const char *data, int size) override;
0288 
0289     int programNumber;
0290     QByteArray lastPmtSectionData;
0291 };
0292 
0293 class DvbSectionGenerator
0294 {
0295 public:
0296     DvbSectionGenerator() : versionNumber(0), continuityCounter(0) { }
0297     ~DvbSectionGenerator() { }
0298 
0299     void initPat(int transportStreamId, int programNumber, int pmtPid);
0300     void initPmt(int pmtPid, const DvbPmtSection &section, const QList<int> &pids);
0301 
0302     void reset()
0303     {
0304         packets.clear();
0305         versionNumber = 0;
0306         continuityCounter = 0;
0307     }
0308 
0309     QByteArray generatePackets();
0310 
0311 private:
0312     char *startSection(int sectionLength);
0313     void endSection(int sectionLength, int pid);
0314 
0315     QByteArray packets;
0316     int versionNumber;
0317     int continuityCounter;
0318 };
0319 
0320 class DvbPmtParser
0321 {
0322 public:
0323     explicit DvbPmtParser(const DvbPmtSection &section);
0324     ~DvbPmtParser() { }
0325 
0326     int videoPid;
0327     QList<QPair<int, QString> > audioPids; // QString = language code (may be empty)
0328     QList<QPair<int, QString> > subtitlePids; // QString = language code
0329     int teletextPid;
0330 };
0331 
0332 class AtscEitSectionEntry : public DvbSectionData
0333 {
0334 public:
0335     AtscEitSectionEntry(const char *data, int size)
0336     {
0337         initEitSectionEntry(data, size);
0338     }
0339 
0340     ~AtscEitSectionEntry() { }
0341 
0342     void advance()
0343     {
0344         initEitSectionEntry(getData() + getLength(), getSize() - getLength());
0345     }
0346 
0347     int eventId() const
0348     {
0349         return ((at(0) & 0x3f) << 8) | at(1);
0350     }
0351 
0352     int startTime() const
0353     {
0354         return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5);
0355     }
0356 
0357     int duration() const
0358     {
0359         return ((at(6) & 0xf) << 16) | (at(7) << 8) | at(8);
0360     }
0361 
0362     QString title() const
0363     {
0364         return AtscPsipText::convertText(getData() + 10, titleLength);
0365     }
0366 
0367 private:
0368     void initEitSectionEntry(const char *data, int size);
0369 
0370     int titleLength;
0371 };
0372 
0373 // everything below this line is automatically generated
0374 
0375 class DvbPatSectionEntry : public DvbSectionData
0376 {
0377 public:
0378     DvbPatSectionEntry(const char *data, int size)
0379     {
0380         initPatSectionEntry(data, size);
0381     }
0382 
0383     ~DvbPatSectionEntry() { }
0384 
0385     void advance()
0386     {
0387         initPatSectionEntry(getData() + getLength(), getSize() - getLength());
0388     }
0389 
0390     int programNumber() const
0391     {
0392         return (at(0) << 8) | at(1);
0393     }
0394 
0395     int pid() const
0396     {
0397         return ((at(2) & 0x1f) << 8) | at(3);
0398     }
0399 
0400 private:
0401     void initPatSectionEntry(const char *data, int size);
0402 };
0403 
0404 class DvbPmtSectionEntry : public DvbSectionData
0405 {
0406 public:
0407     DvbPmtSectionEntry(const char *data, int size)
0408     {
0409         initPmtSectionEntry(data, size);
0410     }
0411 
0412     ~DvbPmtSectionEntry() { }
0413 
0414     void advance()
0415     {
0416         initPmtSectionEntry(getData() + getLength(), getSize() - getLength());
0417     }
0418 
0419     int streamType() const
0420     {
0421         return at(0);
0422     }
0423 
0424     int pid() const
0425     {
0426         return ((at(1) & 0x1f) << 8) | at(2);
0427     }
0428 
0429     DvbDescriptor descriptors() const
0430     {
0431         return DvbDescriptor(getData() + 5, getLength() - 5);
0432     }
0433 
0434 private:
0435     void initPmtSectionEntry(const char *data, int size);
0436 };
0437 
0438 class DvbSdtSectionEntry : public DvbSectionData
0439 {
0440 public:
0441     DvbSdtSectionEntry(const char *data, int size)
0442     {
0443         initSdtSectionEntry(data, size);
0444     }
0445 
0446     ~DvbSdtSectionEntry() { }
0447 
0448     void advance()
0449     {
0450         initSdtSectionEntry(getData() + getLength(), getSize() - getLength());
0451     }
0452 
0453     int serviceId() const
0454     {
0455         return (at(0) << 8) | at(1);
0456     }
0457 
0458     bool isScrambled() const
0459     {
0460         return ((at(3) & 0x10) != 0);
0461     }
0462 
0463     DvbDescriptor descriptors() const
0464     {
0465         return DvbDescriptor(getData() + 5, getLength() - 5);
0466     }
0467 
0468 private:
0469     void initSdtSectionEntry(const char *data, int size);
0470 };
0471 
0472 class DvbEitSectionEntry : public DvbSectionData
0473 {
0474 public:
0475     DvbEitSectionEntry(const char *data, int size)
0476     {
0477         initEitSectionEntry(data, size);
0478     }
0479 
0480     ~DvbEitSectionEntry() { }
0481 
0482     void advance()
0483     {
0484         initEitSectionEntry(getData() + getLength(), getSize() - getLength());
0485     }
0486 
0487     int startDate() const
0488     {
0489         return (at(2) << 8) | at(3);
0490     }
0491 
0492     int startTime() const
0493     {
0494         return (at(4) << 16) | (at(5) << 8) | at(6);
0495     }
0496 
0497     int duration() const
0498     {
0499         return (at(7) << 16) | (at(8) << 8) | at(9);
0500     }
0501 
0502     DvbDescriptor descriptors() const
0503     {
0504         return DvbDescriptor(getData() + 12, getLength() - 12);
0505     }
0506 
0507 private:
0508     void initEitSectionEntry(const char *data, int size);
0509 };
0510 
0511 class DvbEitContentEntry : public DvbSectionData
0512 {
0513 public:
0514     DvbEitContentEntry(const char *data, int size)
0515     {
0516         initEitContentEntry(data, size);
0517     }
0518 
0519     ~DvbEitContentEntry() { }
0520 
0521     void advance()
0522     {
0523         initEitContentEntry(getData() + getLength(), getSize() - getLength());
0524     }
0525 
0526     int contentNibbleLevel1() const
0527     {
0528         return (at(0) >> 4);
0529     }
0530 
0531     int contentNibbleLevel2() const
0532     {
0533         return (at(0) & 0xf);
0534     }
0535 
0536     int userByte() const
0537     {
0538         return at(1);
0539     }
0540 
0541 private:
0542     void initEitContentEntry(const char *data, int size);
0543 };
0544 
0545 class DvbParentalRatingEntry : public DvbSectionData
0546 {
0547 public:
0548     DvbParentalRatingEntry(const char *data, int size)
0549     {
0550         initParentalRatingEntry(data, size);
0551     }
0552 
0553     ~DvbParentalRatingEntry() { }
0554 
0555     void advance()
0556     {
0557         initParentalRatingEntry(getData() + getLength(), getSize() - getLength());
0558     }
0559 
0560     int languageCode1() const
0561     {
0562         return at(0);
0563     }
0564 
0565     int languageCode2() const
0566     {
0567         return at(1);
0568     }
0569 
0570     int languageCode3() const
0571     {
0572         return at(2);
0573     }
0574 
0575     int rating() const
0576     {
0577         return at(3);
0578     }
0579 
0580 private:
0581     void initParentalRatingEntry(const char *data, int size);
0582 };
0583 
0584 class DvbNitSectionEntry : public DvbSectionData
0585 {
0586 public:
0587     DvbNitSectionEntry(const char *data, int size)
0588     {
0589         initNitSectionEntry(data, size);
0590     }
0591 
0592     ~DvbNitSectionEntry() { }
0593 
0594     void advance()
0595     {
0596         initNitSectionEntry(getData() + getLength(), getSize() - getLength());
0597     }
0598 
0599     DvbDescriptor descriptors() const
0600     {
0601         return DvbDescriptor(getData() + 6, getLength() - 6);
0602     }
0603 
0604 private:
0605     void initNitSectionEntry(const char *data, int size);
0606 };
0607 
0608 class AtscMgtSectionEntry : public DvbSectionData
0609 {
0610 public:
0611     AtscMgtSectionEntry(const char *data, int size)
0612     {
0613         initMgtSectionEntry(data, size);
0614     }
0615 
0616     ~AtscMgtSectionEntry() { }
0617 
0618     void advance()
0619     {
0620         initMgtSectionEntry(getData() + getLength(), getSize() - getLength());
0621     }
0622 
0623     int tableType() const
0624     {
0625         return (at(0) << 8) | at(1);
0626     }
0627 
0628     int pid() const
0629     {
0630         return ((at(2) & 0x1f) << 8) | at(3);
0631     }
0632 
0633     DvbDescriptor descriptors() const
0634     {
0635         return DvbDescriptor(getData() + 11, getLength() - 11);
0636     }
0637 
0638 private:
0639     void initMgtSectionEntry(const char *data, int size);
0640 };
0641 
0642 class AtscVctSectionEntry : public DvbSectionData
0643 {
0644 public:
0645     AtscVctSectionEntry(const char *data, int size)
0646     {
0647         initVctSectionEntry(data, size);
0648     }
0649 
0650     ~AtscVctSectionEntry() { }
0651 
0652     void advance()
0653     {
0654         initVctSectionEntry(getData() + getLength(), getSize() - getLength());
0655     }
0656 
0657     int shortName1() const
0658     {
0659         return (at(0) << 8) | at(1);
0660     }
0661 
0662     int shortName2() const
0663     {
0664         return (at(2) << 8) | at(3);
0665     }
0666 
0667     int shortName3() const
0668     {
0669         return (at(4) << 8) | at(5);
0670     }
0671 
0672     int shortName4() const
0673     {
0674         return (at(6) << 8) | at(7);
0675     }
0676 
0677     int shortName5() const
0678     {
0679         return (at(8) << 8) | at(9);
0680     }
0681 
0682     int shortName6() const
0683     {
0684         return (at(10) << 8) | at(11);
0685     }
0686 
0687     int shortName7() const
0688     {
0689         return (at(12) << 8) | at(13);
0690     }
0691 
0692     int majorNumber() const
0693     {
0694         return ((at(14) & 0xf) << 6) | (at(15) >> 2);
0695     }
0696 
0697     int minorNumber() const
0698     {
0699         return ((at(15) & 0x3) << 8) | at(16);
0700     }
0701 
0702     int programNumber() const
0703     {
0704         return (at(24) << 8) | at(25);
0705     }
0706 
0707     bool isScrambled() const
0708     {
0709         return ((at(26) & 0x20) != 0);
0710     }
0711 
0712     int sourceId() const
0713     {
0714         return (at(28) << 8) | at(29);
0715     }
0716 
0717     DvbDescriptor descriptors() const
0718     {
0719         return DvbDescriptor(getData() + 32, getLength() - 32);
0720     }
0721 
0722 private:
0723     void initVctSectionEntry(const char *data, int size);
0724 };
0725 
0726 class DvbRegistrationDescriptor : public DvbDescriptor
0727 {
0728 public:
0729     explicit DvbRegistrationDescriptor(const DvbDescriptor &descriptor);
0730     ~DvbRegistrationDescriptor() { }
0731 
0732     int formatIdentifier0() const
0733     {
0734         return at(2);
0735     }
0736 
0737     int formatIdentifier1() const
0738     {
0739         return at(3);
0740     }
0741 
0742     int formatIdentifier2() const
0743     {
0744         return at(4);
0745     }
0746 
0747     int formatIdentifier3() const
0748     {
0749         return at(5);
0750     }
0751 
0752 private:
0753     Q_DISABLE_COPY(DvbRegistrationDescriptor)
0754 };
0755 
0756 class DvbLanguageDescriptor : public DvbDescriptor
0757 {
0758 public:
0759     explicit DvbLanguageDescriptor(const DvbDescriptor &descriptor);
0760     ~DvbLanguageDescriptor() { }
0761 
0762     int languageCode1() const
0763     {
0764         return at(2);
0765     }
0766 
0767     int languageCode2() const
0768     {
0769         return at(3);
0770     }
0771 
0772     int languageCode3() const
0773     {
0774         return at(4);
0775     }
0776 
0777 private:
0778     Q_DISABLE_COPY(DvbLanguageDescriptor)
0779 };
0780 
0781 class DvbSubtitleDescriptor : public DvbDescriptor
0782 {
0783 public:
0784     explicit DvbSubtitleDescriptor(const DvbDescriptor &descriptor);
0785     ~DvbSubtitleDescriptor() { }
0786 
0787     int languageCode1() const
0788     {
0789         return at(2);
0790     }
0791 
0792     int languageCode2() const
0793     {
0794         return at(3);
0795     }
0796 
0797     int languageCode3() const
0798     {
0799         return at(4);
0800     }
0801 
0802     int subtitleType() const
0803     {
0804         return at(5);
0805     }
0806 
0807 private:
0808     Q_DISABLE_COPY(DvbSubtitleDescriptor)
0809 };
0810 
0811 class DvbServiceDescriptor : public DvbDescriptor
0812 {
0813 public:
0814     explicit DvbServiceDescriptor(const DvbDescriptor &descriptor);
0815     ~DvbServiceDescriptor() { }
0816 
0817     QString providerName() const
0818     {
0819         return DvbSiText::convertText(getData() + 4, providerNameLength);
0820     }
0821 
0822     QString serviceName() const
0823     {
0824         return DvbSiText::convertText(getData() + 5 + providerNameLength, serviceNameLength);
0825     }
0826 
0827 private:
0828     Q_DISABLE_COPY(DvbServiceDescriptor)
0829 
0830     int providerNameLength;
0831     int serviceNameLength;
0832 };
0833 
0834 class DvbShortEventDescriptor : public DvbDescriptor
0835 {
0836 public:
0837     explicit DvbShortEventDescriptor(const DvbDescriptor &descriptor);
0838     ~DvbShortEventDescriptor() { }
0839 
0840     int languageCode1() const
0841     {
0842         return at(2);
0843     }
0844 
0845     int languageCode2() const
0846     {
0847         return at(3);
0848     }
0849 
0850     int languageCode3() const
0851     {
0852         return at(4);
0853     }
0854 
0855     QString eventName() const
0856     {
0857         return DvbSiText::convertText(getData() + 6, eventNameLength);
0858     }
0859 
0860     QString text() const
0861     {
0862         return DvbSiText::convertText(getData() + 7 + eventNameLength, textLength);
0863     }
0864 
0865 private:
0866     Q_DISABLE_COPY(DvbShortEventDescriptor)
0867 
0868     int eventNameLength;
0869     int textLength;
0870 };
0871 
0872 class DvbExtendedEventDescriptor : public DvbDescriptor
0873 {
0874 public:
0875     explicit DvbExtendedEventDescriptor(const DvbDescriptor &descriptor);
0876     ~DvbExtendedEventDescriptor() { }
0877 
0878     int languageCode1() const
0879     {
0880         return at(3);
0881     }
0882 
0883     int languageCode2() const
0884     {
0885         return at(4);
0886     }
0887 
0888     int languageCode3() const
0889     {
0890         return at(5);
0891     }
0892 
0893     QString text() const
0894     {
0895         return DvbSiText::convertText(getData() + 8 + itemsLength, textLength);
0896     }
0897 
0898 private:
0899     Q_DISABLE_COPY(DvbExtendedEventDescriptor)
0900 
0901     int itemsLength;
0902     int textLength;
0903 };
0904 
0905 class DvbContentDescriptor : public DvbDescriptor
0906 {
0907 public:
0908     explicit DvbContentDescriptor(const DvbDescriptor &descriptor);
0909     ~DvbContentDescriptor() { }
0910 
0911     DvbEitContentEntry contents() const
0912     {
0913         return DvbEitContentEntry(getData() + 2, getLength() - 2);
0914     }
0915 
0916 private:
0917     Q_DISABLE_COPY(DvbContentDescriptor)
0918 };
0919 
0920 class DvbParentalRatingDescriptor : public DvbDescriptor
0921 {
0922 public:
0923     explicit DvbParentalRatingDescriptor(const DvbDescriptor &descriptor);
0924     ~DvbParentalRatingDescriptor() { }
0925 
0926     DvbParentalRatingEntry contents() const
0927     {
0928         return DvbParentalRatingEntry(getData() + 2, getLength() - 2);
0929     }
0930 
0931 private:
0932     Q_DISABLE_COPY(DvbParentalRatingDescriptor)
0933 };
0934 
0935 class DvbCableDescriptor : public DvbDescriptor
0936 {
0937 public:
0938     explicit DvbCableDescriptor(const DvbDescriptor &descriptor);
0939     ~DvbCableDescriptor() { }
0940 
0941     int frequency() const
0942     {
0943         return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5);
0944     }
0945 
0946     int modulation() const
0947     {
0948         return at(8);
0949     }
0950 
0951     int symbolRate() const
0952     {
0953         return (at(9) << 20) | (at(10) << 12) | (at(11) << 4) | (at(12) >> 4);
0954     }
0955 
0956     int fecRate() const
0957     {
0958         return (at(12) & 0xf);
0959     }
0960 
0961 private:
0962     Q_DISABLE_COPY(DvbCableDescriptor)
0963 };
0964 
0965 class DvbSatelliteDescriptor : public DvbDescriptor
0966 {
0967 public:
0968     explicit DvbSatelliteDescriptor(const DvbDescriptor &descriptor);
0969     ~DvbSatelliteDescriptor() { }
0970 
0971     int frequency() const
0972     {
0973         return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5);
0974     }
0975 
0976     int polarization() const
0977     {
0978         return ((at(8) & 0x7f) >> 5);
0979     }
0980 
0981     int rollOff() const
0982     {
0983         return ((at(8) & 0x1f) >> 3);
0984     }
0985 
0986     bool isDvbS2() const
0987     {
0988         return ((at(8) & 0x4) != 0);
0989     }
0990 
0991     int modulation() const
0992     {
0993         return (at(8) & 0x3);
0994     }
0995 
0996     int symbolRate() const
0997     {
0998         return (at(9) << 20) | (at(10) << 12) | (at(11) << 4) | (at(12) >> 4);
0999     }
1000 
1001     int fecRate() const
1002     {
1003         return (at(12) & 0xf);
1004     }
1005 
1006 private:
1007     Q_DISABLE_COPY(DvbSatelliteDescriptor)
1008 };
1009 
1010 class DvbTerrestrialDescriptor : public DvbDescriptor
1011 {
1012 public:
1013     explicit DvbTerrestrialDescriptor(const DvbDescriptor &descriptor);
1014     ~DvbTerrestrialDescriptor() { }
1015 
1016     int frequency() const
1017     {
1018         return (at(2) << 24) | (at(3) << 16) | (at(4) << 8) | at(5);
1019     }
1020 
1021     int bandwidth() const
1022     {
1023         return (at(6) >> 5);
1024     }
1025 
1026     int constellation() const
1027     {
1028         return (at(7) >> 6);
1029     }
1030 
1031     int hierarchy() const
1032     {
1033         return ((at(7) & 0x3f) >> 3);
1034     }
1035 
1036     int fecRateHigh() const
1037     {
1038         return (at(7) & 0x7);
1039     }
1040 
1041     int fecRateLow() const
1042     {
1043         return (at(8) >> 5);
1044     }
1045 
1046     int guardInterval() const
1047     {
1048         return ((at(8) & 0x1f) >> 3);
1049     }
1050 
1051     int transmissionMode() const
1052     {
1053         return ((at(8) & 0x7) >> 1);
1054     }
1055 
1056 private:
1057     Q_DISABLE_COPY(DvbTerrestrialDescriptor)
1058 };
1059 
1060 class IsdbTerrestrialDescriptor : public DvbDescriptor
1061 {
1062 public:
1063     explicit IsdbTerrestrialDescriptor(const DvbDescriptor &descriptor);
1064     ~IsdbTerrestrialDescriptor() { }
1065 
1066     int areaCode() const
1067     {
1068         return (at(2) << 4) | (at(3) >> 4);
1069     }
1070 
1071     int guardInterval() const
1072     {
1073         return ((at(3) & 0xf) >> 2);
1074     }
1075 
1076     int transmissionMode() const
1077     {
1078         return (at(3) & 0x3);
1079     }
1080 
1081     int frequencyLength() const
1082     {
1083         return (getLength() - 4) / 2;
1084     }
1085 
1086     int frequency(int idx) const
1087     {
1088         int pos = (idx * 2) + 4;
1089         return (at(pos) << 8) | at(pos + 1);
1090     }
1091 
1092 private:
1093     Q_DISABLE_COPY(IsdbTerrestrialDescriptor)
1094 };
1095 
1096 class AtscChannelNameDescriptor : public DvbDescriptor
1097 {
1098 public:
1099     explicit AtscChannelNameDescriptor(const DvbDescriptor &descriptor);
1100     ~AtscChannelNameDescriptor() { }
1101 
1102     QString name() const
1103     {
1104         return AtscPsipText::convertText(getData() + 2, getLength() - 2);
1105     }
1106 
1107 private:
1108     Q_DISABLE_COPY(AtscChannelNameDescriptor)
1109 };
1110 
1111 class DvbPatSection : public DvbStandardSection
1112 {
1113 public:
1114     DvbPatSection(const char *data, int size)
1115     {
1116         initPatSection(data, size);
1117     }
1118 
1119     explicit DvbPatSection(const QByteArray &byteArray)
1120     {
1121         initPatSection(byteArray.constData(), byteArray.size());
1122     }
1123 
1124     ~DvbPatSection() { }
1125 
1126     int transportStreamId() const
1127     {
1128         return (at(3) << 8) | at(4);
1129     }
1130 
1131     DvbPatSectionEntry entries() const
1132     {
1133         return DvbPatSectionEntry(getData() + 8, getLength() - 12);
1134     }
1135 
1136 private:
1137     Q_DISABLE_COPY(DvbPatSection)
1138     void initPatSection(const char *data, int size);
1139 };
1140 
1141 class DvbPmtSection : public DvbStandardSection
1142 {
1143 public:
1144     DvbPmtSection(const char *data, int size)
1145     {
1146         initPmtSection(data, size);
1147     }
1148 
1149     explicit DvbPmtSection(const QByteArray &byteArray)
1150     {
1151         initPmtSection(byteArray.constData(), byteArray.size());
1152     }
1153 
1154     ~DvbPmtSection() { }
1155 
1156     int programNumber() const
1157     {
1158         return (at(3) << 8) | at(4);
1159     }
1160 
1161     int pcrPid() const
1162     {
1163         return ((at(8) & 0x1f) << 8) | at(9);
1164     }
1165 
1166     DvbDescriptor descriptors() const
1167     {
1168         return DvbDescriptor(getData() + 12, descriptorsLength);
1169     }
1170 
1171     DvbPmtSectionEntry entries() const
1172     {
1173         return DvbPmtSectionEntry(getData() + 12 + descriptorsLength, getLength() - (16 + descriptorsLength));
1174     }
1175 
1176 private:
1177     Q_DISABLE_COPY(DvbPmtSection)
1178     void initPmtSection(const char *data, int size);
1179 
1180     int descriptorsLength;
1181 };
1182 
1183 class DvbSdtSection : public DvbStandardSection
1184 {
1185 public:
1186     DvbSdtSection(const char *data, int size)
1187     {
1188         initSdtSection(data, size);
1189     }
1190 
1191     explicit DvbSdtSection(const QByteArray &byteArray)
1192     {
1193         initSdtSection(byteArray.constData(), byteArray.size());
1194     }
1195 
1196     ~DvbSdtSection() { }
1197 
1198     int originalNetworkId() const
1199     {
1200         return (at(8) << 8) | at(9);
1201     }
1202 
1203     DvbSdtSectionEntry entries() const
1204     {
1205         return DvbSdtSectionEntry(getData() + 11, getLength() - 15);
1206     }
1207 
1208 private:
1209     Q_DISABLE_COPY(DvbSdtSection)
1210     void initSdtSection(const char *data, int size);
1211 };
1212 
1213 class DvbEitSection : public DvbStandardSection
1214 {
1215 public:
1216     DvbEitSection(const char *data, int size)
1217     {
1218         initEitSection(data, size);
1219     }
1220 
1221     explicit DvbEitSection(const QByteArray &byteArray)
1222     {
1223         initEitSection(byteArray.constData(), byteArray.size());
1224     }
1225 
1226     ~DvbEitSection() { }
1227 
1228     int serviceId() const
1229     {
1230         return (at(3) << 8) | at(4);
1231     }
1232 
1233     int transportStreamId() const
1234     {
1235         return (at(8) << 8) | at(9);
1236     }
1237 
1238     int originalNetworkId() const
1239     {
1240         return (at(10) << 8) | at(11);
1241     }
1242 
1243     DvbEitSectionEntry entries() const
1244     {
1245         return DvbEitSectionEntry(getData() + 14, getLength() - 18);
1246     }
1247 
1248 private:
1249     Q_DISABLE_COPY(DvbEitSection)
1250     void initEitSection(const char *data, int size);
1251 };
1252 
1253 class DvbNitSection : public DvbStandardSection
1254 {
1255 public:
1256     DvbNitSection(const char *data, int size)
1257     {
1258         initNitSection(data, size);
1259     }
1260 
1261     explicit DvbNitSection(const QByteArray &byteArray)
1262     {
1263         initNitSection(byteArray.constData(), byteArray.size());
1264     }
1265 
1266     ~DvbNitSection() { }
1267 
1268     DvbDescriptor descriptors() const
1269     {
1270         return DvbDescriptor(getData() + 10, descriptorsLength);
1271     }
1272 
1273     DvbNitSectionEntry entries() const
1274     {
1275         return DvbNitSectionEntry(getData() + 12 + descriptorsLength, entriesLength);
1276     }
1277 
1278 private:
1279     Q_DISABLE_COPY(DvbNitSection)
1280     void initNitSection(const char *data, int size);
1281 
1282     int descriptorsLength;
1283     int entriesLength;
1284 };
1285 
1286 class AtscMgtSection : public DvbStandardSection
1287 {
1288 public:
1289     AtscMgtSection(const char *data, int size)
1290     {
1291         initMgtSection(data, size);
1292     }
1293 
1294     explicit AtscMgtSection(const QByteArray &byteArray)
1295     {
1296         initMgtSection(byteArray.constData(), byteArray.size());
1297     }
1298 
1299     ~AtscMgtSection() { }
1300 
1301     int entryCount() const
1302     {
1303         return (at(9) << 8) | at(10);
1304     }
1305 
1306     AtscMgtSectionEntry entries() const
1307     {
1308         return AtscMgtSectionEntry(getData() + 11, getLength() - 17);
1309     }
1310 
1311 private:
1312     Q_DISABLE_COPY(AtscMgtSection)
1313     void initMgtSection(const char *data, int size);
1314 };
1315 
1316 class AtscVctSection : public DvbStandardSection
1317 {
1318 public:
1319     AtscVctSection(const char *data, int size)
1320     {
1321         initVctSection(data, size);
1322     }
1323 
1324     explicit AtscVctSection(const QByteArray &byteArray)
1325     {
1326         initVctSection(byteArray.constData(), byteArray.size());
1327     }
1328 
1329     ~AtscVctSection() { }
1330 
1331     int entryCount() const
1332     {
1333         return at(9);
1334     }
1335 
1336     AtscVctSectionEntry entries() const
1337     {
1338         return AtscVctSectionEntry(getData() + 10, getLength() - 14);
1339     }
1340 
1341 private:
1342     Q_DISABLE_COPY(AtscVctSection)
1343     void initVctSection(const char *data, int size);
1344 };
1345 
1346 class AtscEitSection : public DvbStandardSection
1347 {
1348 public:
1349     AtscEitSection(const char *data, int size)
1350     {
1351         initEitSection(data, size);
1352     }
1353 
1354     explicit AtscEitSection(const QByteArray &byteArray)
1355     {
1356         initEitSection(byteArray.constData(), byteArray.size());
1357     }
1358 
1359     ~AtscEitSection() { }
1360 
1361     int sourceId() const
1362     {
1363         return (at(3) << 8) | at(4);
1364     }
1365 
1366     int entryCount() const
1367     {
1368         return at(9);
1369     }
1370 
1371     AtscEitSectionEntry entries() const
1372     {
1373         return AtscEitSectionEntry(getData() + 10, getLength() - 14);
1374     }
1375 
1376 private:
1377     Q_DISABLE_COPY(AtscEitSection)
1378     void initEitSection(const char *data, int size);
1379 };
1380 
1381 class AtscEttSection : public DvbStandardSection
1382 {
1383 public:
1384     AtscEttSection(const char *data, int size)
1385     {
1386         initEttSection(data, size);
1387     }
1388 
1389     explicit AtscEttSection(const QByteArray &byteArray)
1390     {
1391         initEttSection(byteArray.constData(), byteArray.size());
1392     }
1393 
1394     ~AtscEttSection() { }
1395 
1396     int sourceId() const
1397     {
1398         return (at(9) << 8) | at(10);
1399     }
1400 
1401     int eventId() const
1402     {
1403         return (at(11) << 6) | (at(12) >> 2);
1404     }
1405 
1406     int messageType() const
1407     {
1408         return (at(12) & 0x3);
1409     }
1410 
1411     QString text() const
1412     {
1413         return AtscPsipText::convertText(getData() + 13, getLength() - 17);
1414     }
1415 
1416 private:
1417     Q_DISABLE_COPY(AtscEttSection)
1418     void initEttSection(const char *data, int size);
1419 };
1420 
1421 #endif /* DVBSI_H */