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
24::parsePMT(PIDState_PMT* pidState, Boolean pusi, unsigned numDataBytes) {
25#ifdef DEBUG_CONTENTS
26 fprintf(stderr, "\tProgram Map Table\n");
27#endif
28 unsigned startPos = curOffset();
29
30 do {
31 if (pusi) {
32 u_int8_t pointer_field = get1Byte();
33 skipBytes(pointer_field); // usually 0
34 }
35
36 u_int8_t table_id = get1Byte();
37 if (table_id != 0x02) {
38#ifdef DEBUG_ERRORS
39 fprintf(stderr, "MPEG2TransportStreamParser::parsePMT(0x%04x, %d, %d): bad table_id: 0x%02x\n",
40 pidState->PID, pusi, numDataBytes, table_id);
41#endif
42 break;
43 }
44
45 u_int16_t flagsPlusSection_length = get2Bytes();
46 u_int16_t section_length = flagsPlusSection_length&0x0FFF;
47#ifdef DEBUG_CONTENTS
48 fprintf(stderr, "\t\tsection_length: %d\n", section_length);
49#endif
50 if (section_length < 13/*too small for remaining fields + CRC*/ ||
51 section_length > 1021/*as per specification*/) {
52#ifdef DEBUG_ERRORS
53 fprintf(stderr, "MPEG2TransportStreamParser::parsePMT(0x%04x, %d, %d): Bad section_length: %d\n",
54 pidState->PID, pusi, numDataBytes, section_length);
55#endif
56 break;
57 }
58 unsigned endPos = curOffset() + section_length;
59 if (endPos - startPos > numDataBytes) {
60#ifdef DEBUG_ERRORS
61 fprintf(stderr, "MPEG2TransportStreamParser::parsePMT(0x%04x, %d, %d): section_length %d gives us a total size %d that's too large!\n",
62 pidState->PID, pusi, numDataBytes, section_length, endPos - startPos);
63#endif
64 break;
65 }
66
67 u_int16_t program_number = get2Bytes();
68 if (program_number != pidState->program_number) {
69#ifdef DEBUG_ERRORS
70 fprintf(stderr, "MPEG2TransportStreamParser::parsePMT(0x%04x, %d, %d): program_number %d does not match the value %d that was given to us in the PAT!\n",
71 pidState->PID, pusi, numDataBytes, program_number, pidState->program_number);
72#endif
73 break;
74 }
75#ifdef DEBUG_CONTENTS
76 fprintf(stderr, "\t\tprogram_number: %d\n", program_number);
77
78 u_int8_t version_number_byte = get1Byte();
79 u_int8_t version_number = (version_number_byte&0x1E)>>1;
80 u_int8_t section_number = get1Byte();
81 u_int8_t last_section_number = get1Byte();
82 fprintf(stderr, "\t\tversion_number: %d; section_number: %d; last_section_number: %d\n",
83 version_number, section_number, last_section_number);
84 u_int16_t PCR_PID = get2Bytes(); PCR_PID &= 0x1FFF;
85 fprintf(stderr, "\t\tPCR_PID: 0x%04x\n", PCR_PID);
86#else
87 skipBytes(5);
88#endif
89
90 u_int16_t program_info_length = get2Bytes(); program_info_length &= 0x0FFF;
91#ifdef DEBUG_CONTENTS
92 fprintf(stderr, "\t\tprogram_info_length: %d\n", program_info_length);
93#endif
94 unsigned endOfDescriptors = curOffset() + program_info_length;
95 if (endOfDescriptors + 4/*CRC*/ - startPos > numDataBytes) {
96#ifdef DEBUG_ERRORS
97 fprintf(stderr, "MPEG2TransportStreamParser::parsePMT(0x%04x, %d, %d): program_info_length %d gives us a total size %d that's too large!\n",
98 pidState->PID, pusi, numDataBytes, program_info_length, endOfDescriptors + 4 - startPos);
99#endif
100 break;
101 }
102 parseStreamDescriptors(program_info_length);
103
104 while (curOffset() <= endPos - 4/*for CRC*/ - 5/*for mapping fields*/) {
105 u_int8_t stream_type = get1Byte();
106 u_int16_t elementary_PID = get2Bytes(); elementary_PID &= 0x1FFF;
107 u_int16_t ES_info_length = get2Bytes(); ES_info_length &= 0x0FFF;
108#ifdef DEBUG_CONTENTS
109 extern StreamType StreamTypes[];
110 char const* const streamTypeDesc = StreamTypes[stream_type].description;
111 fprintf(stderr, "\t\tstream_type: 0x%02x (%s); elementary_PID: 0x%04x; ES_info_length: %d\n",
112 stream_type, streamTypeDesc == NULL ? "???" : streamTypeDesc, elementary_PID, ES_info_length);
113#endif
114 endOfDescriptors = curOffset() + ES_info_length;
115 if (endOfDescriptors + 4/*CRC*/ - startPos > numDataBytes) {
116#ifdef DEBUG_ERRORS
117 fprintf(stderr, "MPEG2TransportStreamParser::parsePMT(0x%04x, %d, %d): ES_info_length %d gives us a total size %d that's too large!\n",
118 pidState->PID, pusi, numDataBytes, ES_info_length, endOfDescriptors + 4 - startPos);
119#endif
120 break;
121 }
122 parseStreamDescriptors(ES_info_length);
123
124 if (fPIDState[elementary_PID] == NULL) {
125 fPIDState[elementary_PID]
126 = new PIDState_STREAM(*this, elementary_PID, program_number, stream_type);
127 }
128 }
129 } while (0);
130
131 // Skip (ignore) all remaining bytes in this packet (including the CRC):
132 int numBytesLeft = numDataBytes - (curOffset() - startPos);
133 if (numBytesLeft > 0) {
134#ifdef DEBUG_CONTENTS
135 fprintf(stderr, "\t\t+%d CRC and stuffing bytes\n", numBytesLeft);
136#endif
137 skipBytes(numBytesLeft);
138 }
139}
140
141#ifdef DEBUG_CONTENTS
142#define pDesc(str) do { fprintf(stderr, "\t\t\tdescriptor_tag: 0x%02x (%s); descriptor_length: %d\n",descriptor_tag, (str), descriptor_length); } while (0)
143#else
144#define pDesc(str)
145#endif
146
147void MPEG2TransportStreamParser::parseStreamDescriptors(unsigned numDescriptorBytes) {
148 while (numDescriptorBytes >= 2/* enough for "descriptor_tag" and "descriptor_length" */) {
149 u_int8_t descriptor_tag = get1Byte();
150 u_int8_t descriptor_length = get1Byte();
151 numDescriptorBytes -= 2;
152
153 if (descriptor_length > numDescriptorBytes) {
154#ifdef DEBUG_ERRORS
155 fprintf(stderr, "MPEG2TransportStreamParser::parseStreamDescriptors() error: Saw descriptor_length %d > remaining bytes %d\n",
156 descriptor_length, numDescriptorBytes);
157#endif
158 skipBytes(numDescriptorBytes); numDescriptorBytes = 0;
159 break;
160 }
161
162 Boolean parsedDescriptor = False;
163 switch (descriptor_tag) {
164 // Note: These are the tags that we've seen to date. Add more when we see more.
165 case 0x02: {
166 pDesc("video");
167 if (descriptor_length < 1) break;
168 u_int8_t flags = get1Byte();
169 Boolean MPEG_1_only_flag = (flags&0x04) != 0;
170#ifdef DEBUG_CONTENTS
171 fprintf(stderr, "\t\t\t\tflags: 0x%02x (frame_rate_code 0x%1x; MPEG_1_only_flag %d)\n",
172 flags, (flags&0x78)>>3, MPEG_1_only_flag);
173#endif
174 if (MPEG_1_only_flag == 0) {
175 if (descriptor_length < 3) break;
176#ifdef DEBUG_CONTENTS
177 u_int8_t profile_and_level_indication = get1Byte();
178 flags = get1Byte();
179 fprintf(stderr, "\t\t\t\tprofile_and_level_indication 0x%02x; flags 0x%02x (chroma_format 0x%1x)\n",
180 profile_and_level_indication, flags, (flags&0xC0)>>6);
181#else
182 skipBytes(2);
183#endif
184 }
185 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
186 break;
187 }
188 case 0x03: {
189 pDesc("audio");
190 if (descriptor_length < 1) break;
191#ifdef DEBUG_CONTENTS
192 u_int8_t flags = get1Byte();
193 fprintf(stderr, "\t\t\t\tflags: 0x%02x (layer %d)\n", flags, (flags&0x30)>>4);
194#else
195 skipBytes(1);
196#endif
197 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
198 break;
199 }
200 case 0x05: {
201 pDesc("registration");
202 if (descriptor_length < 4) break;
203#ifdef DEBUG_CONTENTS
204 u_int32_t format_identifier = get4Bytes();
205 fprintf(stderr, "\t\t\t\tformat_identifier: 0x%08x (%c%c%c%c)\n",
206 format_identifier,
207 format_identifier>>24, format_identifier>>16, format_identifier>>8, format_identifier);
208 if (descriptor_length > 4) {
209 fprintf(stderr, "\t\t\t\tadditional_identification_info: ");
210 for (unsigned i = 4; i < descriptor_length; ++i) fprintf(stderr, "%02x:", get1Byte());
211 fprintf(stderr, "\n");
212 }
213#else
214 skipBytes(descriptor_length);
215#endif
216 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
217 break;
218 }
219 case 0x06: {
220 pDesc("data stream alignment");
221 if (descriptor_length < 1) break;
222#ifdef DEBUG_CONTENTS
223 u_int8_t alignment_type = get1Byte();
224 fprintf(stderr, "\t\t\t\talignment_type: 0x%02x\n", alignment_type);
225#else
226 skipBytes(1);
227#endif
228 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
229 break;
230 }
231 case 0x0a: {
232 pDesc("ISO 639 language descriptor");
233 for (unsigned i = 0; i < descriptor_length/4; ++i) {
234#ifdef DEBUG_CONTENTS
235 fprintf(stderr, "\t\t\t\tISO_639_language_code: %c%c%c; audio_type: 0x%02x\n",
236 get1Byte(), get1Byte(), get1Byte(), get1Byte());
237#else
238 skipBytes(4);
239#endif
240 }
241 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
242 break;
243 }
244 case 0x0b: {
245 pDesc("system clock");
246 if (descriptor_length < 2) break;
247#ifdef DEBUG_CONTENTS
248 u_int8_t flags = get1Byte();
249 Boolean external_clock_ref = (flags&0x80) != 0;
250 u_int8_t clock_accuracy_integer = flags&0x3F;
251
252 u_int8_t clock_accuracy_exponent = get1Byte(); clock_accuracy_exponent >>= 5;
253 float ppm = clock_accuracy_integer*1.0;
254 for (unsigned i = 0; i < clock_accuracy_exponent; ++i) ppm /= 10.0;
255 fprintf(stderr, "\t\t\t\texternal_clock: %d; clock_accuracy int: %d, exp: %d -> %f ppm\n",
256 external_clock_ref, clock_accuracy_integer, clock_accuracy_exponent, ppm);
257#else
258 skipBytes(2);
259#endif
260 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
261 break;
262 }
263 case 0x0e: {
264 pDesc("maximum bitrate");
265 if (descriptor_length < 3) break;
266#ifdef DEBUG_CONTENTS
267 u_int32_t maximum_bitrate = ((get1Byte()&0x3F)<<16)|get2Bytes(); // 22 bits
268 fprintf(stderr, "\t\t\t\tmaximum_bitrate: %d => %f Mbps\n",
269 maximum_bitrate, (maximum_bitrate*50*8)/1000000.0);
270#else
271 skipBytes(3);
272#endif
273 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
274 break;
275 }
276 case 0x10: {
277 pDesc("smoothing buffer");
278 if (descriptor_length < 6) break;
279#ifdef DEBUG_CONTENTS
280 u_int32_t sb_leak_rate = ((get1Byte()&0x3F)<<16)|get2Bytes(); // 22 bits
281 u_int32_t sb_size = ((get1Byte()&0x3F)<<16)|get2Bytes(); // 22 bits
282 fprintf(stderr, "\t\t\t\tsb_leak_rate: %d => %f Mbps; sb_size: %d bytes\n",
283 sb_leak_rate, (sb_leak_rate*400)/1000000.0, sb_size);
284#else
285 skipBytes(6);
286#endif
287 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
288 break;
289 }
290 case 0x1d: {
291 pDesc("IOD parameters for ISO/IEC 14496-1");
292 // Note: We don't know how to parse this. (Where's a document that describes this?)
293 skipBytes(descriptor_length); numDescriptorBytes -= descriptor_length;
294 parsedDescriptor = True;
295 break;
296 }
297 case 0x28: {
298 pDesc("H.264 video parameters");
299 if (descriptor_length < 4) break;
300#ifdef DEBUG_CONTENTS
301 u_int8_t profile_idc = get1Byte();
302 u_int8_t flags1 = get1Byte();
303 u_int8_t level_idc = get1Byte();
304 u_int8_t flags2 = get1Byte();
305 fprintf(stderr, "\t\t\t\tprofile_idc: 0x%02x, flags1: 0x%02x, level_idc: 0x%02x, flags2: 0x%02x\n",
306 profile_idc, flags1, level_idc, flags2);
307#else
308 skipBytes(4);
309#endif
310 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
311 break;
312 }
313 case 0x52: {
314 pDesc("stream identifier");
315 if (descriptor_length < 1) break;
316#ifdef DEBUG_CONTENTS
317 u_int8_t component_tag = get1Byte();
318 fprintf(stderr, "\t\t\t\tcomponent_tag: %d\n", component_tag);
319#else
320 skipBytes(1);
321#endif
322 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
323 break;
324 }
325 case 0x56: {
326 pDesc("teletext");
327 for (unsigned i = 0; i < descriptor_length/5; ++i) {
328#ifdef DEBUG_CONTENTS
329 fprintf(stderr, "\t\t\t\tISO_639_language_code: %c%c%c",
330 get1Byte(), get1Byte(), get1Byte());
331 u_int8_t typePlusMagazine = get1Byte();
332 fprintf(stderr, "; type: 0x%02x; magazine: %d; page: %d\n",
333 typePlusMagazine>>3, typePlusMagazine&0x07, get1Byte());
334#else
335 skipBytes(5);
336#endif
337 }
338 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
339 break;
340 }
341 case 0x59: {
342 pDesc("subtitling");
343 for (unsigned i = 0; i < descriptor_length/8; ++i) {
344#ifdef DEBUG_CONTENTS
345 fprintf(stderr, "\t\t\t\tISO_639_language_code: %c%c%c",
346 get1Byte(), get1Byte(), get1Byte());
347 fprintf(stderr, "; subtitling_type: 0x%02x; composition_page_id: 0x%04x; ancillary_page_id: 0x%04x\n",
348 get1Byte(), get2Bytes(), get2Bytes());
349#else
350 skipBytes(8);
351#endif
352 }
353 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
354 break;
355 }
356 case 0x6f: {
357 pDesc("application signalling");
358 for (unsigned i = 0; i < descriptor_length/3; ++i) {
359#ifdef DEBUG_CONTENTS
360 fprintf(stderr, "\t\t\t\tapplication_type: 0x%04x; AIT_version_number: %d\n",
361 get2Bytes()&0x7FFF, get1Byte()&0x1F);
362#else
363 skipBytes(3);
364#endif
365 }
366 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
367 break;
368 }
369 case 0x7a: {
370 pDesc("enhanced AC-3");
371 if (descriptor_length < 1) break;
372#ifdef DEBUG_CONTENTS
373 u_int8_t flags = get1Byte();
374 fprintf(stderr, "\t\t\t\tflags: 0x%02x", flags);
375 if (descriptor_length > 1) {
376 fprintf(stderr, "; extra bytes: ");
377 for (unsigned i = 1; i < descriptor_length; ++i) fprintf(stderr, "0x%02x ", get1Byte());
378 }
379 fprintf(stderr, "\n");
380#else
381 skipBytes(descriptor_length);
382#endif
383 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
384 break;
385 }
386 case 0x81: {
387 pDesc("AC-3 audio");
388 if (descriptor_length < 3) break;
389#ifdef DEBUG_CONTENTS
390 u_int8_t flags = get1Byte();
391 fprintf(stderr, "\t\t\t\tsample_rate_code: %d; bsid: 0x%02x",
392 flags>>5, flags&0x1F);
393 flags = get1Byte();
394 fprintf(stderr, "; bit_rate_code: %d; surround_mode: %d",
395 flags>>2, flags&0x03);
396 flags = get1Byte();
397 fprintf(stderr, "; bsmod: %d; num_channels: %d; full_svc: %d",
398 flags>>5, (flags&0x1E)>>1, (flags&0x01));
399 if (descriptor_length > 3) {
400 fprintf(stderr, "; extra bytes: ");
401 for (unsigned i = 3; i < descriptor_length; ++i) fprintf(stderr, "0x%02x ", get1Byte());
402 }
403 fprintf(stderr, "\n");
404#else
405 skipBytes(descriptor_length);
406#endif
407 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
408 break;
409 }
410 case 0x86: {
411 pDesc("caption service");
412 if (descriptor_length < 1) break;
413 u_int8_t number_of_services = get1Byte()&0x1F;
414#ifdef DEBUG_CONTENTS
415 fprintf(stderr, "\t\t\t\tnumber_of_services: %d\n", number_of_services);
416#endif
417 if (descriptor_length < number_of_services*6) break;
418#ifdef DEBUG_CONTENTS
419 for (unsigned i = 0; i < number_of_services; ++i) {
420 fprintf(stderr, "\t\t\t\t\tlanguage: %c%c%c", get1Byte(), get1Byte(), get1Byte());
421
422 u_int8_t flags = get1Byte();
423 Boolean digital_cc = (flags&0x80) != 0;
424 fprintf(stderr, "; digital_cc %d", digital_cc);
425 if (digital_cc == 0) {
426 fprintf(stderr, "; line21_field: %d", flags&0x01);
427 } else {
428 fprintf(stderr, "; caption_service_number: %d", flags&0x3F);
429 }
430
431 u_int16_t flags2 = get2Bytes();
432 fprintf(stderr, "; easy_reader: %d; wide_aspect_ratio: %d\n",
433 (flags2&0x8000) != 0, (flags2&0x4000) != 0);
434 }
435#else
436 skipBytes(number_of_services*6);
437#endif
438 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
439 break;
440 }
441 default: {
442 pDesc("???");
443 skipBytes(descriptor_length);
444 numDescriptorBytes -= descriptor_length; parsedDescriptor = True;
445 break;
446 }
447 }
448 if (!parsedDescriptor) break; // an error occurred
449 }
450
451 // Skip over any remaining descriptor bytes (as a result of a parsing error):
452 if (numDescriptorBytes > 0) {
453#ifdef DEBUG_ERRORS
454 fprintf(stderr, "MPEG2TransportStreamParser::parseStreamDescriptors() Parsing error left %d bytes unparsed\n",
455 numDescriptorBytes);
456#endif
457 skipBytes(numDescriptorBytes);
458 }
459}
460
461
462//########## PIDState_PMT implementation ##########
463
464PIDState_PMT
465::PIDState_PMT(MPEG2TransportStreamParser& parser, u_int16_t pid, u_int16_t programNumber)
466 : PIDState(parser, pid, PMT),
467 program_number(programNumber) {
468}
469
470PIDState_PMT::~PIDState_PMT() {
471}
472