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 &section, 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 &section);
~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