1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// A parser for a MPEG Transport Stream
19// Implementation
20
21#include "MPEG2TransportStreamParser.hh"
22
23void MPEG2TransportStreamParser::parsePAT(Boolean pusi, unsigned numDataBytes) {
24#ifdef DEBUG_CONTENTS
25 fprintf(stderr, "\tProgram Association Table\n");
26#endif
27 unsigned startPos = curOffset();
28
29 do {
30 if (pusi) {
31 u_int8_t pointer_field = get1Byte();
32 skipBytes(pointer_field); // usually 0
33 }
34
35 u_int8_t table_id = get1Byte();
36 if (table_id != 0x00) {
37#ifdef DEBUG_ERRORS
38 fprintf(stderr, "MPEG2TransportStreamParser::parsePAT(%d, %d): bad table_id: 0x%02x\n",
39 pusi, numDataBytes, table_id);
40#endif
41 break;
42 }
43
44 u_int16_t flagsPlusSection_length = get2Bytes();
45 u_int16_t section_length = flagsPlusSection_length&0x0FFF;
46#ifdef DEBUG_CONTENTS
47 fprintf(stderr, "\t\tsection_length: %d\n", section_length);
48#endif
49 if (section_length < 9/*too small for remaining fields + CRC*/ ||
50 section_length > 1021/*as per specification*/) {
51#ifdef DEBUG_ERRORS
52 fprintf(stderr, "MPEG2TransportStreamParser::parsePAT(%d, %d): Bad section_length: %d\n",
53 pusi, numDataBytes, section_length);
54#endif
55 break;
56 }
57
58 unsigned endPos = curOffset() + section_length;
59 if (endPos - startPos > numDataBytes) {
60#ifdef DEBUG_ERRORS
61 fprintf(stderr, "MPEG2TransportStreamParser::parsePAT(%d, %d): section_length %d gives us a total size %d that's too large!\n",
62 pusi, numDataBytes, section_length, endPos - startPos);
63#endif
64 break;
65 }
66
67#ifdef DEBUG_CONTENTS
68 u_int16_t transport_stream_id = get2Bytes();
69 fprintf(stderr, "\t\ttransport_stream_id: 0x%04x\n", transport_stream_id);
70 u_int8_t version_number_byte = get1Byte();
71 u_int8_t version_number = (version_number_byte&0x1E)>>1;
72 u_int8_t section_number = get1Byte();
73 u_int8_t last_section_number = get1Byte();
74 fprintf(stderr, "\t\tversion_number: %d; section_number: %d; last_section_number: %d\n",
75 version_number, section_number, last_section_number);
76#else
77 skipBytes(5);
78#endif
79
80 while (curOffset() <= endPos - 4/*for CRC*/ - 4/*for a program_number+PID*/) {
81 u_int16_t program_number = get2Bytes();
82 u_int16_t pid = get2Bytes()&0x1FFF;
83
84#ifdef DEBUG_CONTENTS
85 fprintf(stderr, "\t\tprogram_number: %d; PID: 0x%04x\n", program_number, pid);
86#endif
87 if (program_number != 0x0000) {
88 if (fPIDState[pid] == NULL) fPIDState[pid] = new PIDState_PMT(*this, pid, program_number);
89 }
90 }
91 } while (0);
92
93 // Skip (ignore) all remaining bytes in this packet (including the CRC):
94 int numBytesLeft = numDataBytes - (curOffset() - startPos);
95 if (numBytesLeft > 0) {
96#ifdef DEBUG_CONTENTS
97 fprintf(stderr, "\t\t+%d CRC and stuffing bytes\n", numBytesLeft);
98#endif
99 skipBytes(numBytesLeft);
100 }
101}
102
103
104//########## PIDState_PAT implementation ##########
105
106PIDState_PAT::PIDState_PAT(MPEG2TransportStreamParser& parser, u_int16_t pid)
107 : PIDState(parser, pid, PAT) {
108}
109
110PIDState_PAT::~PIDState_PAT() {
111}
112