Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2005-2020
6 : *
7 : * This file is part of GPAC / MPEG2-TS sub-project
8 : *
9 : * GPAC is free software; you can redistribute it and/or modify
10 : * it under the terms of the GNU Lesser General Public License as published by
11 : * the Free Software Foundation; either version 2, or (at your option)
12 : * any later version.
13 : *
14 : * GPAC is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU Lesser General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public
20 : * License along with this library; see the file COPYING. If not, write to
21 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 : *
23 : */
24 :
25 : #include <gpac/mpegts.h>
26 :
27 :
28 : #ifndef GPAC_DISABLE_MPEG2TS
29 :
30 : #include <string.h>
31 : #include <gpac/constants.h>
32 : #include <gpac/internal/media_dev.h>
33 : #include <gpac/download.h>
34 :
35 :
36 : #ifndef GPAC_DISABLE_STREAMING
37 : #include <gpac/internal/ietf_dev.h>
38 : #endif
39 :
40 :
41 : #ifdef GPAC_CONFIG_LINUX
42 : #include <unistd.h>
43 : #endif
44 :
45 : #ifdef GPAC_ENABLE_MPE
46 : #include <gpac/dvb_mpe.h>
47 : #endif
48 :
49 : #ifdef GPAC_ENABLE_DSMCC
50 : #include <gpac/ait.h>
51 : #endif
52 :
53 : #define DEBUG_TS_PACKET 0
54 :
55 : GF_EXPORT
56 1 : const char *gf_m2ts_get_stream_name(u32 streamType)
57 : {
58 1 : switch (streamType) {
59 : case GF_M2TS_VIDEO_MPEG1:
60 : return "MPEG-1 Video";
61 0 : case GF_M2TS_VIDEO_MPEG2:
62 0 : return "MPEG-2 Video";
63 0 : case GF_M2TS_AUDIO_MPEG1:
64 0 : return "MPEG-1 Audio";
65 0 : case GF_M2TS_AUDIO_MPEG2:
66 0 : return "MPEG-2 Audio";
67 0 : case GF_M2TS_PRIVATE_SECTION:
68 0 : return "Private Section";
69 0 : case GF_M2TS_PRIVATE_DATA:
70 0 : return "Private Data";
71 0 : case GF_M2TS_AUDIO_AAC:
72 0 : return "AAC Audio";
73 0 : case GF_M2TS_VIDEO_MPEG4:
74 0 : return "MPEG-4 Video";
75 0 : case GF_M2TS_VIDEO_H264:
76 0 : return "MPEG-4/H264 Video";
77 0 : case GF_M2TS_VIDEO_SVC:
78 0 : return "H264-SVC Video";
79 0 : case GF_M2TS_VIDEO_HEVC:
80 0 : return "HEVC Video";
81 1 : case GF_M2TS_VIDEO_SHVC:
82 1 : return "SHVC Video";
83 0 : case GF_M2TS_VIDEO_SHVC_TEMPORAL:
84 0 : return "SHVC Video Temporal Sublayer";
85 0 : case GF_M2TS_VIDEO_MHVC:
86 0 : return "MHVC Video";
87 0 : case GF_M2TS_VIDEO_MHVC_TEMPORAL:
88 0 : return "MHVC Video Temporal Sublayer";
89 0 : case GF_M2TS_VIDEO_VVC:
90 0 : return "VVC Video";
91 0 : case GF_M2TS_VIDEO_VVC_TEMPORAL:
92 0 : return "VVC Video Temporal Sublayer";
93 0 : case GF_M2TS_VIDEO_VC1:
94 0 : return "SMPTE VC-1 Video";
95 0 : case GF_M2TS_AUDIO_AC3:
96 0 : return "Dolby AC3 Audio";
97 0 : case GF_M2TS_AUDIO_EC3:
98 0 : return "Dolby E-AC3 Audio";
99 0 : case GF_M2TS_AUDIO_DTS:
100 0 : return "Dolby DTS Audio";
101 0 : case GF_M2TS_SUBTITLE_DVB:
102 0 : return "DVB Subtitle";
103 0 : case GF_M2TS_SYSTEMS_MPEG4_PES:
104 0 : return "MPEG-4 SL (PES)";
105 0 : case GF_M2TS_SYSTEMS_MPEG4_SECTIONS:
106 0 : return "MPEG-4 SL (Section)";
107 0 : case GF_M2TS_MPE_SECTIONS:
108 0 : return "MPE (Section)";
109 :
110 0 : case GF_M2TS_METADATA_PES:
111 0 : return "Metadata (PES)";
112 0 : case GF_M2TS_METADATA_ID3_HLS:
113 0 : return "ID3/HLS Metadata (PES)";
114 :
115 0 : default:
116 0 : return "Unknown";
117 : }
118 : }
119 :
120 :
121 21571 : static u32 gf_m2ts_reframe_default(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, Bool same_pts, unsigned char *data, u32 data_len, GF_M2TS_PESHeader *pes_hdr)
122 : {
123 : GF_M2TS_PES_PCK pck;
124 21571 : pck.flags = 0;
125 21571 : if (pes->rap) pck.flags |= GF_M2TS_PES_PCK_RAP;
126 21571 : if (!same_pts) pck.flags |= GF_M2TS_PES_PCK_AU_START;
127 21571 : pck.DTS = pes->DTS;
128 21571 : pck.PTS = pes->PTS;
129 21571 : pck.data = (char *)data;
130 21571 : pck.data_len = data_len;
131 21571 : pck.stream = pes;
132 21571 : ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck);
133 : /*we consumed all data*/
134 21571 : return 0;
135 : }
136 :
137 62 : static u32 gf_m2ts_reframe_reset(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, Bool same_pts, unsigned char *data, u32 data_len, GF_M2TS_PESHeader *pes_hdr)
138 : {
139 62 : if (pes->pck_data) {
140 62 : gf_free(pes->pck_data);
141 62 : pes->pck_data = NULL;
142 : }
143 62 : pes->pck_data_len = pes->pck_alloc_len = 0;
144 62 : if (pes->prev_data) {
145 0 : gf_free(pes->prev_data);
146 0 : pes->prev_data = NULL;
147 : }
148 62 : pes->prev_data_len = 0;
149 62 : pes->pes_len = 0;
150 62 : pes->reframe = NULL;
151 62 : pes->cc = -1;
152 62 : pes->temi_tc_desc_len = 0;
153 62 : return 0;
154 : }
155 :
156 :
157 162 : static void add_text(char **buffer, u32 *size, u32 *pos, char *msg, u32 msg_len)
158 : {
159 162 : if (!msg || !buffer) return;
160 :
161 162 : if (*pos+msg_len>*size) {
162 54 : *size = *pos+msg_len-*size+256;
163 54 : *buffer = (char *)gf_realloc(*buffer, *size);
164 : }
165 162 : if (! *buffer)
166 : return;
167 :
168 162 : memcpy((*buffer)+(*pos), msg, msg_len);
169 162 : (*buffer)[*pos+msg_len] = 0;
170 162 : *pos += msg_len;
171 : }
172 :
173 54 : static GF_Err id3_parse_tag(char *data, u32 length, char **output, u32 *output_size, u32 *output_pos)
174 : {
175 : GF_BitStream *bs;
176 : u32 pos, size;
177 :
178 54 : if ((data[0] != 'I') || (data[1] != 'D') || (data[2] != '3'))
179 : return GF_NOT_SUPPORTED;
180 :
181 54 : bs = gf_bs_new(data, length, GF_BITSTREAM_READ);
182 :
183 54 : gf_bs_skip_bytes(bs, 3);
184 54 : /*u8 major = */gf_bs_read_u8(bs);
185 54 : /*u8 minor = */gf_bs_read_u8(bs);
186 54 : /*u8 unsync = */gf_bs_read_int(bs, 1);
187 54 : /*u8 ext_hdr = */ gf_bs_read_int(bs, 1);
188 54 : gf_bs_read_int(bs, 6);
189 54 : /*size = */gf_id3_read_size(bs);
190 :
191 54 : pos = (u32) gf_bs_get_position(bs);
192 54 : size = length-pos;
193 :
194 162 : while (size && (gf_bs_available(bs)>=10) ) {
195 54 : u32 ftag = gf_bs_read_u32(bs);
196 54 : u32 fsize = gf_id3_read_size(bs);
197 54 : /*u16 fflags = */gf_bs_read_u16(bs);
198 54 : size -= 10;
199 :
200 : //TODO, handle more ID3 tags ?
201 54 : if (ftag==GF_ID3V2_FRAME_TXXX) {
202 54 : u32 tpos = (u32) gf_bs_get_position(bs);
203 54 : char *text = data+tpos;
204 54 : add_text(output, output_size, output_pos, text, fsize);
205 : } else {
206 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] ID3 tag not handled, patch welcome\n", gf_4cc_to_str(ftag) ) );
207 : }
208 54 : gf_bs_skip_bytes(bs, fsize);
209 : }
210 54 : gf_bs_del(bs);
211 54 : return GF_OK;
212 : }
213 :
214 54 : static u32 gf_m2ts_reframe_id3_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, Bool same_pts, unsigned char *data, u32 data_len, GF_M2TS_PESHeader *pes_hdr)
215 : {
216 : char frame_header[256];
217 54 : char *output_text = NULL;
218 54 : u32 output_len = 0;
219 54 : u32 pos = 0;
220 : GF_M2TS_PES_PCK pck;
221 54 : pck.flags = 0;
222 54 : if (pes->rap) pck.flags |= GF_M2TS_PES_PCK_RAP;
223 54 : if (!same_pts) pck.flags |= GF_M2TS_PES_PCK_AU_START;
224 54 : pck.DTS = pes->DTS;
225 54 : pck.PTS = pes->PTS;
226 : sprintf(frame_header, LLU" --> NEXT\n", pes->PTS);
227 54 : add_text(&output_text, &output_len, &pos, frame_header, (u32)strlen(frame_header));
228 54 : id3_parse_tag((char *)data, data_len, &output_text, &output_len, &pos);
229 54 : add_text(&output_text, &output_len, &pos, "\n\n", 2);
230 54 : pck.data = (char *)output_text;
231 54 : pck.data_len = pos;
232 54 : pck.stream = pes;
233 54 : ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck);
234 54 : gf_free(output_text);
235 : /*we consumed all data*/
236 54 : return 0;
237 : }
238 :
239 84223 : static u32 gf_m2ts_sync(GF_M2TS_Demuxer *ts, char *data, u32 size, Bool simple_check)
240 : {
241 : u32 i=0;
242 : /*if first byte is sync assume we're sync*/
243 84223 : if (simple_check && (data[i]==0x47)) return 0;
244 :
245 9498116 : while (i < size) {
246 9498114 : if (i+192 >= size) return size;
247 9495701 : if ((data[i]==0x47) && (data[i+188]==0x47))
248 : break;
249 9495280 : if ((data[i]==0x47) && (data[i+192]==0x47)) {
250 123 : ts->prefix_present = 1;
251 : break;
252 : }
253 9495157 : i++;
254 : }
255 546 : if (i) {
256 544 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] re-sync skipped %d bytes\n", i) );
257 : }
258 : return i;
259 : }
260 :
261 9578 : Bool gf_m2ts_crc32_check(u8 *data, u32 len)
262 : {
263 9578 : u32 crc = gf_crc_32(data, len);
264 9578 : u32 crc_val = GF_4CC((u32) data[len], (u8) data[len+1], (u8) data[len+2], (u8) data[len+3]);
265 9578 : return (crc==crc_val) ? GF_TRUE : GF_FALSE;
266 : }
267 :
268 :
269 18483 : static GF_M2TS_SectionFilter *gf_m2ts_section_filter_new(gf_m2ts_section_callback process_section_callback, Bool process_individual)
270 : {
271 : GF_M2TS_SectionFilter *sec;
272 18483 : GF_SAFEALLOC(sec, GF_M2TS_SectionFilter);
273 18483 : if (!sec) {
274 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] gf_m2ts_section_filter_new : OUT OF MEMORY\n"));
275 : return NULL;
276 : }
277 18483 : sec->cc = -1;
278 18483 : sec->process_section = process_section_callback;
279 18483 : sec->process_individual = process_individual;
280 18483 : return sec;
281 : }
282 :
283 9919 : static void gf_m2ts_reset_sections(GF_List *sections)
284 : {
285 : u32 count;
286 : //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Deleting sections\n"));
287 :
288 9919 : count = gf_list_count(sections);
289 29416 : while (count) {
290 9578 : GF_M2TS_Section *section = gf_list_get(sections, 0);
291 9578 : gf_list_rem(sections, 0);
292 9578 : if (section->data) gf_free(section->data);
293 9578 : gf_free(section);
294 9578 : count--;
295 : }
296 9919 : }
297 :
298 18730 : static void gf_m2ts_section_filter_reset(GF_M2TS_SectionFilter *sf)
299 : {
300 18730 : if (sf->section) {
301 6 : gf_free(sf->section);
302 6 : sf->section = NULL;
303 : }
304 19071 : while (sf->table) {
305 : GF_M2TS_Table *t = sf->table;
306 341 : sf->table = t->next;
307 341 : gf_m2ts_reset_sections(t->sections);
308 341 : gf_list_del(t->sections);
309 341 : gf_free(t);
310 : }
311 18730 : sf->cc = -1;
312 18730 : sf->length = sf->received = 0;
313 18730 : sf->demux_restarted = 1;
314 :
315 18730 : }
316 : static void gf_m2ts_section_filter_del(GF_M2TS_SectionFilter *sf)
317 : {
318 18483 : gf_m2ts_section_filter_reset(sf);
319 18483 : gf_free(sf);
320 : }
321 :
322 :
323 12 : static void gf_m2ts_metadata_descriptor_del(GF_M2TS_MetadataDescriptor *metad)
324 : {
325 12 : if (metad) {
326 12 : if (metad->service_id_record) gf_free(metad->service_id_record);
327 12 : if (metad->decoder_config) gf_free(metad->decoder_config);
328 12 : if (metad->decoder_config_id) gf_free(metad->decoder_config_id);
329 12 : gf_free(metad);
330 : }
331 12 : }
332 :
333 435 : static void gf_m2ts_es_del(GF_M2TS_ES *es, GF_M2TS_Demuxer *ts)
334 : {
335 435 : gf_list_del_item(es->program->streams, es);
336 :
337 435 : if (es->flags & GF_M2TS_ES_IS_SECTION) {
338 : GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
339 147 : if (ses->sec) gf_m2ts_section_filter_del(ses->sec);
340 :
341 : #ifdef GPAC_ENABLE_MPE
342 : if (es->flags & GF_M2TS_ES_IS_MPE)
343 : gf_dvb_mpe_section_del(es);
344 : #endif
345 :
346 288 : } else if (es->pid!=es->program->pmt_pid) {
347 : GF_M2TS_PES *pes = (GF_M2TS_PES *)es;
348 :
349 288 : if ((pes->flags & GF_M2TS_INHERIT_PCR) && ts->ess[es->program->pcr_pid]==es)
350 106 : ts->ess[es->program->pcr_pid] = NULL;
351 :
352 288 : if (pes->pck_data) gf_free(pes->pck_data);
353 288 : if (pes->prev_data) gf_free(pes->prev_data);
354 288 : if (pes->temi_tc_desc) gf_free(pes->temi_tc_desc);
355 :
356 288 : if (pes->metadata_descriptor) gf_m2ts_metadata_descriptor_del(pes->metadata_descriptor);
357 :
358 : }
359 435 : if (es->slcfg) gf_free(es->slcfg);
360 435 : gf_free(es);
361 435 : }
362 :
363 3071 : static void gf_m2ts_reset_sdt(GF_M2TS_Demuxer *ts)
364 : {
365 3101 : while (gf_list_count(ts->SDTs)) {
366 30 : GF_M2TS_SDT *sdt = (GF_M2TS_SDT *)gf_list_last(ts->SDTs);
367 30 : gf_list_rem_last(ts->SDTs);
368 30 : if (sdt->provider) gf_free(sdt->provider);
369 30 : if (sdt->service) gf_free(sdt->service);
370 30 : gf_free(sdt);
371 : }
372 3071 : }
373 :
374 : GF_EXPORT
375 28 : GF_M2TS_SDT *gf_m2ts_get_sdt_info(GF_M2TS_Demuxer *ts, u32 program_id)
376 : {
377 : u32 i;
378 91 : for (i=0; i<gf_list_count(ts->SDTs); i++) {
379 88 : GF_M2TS_SDT *sdt = (GF_M2TS_SDT *)gf_list_get(ts->SDTs, i);
380 88 : if (sdt->service_id==program_id) return sdt;
381 : }
382 : return NULL;
383 : }
384 :
385 10148 : static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *sec, GF_M2TS_SECTION_ES *ses)
386 : {
387 : //seek mode, only process PAT and PMT
388 10148 : if (ts->seek_mode && (sec->section[0] != GF_M2TS_TABLE_ID_PAT) && (sec->section[0] != GF_M2TS_TABLE_ID_PMT)) {
389 : /*clean-up (including broken sections)*/
390 210 : if (sec->section) gf_free(sec->section);
391 210 : sec->section = NULL;
392 210 : sec->length = sec->received = 0;
393 210 : return;
394 : }
395 :
396 9938 : if (!sec->process_section) {
397 360 : if ((ts->on_event && (sec->section[0]==GF_M2TS_TABLE_ID_AIT)) ) {
398 : #ifdef GPAC_ENABLE_DSMCC
399 : GF_M2TS_SL_PCK pck;
400 : pck.data_len = sec->length;
401 : pck.data = sec->section;
402 : pck.stream = (GF_M2TS_ES *)ses;
403 : //ts->on_event(ts, GF_M2TS_EVT_AIT_FOUND, &pck);
404 : on_ait_section(ts, GF_M2TS_EVT_AIT_FOUND, &pck);
405 : #endif
406 720 : } else if ((ts->on_event && (sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA || sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE ||
407 360 : sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_DOWNLOAD_DATA_MESSAGE || sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_STREAM_DESCRIPTION || sec->section[0]==GF_M2TS_TABLE_ID_DSM_CC_PRIVATE)) ) {
408 :
409 : #ifdef GPAC_ENABLE_DSMCC
410 : GF_M2TS_SL_PCK pck;
411 : pck.data_len = sec->length;
412 : pck.data = sec->section;
413 : pck.stream = (GF_M2TS_ES *)ses;
414 : on_dsmcc_section(ts,GF_M2TS_EVT_DSMCC_FOUND,&pck);
415 : //ts->on_event(ts, GF_M2TS_EVT_DSMCC_FOUND, &pck);
416 : #endif
417 : }
418 : #ifdef GPAC_ENABLE_MPE
419 : else if (ts->on_mpe_event && ((ses && (ses->flags & GF_M2TS_EVT_DVB_MPE)) || (sec->section[0]==GF_M2TS_TABLE_ID_INT)) ) {
420 : GF_M2TS_SL_PCK pck;
421 : pck.data_len = sec->length;
422 : pck.data = sec->section;
423 : pck.stream = (GF_M2TS_ES *)ses;
424 : ts->on_mpe_event(ts, GF_M2TS_EVT_DVB_MPE, &pck);
425 : }
426 : #endif
427 345 : else if (ts->on_event) {
428 : GF_M2TS_SL_PCK pck;
429 345 : pck.data_len = sec->length;
430 345 : pck.data = sec->section;
431 345 : pck.stream = (GF_M2TS_ES *)ses;
432 345 : ts->on_event(ts, GF_M2TS_EVT_DVB_GENERAL, &pck);
433 : }
434 : } else {
435 : Bool has_syntax_indicator;
436 : u8 table_id;
437 : u16 extended_table_id;
438 : u32 status, section_start, i;
439 : GF_M2TS_Table *t, *prev_t;
440 : unsigned char *data;
441 : Bool section_valid = 0;
442 :
443 : status = 0;
444 : /*parse header*/
445 9578 : data = (u8 *)sec->section;
446 :
447 9578 : if (sec->length < 2) {
448 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] M2TS Table parsing error, length %d is too small\n", sec->length) );
449 : return;
450 : }
451 :
452 : /*look for proper table*/
453 9578 : table_id = data[0];
454 :
455 9578 : if (ts->on_event) {
456 9398 : switch (table_id) {
457 9106 : case GF_M2TS_TABLE_ID_PAT:
458 : case GF_M2TS_TABLE_ID_SDT_ACTUAL:
459 : case GF_M2TS_TABLE_ID_PMT:
460 : case GF_M2TS_TABLE_ID_NIT_ACTUAL:
461 : case GF_M2TS_TABLE_ID_TDT:
462 : case GF_M2TS_TABLE_ID_TOT:
463 : {
464 : GF_M2TS_SL_PCK pck;
465 9106 : pck.data_len = sec->length;
466 9106 : pck.data = sec->section;
467 9106 : pck.stream = (GF_M2TS_ES *)ses;
468 9106 : ts->on_event(ts, GF_M2TS_EVT_DVB_GENERAL, &pck);
469 : }
470 : }
471 : }
472 :
473 9578 : has_syntax_indicator = (data[1] & 0x80) ? 1 : 0;
474 9578 : if (has_syntax_indicator) {
475 9578 : if (sec->length < 5) {
476 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] M2TS Table parsing error, length %d is too small\n", sec->length) );
477 : return;
478 : }
479 9578 : extended_table_id = (data[3]<<8) | data[4];
480 : } else {
481 : extended_table_id = 0;
482 : }
483 :
484 : prev_t = NULL;
485 9578 : t = sec->table;
486 19156 : while (t) {
487 9237 : if ((t->table_id==table_id) && (t->ex_table_id == extended_table_id)) break;
488 : prev_t = t;
489 0 : t = t->next;
490 : }
491 :
492 : /*create table*/
493 9578 : if (!t) {
494 341 : GF_SAFEALLOC(t, GF_M2TS_Table);
495 341 : if (!t) {
496 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Fail to alloc table %d %d\n", table_id, extended_table_id));
497 : return;
498 : }
499 341 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Creating table %d %d\n", table_id, extended_table_id));
500 341 : t->table_id = table_id;
501 341 : t->ex_table_id = extended_table_id;
502 341 : t->last_version_number = 0xFF;
503 341 : t->sections = gf_list_new();
504 341 : if (prev_t) prev_t->next = t;
505 341 : else sec->table = t;
506 : }
507 :
508 9578 : if (has_syntax_indicator) {
509 9578 : if (sec->length < 4) {
510 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted section length %d less than CRC \n", sec->length));
511 : } else {
512 : /*remove crc32*/
513 9578 : sec->length -= 4;
514 9578 : if (gf_m2ts_crc32_check((char *)data, sec->length)) {
515 : s32 cur_sec_num;
516 9578 : t->version_number = (data[5] >> 1) & 0x1f;
517 9578 : if (t->last_section_number && t->section_number && (t->version_number != t->last_version_number)) {
518 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] table transmission interrupted: previous table (v=%d) %d/%d sections - new table (v=%d) %d/%d sections\n", t->last_version_number, t->section_number, t->last_section_number, t->version_number, data[6] + 1, data[7] + 1) );
519 0 : gf_m2ts_reset_sections(t->sections);
520 0 : t->section_number = 0;
521 : }
522 :
523 9578 : t->current_next_indicator = (data[5] & 0x1) ? 1 : 0;
524 : /*add one to section numbers to detect if we missed or not the first section in the table*/
525 9578 : cur_sec_num = data[6] + 1;
526 9578 : t->last_section_number = data[7] + 1;
527 : section_start = 8;
528 : /*we missed something*/
529 9578 : if (!sec->process_individual && t->section_number + 1 != cur_sec_num) {
530 : /* TODO - Check how to handle sections when the first complete section does
531 : not have its sec num 0 */
532 : section_valid = 0;
533 0 : if (t->is_init) {
534 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted table (lost section %d)\n", cur_sec_num ? cur_sec_num-1 : 31) );
535 : }
536 : } else {
537 : section_valid = 1;
538 9578 : t->section_number = cur_sec_num;
539 : }
540 : } else {
541 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted section (CRC32 failed)\n"));
542 : }
543 : }
544 : } else {
545 : section_valid = 1;
546 : section_start = 3;
547 : }
548 : /*process section*/
549 : if (section_valid) {
550 : GF_M2TS_Section *section;
551 :
552 9578 : GF_SAFEALLOC(section, GF_M2TS_Section);
553 9578 : if (!section) {
554 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Fail to create section\n"));
555 : return;
556 : }
557 9578 : section->data_size = sec->length - section_start;
558 9578 : section->data = (unsigned char*)gf_malloc(sizeof(unsigned char)*section->data_size);
559 9578 : memcpy(section->data, sec->section + section_start, sizeof(unsigned char)*section->data_size);
560 9578 : gf_list_add(t->sections, section);
561 :
562 9578 : if (t->section_number == 1) {
563 : status |= GF_M2TS_TABLE_START;
564 9578 : if (t->last_version_number == t->version_number) {
565 9237 : t->is_repeat = 1;
566 : } else {
567 341 : t->is_repeat = 0;
568 : }
569 : /*only update version number in the first section of the table*/
570 9578 : t->last_version_number = t->version_number;
571 : }
572 :
573 9578 : if (t->is_init) {
574 9237 : if (t->is_repeat) {
575 9237 : status |= GF_M2TS_TABLE_REPEAT;
576 : } else {
577 0 : status |= GF_M2TS_TABLE_UPDATE;
578 : }
579 : } else {
580 341 : status |= GF_M2TS_TABLE_FOUND;
581 : }
582 :
583 9578 : if (t->last_section_number == t->section_number) {
584 : u32 table_size;
585 :
586 9578 : status |= GF_M2TS_TABLE_END;
587 :
588 : table_size = 0;
589 19156 : for (i=0; i<gf_list_count(t->sections); i++) {
590 9578 : GF_M2TS_Section *a_sec = gf_list_get(t->sections, i);
591 9578 : table_size += a_sec->data_size;
592 : }
593 9578 : if (t->is_repeat) {
594 9237 : if (t->table_size != table_size) {
595 0 : status |= GF_M2TS_TABLE_UPDATE;
596 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Repeated section found with different sizes (old table %d bytes, new table %d bytes)\n", t->table_size, table_size) );
597 :
598 0 : t->table_size = table_size;
599 : }
600 : } else {
601 341 : t->table_size = table_size;
602 : }
603 :
604 9578 : t->is_init = 1;
605 : /*reset section number*/
606 9578 : t->section_number = 0;
607 :
608 9578 : t->is_repeat = 0;
609 :
610 : }
611 :
612 9578 : if (sec->process_individual) {
613 : /*send each section of the table and not the aggregated table*/
614 82 : if (sec->process_section)
615 82 : sec->process_section(ts, ses, t->sections, t->table_id, t->ex_table_id, t->version_number, (u8) (t->last_section_number - 1), status);
616 :
617 82 : gf_m2ts_reset_sections(t->sections);
618 : } else {
619 9496 : if (status&GF_M2TS_TABLE_END) {
620 9496 : if (sec->process_section)
621 9496 : sec->process_section(ts, ses, t->sections, t->table_id, t->ex_table_id, t->version_number, (u8) (t->last_section_number - 1), status);
622 :
623 9496 : gf_m2ts_reset_sections(t->sections);
624 : }
625 : }
626 :
627 : } else {
628 0 : sec->cc = -1;
629 0 : t->section_number = 0;
630 : }
631 : }
632 : /*clean-up (including broken sections)*/
633 9938 : if (sec->section) gf_free(sec->section);
634 9938 : sec->section = NULL;
635 9938 : sec->length = sec->received = 0;
636 : }
637 :
638 10154 : static Bool gf_m2ts_is_long_section(u8 table_id)
639 : {
640 10154 : switch (table_id) {
641 : case GF_M2TS_TABLE_ID_MPEG4_BIFS:
642 : case GF_M2TS_TABLE_ID_MPEG4_OD:
643 : case GF_M2TS_TABLE_ID_INT:
644 : case GF_M2TS_TABLE_ID_EIT_ACTUAL_PF:
645 : case GF_M2TS_TABLE_ID_EIT_OTHER_PF:
646 : case GF_M2TS_TABLE_ID_ST:
647 : case GF_M2TS_TABLE_ID_SIT:
648 : case GF_M2TS_TABLE_ID_DSM_CC_PRIVATE:
649 : case GF_M2TS_TABLE_ID_MPE_FEC:
650 : case GF_M2TS_TABLE_ID_DSM_CC_DOWNLOAD_DATA_MESSAGE:
651 : case GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE:
652 : return 1;
653 9666 : default:
654 9666 : if (table_id >= GF_M2TS_TABLE_ID_EIT_SCHEDULE_MIN && table_id <= GF_M2TS_TABLE_ID_EIT_SCHEDULE_MAX)
655 : return 1;
656 : else
657 9666 : return 0;
658 : }
659 : }
660 :
661 10154 : static u32 gf_m2ts_get_section_length(char byte0, char byte1, char byte2)
662 : {
663 : u32 length;
664 10154 : if (gf_m2ts_is_long_section(byte0)) {
665 488 : length = 3 + ( (((u8)byte1<<8) | (byte2&0xff)) & 0xfff );
666 : } else {
667 9666 : length = 3 + ( (((u8)byte1<<8) | (byte2&0xff)) & 0x3ff );
668 : }
669 10154 : return length;
670 : }
671 :
672 10761 : static void gf_m2ts_gather_section(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *sec, GF_M2TS_SECTION_ES *ses, GF_M2TS_Header *hdr, unsigned char *data, u32 data_size)
673 : {
674 : u32 payload_size = data_size;
675 10761 : u8 expect_cc = (sec->cc<0) ? hdr->continuity_counter : (sec->cc + 1) & 0xf;
676 10761 : Bool disc = (expect_cc == hdr->continuity_counter) ? 0 : 1;
677 10761 : sec->cc = expect_cc;
678 :
679 : /*may happen if hdr->adaptation_field=2 no payload in TS packet*/
680 10761 : if (!data_size) return;
681 :
682 10761 : if (hdr->payload_start) {
683 : u32 ptr_field;
684 :
685 10154 : ptr_field = data[0];
686 10154 : if (ptr_field+1>data_size) {
687 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid section start (@ptr_field=%d, @data_size=%d)\n", ptr_field, data_size) );
688 : return;
689 : }
690 :
691 : /*end of previous section*/
692 10154 : if (!sec->length && sec->received) {
693 : /* the length of the section could not be determined from the previous TS packet because we had only 1 or 2 bytes */
694 0 : if (sec->received == 1)
695 0 : sec->length = gf_m2ts_get_section_length(sec->section[0], data[1], data[2]);
696 : else /* (sec->received == 2) */
697 0 : sec->length = gf_m2ts_get_section_length(sec->section[0], sec->section[1], data[1]);
698 0 : sec->section = (char*)gf_realloc(sec->section, sizeof(char)*sec->length);
699 : }
700 :
701 10154 : if (sec->length && sec->received + ptr_field >= sec->length) {
702 0 : u32 len = sec->length - sec->received;
703 0 : memcpy(sec->section + sec->received, data+1, sizeof(char)*len);
704 0 : sec->received += len;
705 0 : if (ptr_field > len)
706 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid pointer field (@ptr_field=%d, @remaining=%d)\n", ptr_field, len) );
707 0 : gf_m2ts_section_complete(ts, sec, ses);
708 : }
709 10154 : data += ptr_field+1;
710 10154 : data_size -= ptr_field+1;
711 : payload_size -= ptr_field+1;
712 :
713 10154 : aggregated_section:
714 :
715 10154 : if (sec->section) gf_free(sec->section);
716 10154 : sec->length = sec->received = 0;
717 10154 : sec->section = (char*)gf_malloc(sizeof(char)*data_size);
718 : memcpy(sec->section, data, sizeof(char)*data_size);
719 10154 : sec->received = data_size;
720 607 : } else if (disc) {
721 0 : if (sec->section) gf_free(sec->section);
722 0 : sec->section = NULL;
723 0 : sec->received = sec->length = 0;
724 : return;
725 607 : } else if (!sec->section) {
726 : return;
727 : } else {
728 547 : if (sec->length && sec->received+data_size > sec->length)
729 118 : data_size = sec->length - sec->received;
730 :
731 547 : if (sec->length) {
732 547 : memcpy(sec->section + sec->received, data, sizeof(char)*data_size);
733 : } else {
734 0 : sec->section = (char*)gf_realloc(sec->section, sizeof(char)*(sec->received+data_size));
735 0 : memcpy(sec->section + sec->received, data, sizeof(char)*data_size);
736 : }
737 547 : sec->received += data_size;
738 : }
739 : /*alloc final buffer*/
740 10701 : if (!sec->length && (sec->received >= 3)) {
741 10154 : sec->length = gf_m2ts_get_section_length(sec->section[0], sec->section[1], sec->section[2]);
742 10154 : sec->section = (char*)gf_realloc(sec->section, sizeof(char)*sec->length);
743 :
744 10154 : if (sec->received > sec->length) {
745 10030 : data_size -= sec->received - sec->length;
746 10030 : sec->received = sec->length;
747 : }
748 : }
749 10701 : if (!sec->length || sec->received < sec->length) return;
750 :
751 : /*OK done*/
752 10148 : gf_m2ts_section_complete(ts, sec, ses);
753 :
754 10148 : if (payload_size > data_size) {
755 10148 : data += data_size;
756 : /* detect padding after previous section */
757 10148 : if (data[0] != 0xFF) {
758 0 : data_size = payload_size - data_size;
759 : payload_size = data_size;
760 : goto aggregated_section;
761 : }
762 : }
763 : }
764 :
765 82 : static void gf_m2ts_process_sdt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
766 : {
767 : u32 pos, evt_type;
768 : u32 nb_sections;
769 : u32 data_size;
770 : unsigned char *data;
771 : GF_M2TS_Section *section;
772 :
773 : /*wait for the last section */
774 82 : if (!(status&GF_M2TS_TABLE_END)) return;
775 :
776 : /*skip if already received*/
777 82 : if (status&GF_M2TS_TABLE_REPEAT) {
778 67 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SDT_REPEAT, NULL);
779 : return;
780 : }
781 :
782 15 : if (table_id != GF_M2TS_TABLE_ID_SDT_ACTUAL) {
783 : return;
784 : }
785 :
786 15 : gf_m2ts_reset_sdt(ts);
787 :
788 15 : nb_sections = gf_list_count(sections);
789 15 : if (nb_sections > 1) {
790 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] SDT on multiple sections not supported\n"));
791 : }
792 :
793 15 : section = (GF_M2TS_Section *)gf_list_get(sections, 0);
794 15 : data = section->data;
795 15 : data_size = section->data_size;
796 :
797 : //orig_net_id = (data[0] << 8) | data[1];
798 : pos = 3;
799 60 : while (pos < data_size) {
800 : GF_M2TS_SDT *sdt;
801 : u32 descs_size, d_pos, ulen;
802 :
803 30 : GF_SAFEALLOC(sdt, GF_M2TS_SDT);
804 30 : if (!sdt) {
805 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Fail to create SDT\n"));
806 : return;
807 : }
808 30 : gf_list_add(ts->SDTs, sdt);
809 :
810 30 : sdt->service_id = (data[pos]<<8) + data[pos+1];
811 30 : sdt->EIT_schedule = (data[pos+2] & 0x2) ? 1 : 0;
812 30 : sdt->EIT_present_following = (data[pos+2] & 0x1);
813 30 : sdt->running_status = (data[pos+3]>>5) & 0x7;
814 30 : sdt->free_CA_mode = (data[pos+3]>>4) & 0x1;
815 30 : descs_size = ((data[pos+3]&0xf)<<8) | data[pos+4];
816 30 : pos += 5;
817 :
818 : d_pos = 0;
819 90 : while (d_pos < descs_size) {
820 30 : u8 d_tag = data[pos+d_pos];
821 30 : u8 d_len = data[pos+d_pos+1];
822 :
823 30 : switch (d_tag) {
824 30 : case GF_M2TS_DVB_SERVICE_DESCRIPTOR:
825 30 : if (sdt->provider) gf_free(sdt->provider);
826 30 : sdt->provider = NULL;
827 30 : if (sdt->service) gf_free(sdt->service);
828 30 : sdt->service = NULL;
829 :
830 30 : d_pos+=2;
831 30 : sdt->service_type = data[pos+d_pos];
832 30 : ulen = data[pos+d_pos+1];
833 30 : d_pos += 2;
834 30 : sdt->provider = (char*)gf_malloc(sizeof(char)*(ulen+1));
835 30 : memcpy(sdt->provider, data+pos+d_pos, sizeof(char)*ulen);
836 30 : sdt->provider[ulen] = 0;
837 30 : d_pos += ulen;
838 :
839 30 : ulen = data[pos+d_pos];
840 30 : d_pos += 1;
841 30 : sdt->service = (char*)gf_malloc(sizeof(char)*(ulen+1));
842 30 : memcpy(sdt->service, data+pos+d_pos, sizeof(char)*ulen);
843 30 : sdt->service[ulen] = 0;
844 30 : d_pos += ulen;
845 30 : break;
846 :
847 0 : default:
848 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Skipping descriptor (0x%x) not supported\n", d_tag));
849 0 : d_pos += d_len;
850 0 : if (d_len == 0) d_pos = descs_size;
851 : break;
852 : }
853 : }
854 30 : pos += descs_size;
855 : }
856 : evt_type = GF_M2TS_EVT_SDT_FOUND;
857 15 : if (ts->on_event) ts->on_event(ts, evt_type, NULL);
858 : }
859 :
860 6 : static void gf_m2ts_process_mpeg4section(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
861 : {
862 : GF_M2TS_SL_PCK sl_pck;
863 : u32 nb_sections, i;
864 : GF_M2TS_Section *section;
865 :
866 : /*skip if already received*/
867 6 : if (status & GF_M2TS_TABLE_REPEAT)
868 0 : if (!(es->flags & GF_M2TS_ES_SEND_REPEATED_SECTIONS))
869 0 : return;
870 :
871 6 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Sections for PID %d\n", es->pid) );
872 : /*send all sections (eg SL-packets)*/
873 6 : nb_sections = gf_list_count(sections);
874 12 : for (i=0; i<nb_sections; i++) {
875 6 : section = (GF_M2TS_Section *)gf_list_get(sections, i);
876 6 : sl_pck.data = (char *)section->data;
877 6 : sl_pck.data_len = section->data_size;
878 6 : sl_pck.stream = (GF_M2TS_ES *)es;
879 6 : sl_pck.version_number = version_number;
880 6 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SL_PCK, &sl_pck);
881 : }
882 : }
883 :
884 21 : static void gf_m2ts_process_nit(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *nit_es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
885 : {
886 21 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] NIT table processing (not yet implemented)"));
887 21 : }
888 :
889 :
890 :
891 :
892 0 : static void gf_m2ts_process_tdt_tot(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *tdt_tot_es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
893 : {
894 : unsigned char *data;
895 : u32 data_size, nb_sections;
896 : u32 date, yp, mp, k;
897 : GF_M2TS_Section *section;
898 : GF_M2TS_TDT_TOT *time_table;
899 : const char *table_name;
900 :
901 : /*wait for the last section */
902 0 : if ( !(status & GF_M2TS_TABLE_END) )
903 : return;
904 :
905 0 : switch (table_id) {
906 : case GF_M2TS_TABLE_ID_TDT:
907 : table_name = "TDT";
908 : break;
909 0 : case GF_M2TS_TABLE_ID_TOT:
910 : table_name = "TOT";
911 0 : break;
912 0 : default:
913 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Unimplemented table_id %u for PID %u\n", table_id, GF_M2TS_PID_TDT_TOT_ST));
914 : return;
915 : }
916 :
917 0 : nb_sections = gf_list_count(sections);
918 0 : if (nb_sections > 1) {
919 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] %s on multiple sections not supported\n", table_name));
920 : }
921 :
922 0 : section = (GF_M2TS_Section *)gf_list_get(sections, 0);
923 0 : data = section->data;
924 0 : data_size = section->data_size;
925 :
926 : /*TOT only contains 40 bits of UTC_time; TDT add descriptors and a CRC*/
927 0 : if ((table_id==GF_M2TS_TABLE_ID_TDT) && (data_size != 5)) {
928 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Corrupted TDT size\n", table_name));
929 : }
930 0 : GF_SAFEALLOC(time_table, GF_M2TS_TDT_TOT);
931 0 : if (!time_table) {
932 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Fail to alloc DVB time table\n"));
933 : return;
934 : }
935 :
936 : /*UTC_time - see annex C of DVB-SI ETSI EN 300468*/
937 : /* decodes an Modified Julian Date (MJD) into a Co-ordinated Universal Time (UTC)
938 : See annex C of DVB-SI ETSI EN 300468 */
939 0 : date = data[0]*256 + data[1];
940 0 : yp = (u32)((date - 15078.2)/365.25);
941 0 : mp = (u32)((date - 14956.1 - (u32)(yp * 365.25))/30.6001);
942 0 : time_table->day = (u32)(date - 14956 - (u32)(yp * 365.25) - (u32)(mp * 30.6001));
943 0 : if (mp == 14 || mp == 15) k = 1;
944 : else k = 0;
945 0 : time_table->year = yp + k + 1900;
946 0 : time_table->month = mp - 1 - k*12;
947 :
948 0 : time_table->hour = 10*((data[2]&0xf0)>>4) + (data[2]&0x0f);
949 0 : time_table->minute = 10*((data[3]&0xf0)>>4) + (data[3]&0x0f);
950 0 : time_table->second = 10*((data[4]&0xf0)>>4) + (data[4]&0x0f);
951 : assert(time_table->hour<24 && time_table->minute<60 && time_table->second<60);
952 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream UTC time is %u/%02u/%02u %02u:%02u:%02u\n", time_table->year, time_table->month, time_table->day, time_table->hour, time_table->minute, time_table->second));
953 :
954 0 : switch (table_id) {
955 0 : case GF_M2TS_TABLE_ID_TDT:
956 0 : if (ts->TDT_time) gf_free(ts->TDT_time);
957 0 : ts->TDT_time = time_table;
958 0 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TDT, time_table);
959 : break;
960 0 : case GF_M2TS_TABLE_ID_TOT:
961 : #if 0
962 : {
963 : u32 pos, loop_len;
964 : loop_len = ((data[5]&0x0f) << 8) | (data[6] & 0xff);
965 : data += 7;
966 : pos = 0;
967 : while (pos < loop_len) {
968 : u8 tag = data[pos];
969 : pos += 2;
970 : if (tag == GF_M2TS_DVB_LOCAL_TIME_OFFSET_DESCRIPTOR) {
971 : char tmp_time[10];
972 : u16 offset_hours, offset_minutes;
973 : now->country_code[0] = data[pos];
974 : now->country_code[1] = data[pos+1];
975 : now->country_code[2] = data[pos+2];
976 : now->country_region_id = data[pos+3]>>2;
977 :
978 : sprintf(tmp_time, "%02x", data[pos+4]);
979 : offset_hours = atoi(tmp_time);
980 : sprintf(tmp_time, "%02x", data[pos+5]);
981 : offset_minutes = atoi(tmp_time);
982 : now->local_time_offset_seconds = (offset_hours * 60 + offset_minutes) * 60;
983 : if (data[pos+3] & 1) now->local_time_offset_seconds *= -1;
984 :
985 : dvb_decode_mjd_to_unix_time(data+pos+6, &now->unix_next_toc);
986 :
987 : sprintf(tmp_time, "%02x", data[pos+11]);
988 : offset_hours = atoi(tmp_time);
989 : sprintf(tmp_time, "%02x", data[pos+12]);
990 : offset_minutes = atoi(tmp_time);
991 : now->next_time_offset_seconds = (offset_hours * 60 + offset_minutes) * 60;
992 : if (data[pos+3] & 1) now->next_time_offset_seconds *= -1;
993 : pos+= 13;
994 : }
995 : }
996 : /*TODO: check lengths are ok*/
997 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TOT, time_table);
998 : }
999 : #endif
1000 : /*check CRC32*/
1001 0 : if (ts->tdt_tot->length<4) {
1002 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted %s table (less than 4 bytes but CRC32 should be present\n", table_name));
1003 : goto error_exit;
1004 : }
1005 0 : if (!gf_m2ts_crc32_check(ts->tdt_tot->section, ts->tdt_tot->length-4)) {
1006 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted %s table (CRC32 failed)\n", table_name));
1007 : goto error_exit;
1008 : }
1009 0 : if (ts->TDT_time) gf_free(ts->TDT_time);
1010 0 : ts->TDT_time = time_table;
1011 0 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TOT, time_table);
1012 : break;
1013 : default:
1014 : assert(0);
1015 : goto error_exit;
1016 : }
1017 :
1018 : return; /*success*/
1019 :
1020 0 : error_exit:
1021 0 : gf_free(time_table);
1022 0 : return;
1023 : }
1024 :
1025 12 : static GF_M2TS_MetadataPointerDescriptor *gf_m2ts_read_metadata_pointer_descriptor(GF_BitStream *bs, u32 length)
1026 : {
1027 : u32 size;
1028 : GF_M2TS_MetadataPointerDescriptor *d;
1029 12 : GF_SAFEALLOC(d, GF_M2TS_MetadataPointerDescriptor);
1030 12 : if (!d) return NULL;
1031 12 : d->application_format = gf_bs_read_u16(bs);
1032 : size = 2;
1033 12 : if (d->application_format == 0xFFFF) {
1034 12 : d->application_format_identifier = gf_bs_read_u32(bs);
1035 : size += 4;
1036 : }
1037 12 : d->format = gf_bs_read_u8(bs);
1038 12 : size += 1;
1039 12 : if (d->format == 0xFF) {
1040 12 : d->format_identifier = gf_bs_read_u32(bs);
1041 12 : size += 4;
1042 : }
1043 12 : d->service_id = gf_bs_read_u8(bs);
1044 12 : d->locator_record_flag = (gf_bs_read_int(bs, 1) ? GF_TRUE : GF_FALSE);
1045 12 : d->carriage_flag = (enum metadata_carriage)gf_bs_read_int(bs, 2);
1046 12 : gf_bs_read_int(bs, 5); /*reserved */
1047 12 : size += 2;
1048 12 : if (d->locator_record_flag) {
1049 0 : d->locator_length = gf_bs_read_u8(bs);
1050 0 : d->locator_data = (char *)gf_malloc(d->locator_length);
1051 0 : size += 1 + d->locator_length;
1052 0 : gf_bs_read_data(bs, d->locator_data, d->locator_length);
1053 : }
1054 12 : if (d->carriage_flag != 3) {
1055 12 : d->program_number = gf_bs_read_u16(bs);
1056 12 : size += 2;
1057 : }
1058 12 : if (d->carriage_flag == 1) {
1059 0 : d->ts_location = gf_bs_read_u16(bs);
1060 0 : d->ts_id = gf_bs_read_u16(bs);
1061 0 : size += 4;
1062 : }
1063 12 : if (length-size > 0) {
1064 0 : d->data_size = length-size;
1065 0 : d->data = (char *)gf_malloc(d->data_size);
1066 0 : gf_bs_read_data(bs, d->data, d->data_size);
1067 : }
1068 : return d;
1069 : }
1070 :
1071 12 : static void gf_m2ts_metadata_pointer_descriptor_del(GF_M2TS_MetadataPointerDescriptor *metapd)
1072 : {
1073 12 : if (metapd) {
1074 12 : if (metapd->locator_data) gf_free(metapd->locator_data);
1075 12 : if (metapd->data) gf_free(metapd->data);
1076 12 : gf_free(metapd);
1077 : }
1078 12 : }
1079 :
1080 12 : static GF_M2TS_MetadataDescriptor *gf_m2ts_read_metadata_descriptor(GF_BitStream *bs, u32 length)
1081 : {
1082 : //u32 size;
1083 : GF_M2TS_MetadataDescriptor *d;
1084 12 : GF_SAFEALLOC(d, GF_M2TS_MetadataDescriptor);
1085 12 : if (!d) return NULL;
1086 12 : d->application_format = gf_bs_read_u16(bs);
1087 : //size = 2;
1088 12 : if (d->application_format == 0xFFFF) {
1089 12 : d->application_format_identifier = gf_bs_read_u32(bs);
1090 : //size += 4;
1091 : }
1092 12 : d->format = gf_bs_read_u8(bs);
1093 : //size += 1;
1094 12 : if (d->format == 0xFF) {
1095 12 : d->format_identifier = gf_bs_read_u32(bs);
1096 : //size += 4;
1097 : }
1098 12 : d->service_id = gf_bs_read_u8(bs);
1099 12 : d->decoder_config_flags = gf_bs_read_int(bs, 3);
1100 12 : d->dsmcc_flag = (gf_bs_read_int(bs, 1) ? GF_TRUE : GF_FALSE);
1101 12 : gf_bs_read_int(bs, 4); /* reserved */
1102 : //size += 2;
1103 12 : if (d->dsmcc_flag) {
1104 0 : d->service_id_record_length = gf_bs_read_u8(bs);
1105 0 : d->service_id_record = (char *)gf_malloc(d->service_id_record_length);
1106 : //size += 1 + d->service_id_record_length;
1107 0 : gf_bs_read_data(bs, d->service_id_record, d->service_id_record_length);
1108 : }
1109 12 : if (d->decoder_config_flags == 1) {
1110 0 : d->decoder_config_length = gf_bs_read_u8(bs);
1111 0 : d->decoder_config = (char *)gf_malloc(d->decoder_config_length);
1112 : //size += 1 + d->decoder_config_length;
1113 0 : gf_bs_read_data(bs, d->decoder_config, d->decoder_config_length);
1114 : }
1115 12 : if (d->decoder_config_flags == 3) {
1116 0 : d->decoder_config_id_length = gf_bs_read_u8(bs);
1117 0 : d->decoder_config_id = (char *)gf_malloc(d->decoder_config_id_length);
1118 : //size += 1 + d->decoder_config_id_length;
1119 0 : gf_bs_read_data(bs, d->decoder_config_id, d->decoder_config_id_length);
1120 : }
1121 12 : if (d->decoder_config_flags == 4) {
1122 0 : d->decoder_config_service_id = gf_bs_read_u8(bs);
1123 : //size++;
1124 : }
1125 : return d;
1126 : }
1127 :
1128 :
1129 5840 : static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
1130 : {
1131 : u32 info_length, pos, desc_len, evt_type, nb_es,i;
1132 : u32 nb_sections;
1133 : u32 data_size;
1134 : u32 nb_hevc, nb_hevc_temp, nb_shvc, nb_shvc_temp, nb_mhvc, nb_mhvc_temp;
1135 : unsigned char *data;
1136 : GF_M2TS_Section *section;
1137 : GF_Err e = GF_OK;
1138 :
1139 : /*wait for the last section */
1140 5840 : if (!(status&GF_M2TS_TABLE_END)) return;
1141 :
1142 : nb_es = 0;
1143 :
1144 : /*skip if already received but no update detected (eg same data) */
1145 5840 : if ((status&GF_M2TS_TABLE_REPEAT) && !(status&GF_M2TS_TABLE_UPDATE)) {
1146 5656 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PMT_REPEAT, pmt->program);
1147 : return;
1148 : }
1149 :
1150 184 : if (pmt->sec->demux_restarted) {
1151 50 : pmt->sec->demux_restarted = 0;
1152 50 : return;
1153 : }
1154 134 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PMT Found or updated\n"));
1155 :
1156 134 : nb_sections = gf_list_count(sections);
1157 134 : if (nb_sections > 1) {
1158 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PMT on multiple sections not supported\n"));
1159 : }
1160 :
1161 134 : section = (GF_M2TS_Section *)gf_list_get(sections, 0);
1162 134 : data = section->data;
1163 134 : data_size = section->data_size;
1164 :
1165 134 : if (data_size < 6) {
1166 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PMT header data size %d\n", data_size ) );
1167 : return;
1168 : }
1169 :
1170 134 : pmt->program->pcr_pid = ((data[0] & 0x1f) << 8) | data[1];
1171 :
1172 134 : info_length = ((data[2]&0xf)<<8) | data[3];
1173 134 : if (info_length + 4 > data_size) {
1174 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken PMT first loop, %d bytes avail but first loop size %d\n", data_size, info_length));
1175 : return;
1176 134 : } else if (info_length != 0) {
1177 : /* ...Read Descriptors ... */
1178 : u32 tag, len;
1179 : u32 first_loop_len = 0;
1180 15 : tag = (u32) data[4];
1181 15 : len = (u32) data[5];
1182 45 : while (info_length > first_loop_len) {
1183 15 : if (tag == GF_M2TS_MPEG4_IOD_DESCRIPTOR) {
1184 6 : if ((len>2) && (len - 2 <= info_length)) {
1185 : u32 size;
1186 : GF_BitStream *iod_bs;
1187 3 : iod_bs = gf_bs_new((char *)data+8, len-2, GF_BITSTREAM_READ);
1188 3 : if (pmt->program->pmt_iod) gf_odf_desc_del((GF_Descriptor *)pmt->program->pmt_iod);
1189 3 : pmt->program->pmt_iod = NULL;
1190 3 : e = gf_odf_parse_descriptor(iod_bs , (GF_Descriptor **) &pmt->program->pmt_iod, &size);
1191 3 : gf_bs_del(iod_bs );
1192 3 : if (pmt->program->pmt_iod && pmt->program->pmt_iod->tag != GF_ODF_IOD_TAG) {
1193 0 : GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER, ("pmt iod has wrong tag %d\n", pmt->program->pmt_iod->tag) );
1194 0 : gf_odf_desc_del((GF_Descriptor *)pmt->program->pmt_iod);
1195 0 : pmt->program->pmt_iod = NULL;
1196 : }
1197 3 : if (e==GF_OK) {
1198 : /*remember program number for service/program selection*/
1199 3 : if (pmt->program->pmt_iod) {
1200 3 : pmt->program->pmt_iod->ServiceID = pmt->program->number;
1201 : /*if empty IOD (freebox case), discard it and use dynamic declaration of object*/
1202 3 : if (!gf_list_count(pmt->program->pmt_iod->ESDescriptors)) {
1203 0 : gf_odf_desc_del((GF_Descriptor *)pmt->program->pmt_iod);
1204 0 : pmt->program->pmt_iod = NULL;
1205 : }
1206 : }
1207 : }
1208 : } else {
1209 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken IOD! len %d less than 2 bytes to declare IOD\n", len));
1210 : }
1211 12 : } else if (tag == GF_M2TS_METADATA_POINTER_DESCRIPTOR) {
1212 : GF_BitStream *metadatapd_bs;
1213 : GF_M2TS_MetadataPointerDescriptor *metapd;
1214 :
1215 12 : if (data_size <= 8 || data_size-6 < (u32)len)
1216 : break;
1217 :
1218 12 : metadatapd_bs = gf_bs_new((char *)data+6, len, GF_BITSTREAM_READ);
1219 12 : metapd = gf_m2ts_read_metadata_pointer_descriptor(metadatapd_bs, len);
1220 12 : gf_bs_del(metadatapd_bs);
1221 24 : if (metapd->application_format_identifier == GF_M2TS_META_ID3 &&
1222 24 : metapd->format_identifier == GF_M2TS_META_ID3 &&
1223 12 : metapd->carriage_flag == METADATA_CARRIAGE_SAME_TS) {
1224 : /*HLS ID3 Metadata */
1225 12 : pmt->program->metadata_pointer_descriptor = metapd;
1226 : } else {
1227 : /* don't know what to do with it for now, delete */
1228 0 : gf_m2ts_metadata_pointer_descriptor_del(metapd);
1229 : }
1230 : } else {
1231 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Skipping descriptor (0x%x) and others not supported\n", tag));
1232 : }
1233 15 : first_loop_len += 2 + len;
1234 : }
1235 : }
1236 134 : if (data_size <= 4 + info_length) return;
1237 134 : data += 4 + info_length;
1238 134 : data_size -= 4 + info_length;
1239 : pos = 0;
1240 :
1241 : /* count de number of program related PMT received */
1242 281 : for(i=0; i<gf_list_count(ts->programs); i++) {
1243 281 : GF_M2TS_Program *prog = (GF_M2TS_Program *)gf_list_get(ts->programs,i);
1244 281 : if(prog->pmt_pid == pmt->pid) {
1245 : break;
1246 : }
1247 : }
1248 :
1249 : nb_hevc = nb_hevc_temp = nb_shvc = nb_shvc_temp = nb_mhvc = nb_mhvc_temp = 0;
1250 435 : while (pos<data_size) {
1251 : GF_M2TS_PES *pes = NULL;
1252 : GF_M2TS_SECTION_ES *ses = NULL;
1253 : GF_M2TS_ES *es = NULL;
1254 : Bool inherit_pcr = 0;
1255 : Bool pmt_pid_reused = GF_FALSE;
1256 : u32 pid, stream_type, reg_desc_format;
1257 :
1258 301 : if (pos + 5 > data_size) {
1259 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken PMT! size %d but position %d and need at least 5 bytes to declare es\n", data_size, pos));
1260 : break;
1261 : }
1262 :
1263 301 : stream_type = data[0];
1264 301 : pid = ((data[1] & 0x1f) << 8) | data[2];
1265 301 : desc_len = ((data[3] & 0xf) << 8) | data[4];
1266 :
1267 301 : if (!pid) {
1268 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PID 0 for es descriptor in PMT of program %d, reserved for PAT\n", pmt->pid) );
1269 : break;
1270 : }
1271 301 : if (pid==1) {
1272 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PID 1 for es descriptor in PMT of program %d, reserved for CAT\n", pmt->pid) );
1273 : break;
1274 : }
1275 :
1276 301 : if (pid==pmt->pid) {
1277 : pmt_pid_reused = GF_TRUE;
1278 : } else {
1279 301 : u32 pcount = gf_list_count(ts->programs);
1280 1484 : for(i=0; i<pcount; i++) {
1281 1183 : GF_M2TS_Program *prog = (GF_M2TS_Program *)gf_list_get(ts->programs,i);
1282 1183 : if(prog->pmt_pid == pid) {
1283 : pmt_pid_reused = GF_TRUE;
1284 : break;
1285 : }
1286 : }
1287 : }
1288 301 : if (pmt_pid_reused) {
1289 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PID %d for es descriptor in PMT of program %d, this PID is already assigned to a PMT\n", pid, pmt->pid) );
1290 : break;
1291 : }
1292 :
1293 301 : if (desc_len > data_size-5) {
1294 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PMT es descriptor size for PID %d\n", pid ) );
1295 : break;
1296 : }
1297 :
1298 : if (!pid) {
1299 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PID 0 for es descriptor in PMT of program %d, reserved for PAT\n", pmt->pid) );
1300 : break;
1301 : }
1302 : if (pid==1) {
1303 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PID 1 for es descriptor in PMT of program %d, reserved for CAT\n", pmt->pid) );
1304 : break;
1305 : }
1306 :
1307 301 : if (pid==pmt->pid) {
1308 : pmt_pid_reused = GF_TRUE;
1309 : } else {
1310 301 : u32 pcount = gf_list_count(ts->programs);
1311 1484 : for(i=0; i<pcount; i++) {
1312 1183 : GF_M2TS_Program *prog = (GF_M2TS_Program *)gf_list_get(ts->programs,i);
1313 1183 : if(prog->pmt_pid == pid) {
1314 : pmt_pid_reused = GF_TRUE;
1315 : break;
1316 : }
1317 : }
1318 : }
1319 :
1320 301 : if (pmt_pid_reused) {
1321 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PID %d for es descriptor in PMT of program %d, this PID is already assigned to a PMT\n", pid, pmt->pid) );
1322 : break;
1323 : }
1324 :
1325 301 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("stream_type :%d \n",stream_type));
1326 301 : if ((stream_type==GF_M2TS_JPEG_XS) && gf_opts_get_bool("core", "m2ts-vvc-old"))
1327 : stream_type = GF_M2TS_VIDEO_VVC;
1328 :
1329 301 : switch (stream_type) {
1330 :
1331 : /* PES */
1332 : case GF_M2TS_VIDEO_MPEG1:
1333 : case GF_M2TS_VIDEO_MPEG2:
1334 : case GF_M2TS_VIDEO_DCII:
1335 : case GF_M2TS_VIDEO_MPEG4:
1336 : case GF_M2TS_SYSTEMS_MPEG4_PES:
1337 : case GF_M2TS_VIDEO_H264:
1338 : case GF_M2TS_VIDEO_SVC:
1339 : case GF_M2TS_VIDEO_MVCD:
1340 : case GF_M2TS_VIDEO_HEVC:
1341 : case GF_M2TS_VIDEO_HEVC_MCTS:
1342 : case GF_M2TS_VIDEO_HEVC_TEMPORAL:
1343 : case GF_M2TS_VIDEO_SHVC:
1344 : case GF_M2TS_VIDEO_SHVC_TEMPORAL:
1345 : case GF_M2TS_VIDEO_MHVC:
1346 : case GF_M2TS_VIDEO_MHVC_TEMPORAL:
1347 : case GF_M2TS_VIDEO_VVC:
1348 : case GF_M2TS_VIDEO_VVC_TEMPORAL:
1349 : case GF_M2TS_VIDEO_VC1:
1350 : inherit_pcr = 1;
1351 227 : case GF_M2TS_AUDIO_MPEG1:
1352 : case GF_M2TS_AUDIO_MPEG2:
1353 : case GF_M2TS_AUDIO_AAC:
1354 : case GF_M2TS_AUDIO_LATM_AAC:
1355 : case GF_M2TS_AUDIO_AC3:
1356 : case GF_M2TS_AUDIO_EC3:
1357 : case GF_M2TS_AUDIO_DTS:
1358 : case GF_M2TS_MHAS_MAIN:
1359 : case GF_M2TS_MHAS_AUX:
1360 : case GF_M2TS_SUBTITLE_DVB:
1361 : case GF_M2TS_METADATA_PES:
1362 : case 0xA1:
1363 227 : GF_SAFEALLOC(pes, GF_M2TS_PES);
1364 227 : if (!pes) {
1365 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG2TS] Failed to allocate ES for pid %d\n", pid));
1366 : return;
1367 : }
1368 227 : pes->cc = -1;
1369 227 : pes->flags = GF_M2TS_ES_IS_PES;
1370 227 : if (inherit_pcr)
1371 106 : pes->flags |= GF_M2TS_INHERIT_PCR;
1372 : es = (GF_M2TS_ES *)pes;
1373 : break;
1374 61 : case GF_M2TS_PRIVATE_DATA:
1375 61 : GF_SAFEALLOC(pes, GF_M2TS_PES);
1376 61 : if (!pes) {
1377 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG2TS] Failed to allocate ES for pid %d\n", pid));
1378 : return;
1379 : }
1380 61 : pes->cc = -1;
1381 61 : pes->flags = GF_M2TS_ES_IS_PES;
1382 : es = (GF_M2TS_ES *)pes;
1383 61 : break;
1384 : /* Sections */
1385 6 : case GF_M2TS_SYSTEMS_MPEG4_SECTIONS:
1386 6 : GF_SAFEALLOC(ses, GF_M2TS_SECTION_ES);
1387 6 : if (!ses) {
1388 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG2TS] Failed to allocate ES for pid %d\n", pid));
1389 : return;
1390 : }
1391 : es = (GF_M2TS_ES *)ses;
1392 6 : es->flags |= GF_M2TS_ES_IS_SECTION;
1393 : /* carriage of ISO_IEC_14496 data in sections */
1394 6 : if (stream_type == GF_M2TS_SYSTEMS_MPEG4_SECTIONS) {
1395 : /*MPEG-4 sections need to be fully checked: if one section is lost, this means we lost
1396 : one SL packet in the AU so we must wait for the complete section again*/
1397 6 : ses->sec = gf_m2ts_section_filter_new(gf_m2ts_process_mpeg4section, 0);
1398 : /*create OD container*/
1399 6 : if (!pmt->program->additional_ods) {
1400 3 : pmt->program->additional_ods = gf_list_new();
1401 3 : ts->has_4on2 = 1;
1402 : }
1403 : }
1404 : break;
1405 :
1406 7 : case GF_M2TS_13818_6_ANNEX_A:
1407 : case GF_M2TS_13818_6_ANNEX_B:
1408 : case GF_M2TS_13818_6_ANNEX_C:
1409 : case GF_M2TS_13818_6_ANNEX_D:
1410 : case GF_M2TS_PRIVATE_SECTION:
1411 : case GF_M2TS_QUALITY_SEC:
1412 : case GF_M2TS_MORE_SEC:
1413 7 : GF_SAFEALLOC(ses, GF_M2TS_SECTION_ES);
1414 7 : if (!ses) {
1415 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG2TS] Failed to allocate ES for pid %d\n", pid));
1416 : return;
1417 : }
1418 : es = (GF_M2TS_ES *)ses;
1419 7 : es->flags |= GF_M2TS_ES_IS_SECTION;
1420 7 : es->pid = pid;
1421 7 : es->service_id = pmt->program->number;
1422 7 : if (stream_type == GF_M2TS_PRIVATE_SECTION) {
1423 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("AIT sections on pid %d\n", pid));
1424 7 : } else if (stream_type == GF_M2TS_QUALITY_SEC) {
1425 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("Quality metadata sections on pid %d\n", pid));
1426 7 : } else if (stream_type == GF_M2TS_MORE_SEC) {
1427 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("MORE sections on pid %d\n", pid));
1428 : } else {
1429 7 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("stream type DSM CC user private sections on pid %d \n", pid));
1430 : }
1431 : /* NULL means: trigger the call to on_event with DVB_GENERAL type and the raw section as payload */
1432 7 : ses->sec = gf_m2ts_section_filter_new(NULL, 1);
1433 : //ses->sec->service_id = pmt->program->number;
1434 7 : break;
1435 :
1436 0 : case GF_M2TS_MPE_SECTIONS:
1437 0 : if (! ts->prefix_present) {
1438 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("stream type MPE found : pid = %d \n", pid));
1439 : #ifdef GPAC_ENABLE_MPE
1440 : es = gf_dvb_mpe_section_new();
1441 : if (es->flags & GF_M2TS_ES_IS_SECTION) {
1442 : /* NULL means: trigger the call to on_event with DVB_GENERAL type and the raw section as payload */
1443 : ((GF_M2TS_SECTION_ES*)es)->sec = gf_m2ts_section_filter_new(NULL, 1);
1444 : }
1445 : #endif
1446 : break;
1447 : }
1448 :
1449 : default:
1450 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) );
1451 : //GF_LOG(/*GF_LOG_WARNING*/GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) );
1452 : break;
1453 : }
1454 :
1455 301 : if (es) {
1456 301 : es->stream_type = (stream_type==GF_M2TS_PRIVATE_DATA) ? 0 : stream_type;
1457 301 : es->program = pmt->program;
1458 301 : es->pid = pid;
1459 301 : es->component_tag = -1;
1460 : }
1461 :
1462 : pos += 5;
1463 301 : data += 5;
1464 :
1465 799 : while (desc_len) {
1466 197 : if (pos + 2 > data_size) {
1467 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken PMT descriptor! size %d but position %d and need at least 2 bytes to parse descriptor\n", data_size, pos));
1468 : break;
1469 : }
1470 197 : u8 tag = data[0];
1471 197 : u32 len = data[1];
1472 :
1473 197 : if (pos + 2 + len > data_size) {
1474 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken PMT descriptor! size %d, desc size %d but position %d\n", data_size, len, pos));
1475 : break;
1476 : }
1477 :
1478 197 : if (es) {
1479 197 : switch (tag) {
1480 55 : case GF_M2TS_ISO_639_LANGUAGE_DESCRIPTOR:
1481 55 : if (pes && (len>=3) )
1482 55 : pes->lang = GF_4CC(' ', data[2], data[3], data[4]);
1483 : break;
1484 9 : case GF_M2TS_MPEG4_SL_DESCRIPTOR:
1485 9 : if (len>=2) {
1486 9 : es->mpeg4_es_id = ( (u32) data[2] & 0x1f) << 8 | data[3];
1487 9 : es->flags |= GF_M2TS_ES_IS_SL;
1488 : }
1489 : break;
1490 6 : case GF_M2TS_REGISTRATION_DESCRIPTOR:
1491 6 : if (len>=4) {
1492 6 : reg_desc_format = GF_4CC(data[2], data[3], data[4], data[5]);
1493 : /* cf http://www.smpte-ra.org/mpegreg/mpegreg.html */
1494 6 : switch (reg_desc_format) {
1495 6 : case GF_M2TS_RA_STREAM_AC3:
1496 6 : es->stream_type = GF_M2TS_AUDIO_AC3;
1497 6 : break;
1498 0 : case GF_M2TS_RA_STREAM_VC1:
1499 0 : es->stream_type = GF_M2TS_VIDEO_VC1;
1500 0 : break;
1501 0 : case GF_M2TS_RA_STREAM_GPAC:
1502 0 : if (len==8) {
1503 0 : es->stream_type = GF_4CC(data[6], data[7], data[8], data[9]);
1504 0 : es->flags |= GF_M2TS_GPAC_CODEC_ID;
1505 0 : break;
1506 : }
1507 : default:
1508 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("Unknown registration descriptor %s\n", gf_4cc_to_str(reg_desc_format) ));
1509 : break;
1510 : }
1511 0 : }
1512 : break;
1513 0 : case GF_M2TS_DVB_EAC3_DESCRIPTOR:
1514 0 : es->stream_type = GF_M2TS_AUDIO_EC3;
1515 0 : break;
1516 7 : case GF_M2TS_DVB_DATA_BROADCAST_ID_DESCRIPTOR:
1517 7 : if (len>=2) {
1518 7 : u32 id = data[2]<<8 | data[3];
1519 7 : if ((id == 0xB) && ses && !ses->sec) {
1520 0 : ses->sec = gf_m2ts_section_filter_new(NULL, 1);
1521 : }
1522 : }
1523 : break;
1524 49 : case GF_M2TS_DVB_SUBTITLING_DESCRIPTOR:
1525 49 : if (pes && (len>=8)) {
1526 49 : pes->sub.language[0] = data[2];
1527 49 : pes->sub.language[1] = data[3];
1528 49 : pes->sub.language[2] = data[4];
1529 49 : pes->sub.type = data[5];
1530 49 : pes->sub.composition_page_id = (data[6]<<8) | data[7];
1531 49 : pes->sub.ancillary_page_id = (data[8]<<8) | data[9];
1532 : }
1533 49 : es->stream_type = GF_M2TS_DVB_SUBTITLE;
1534 49 : break;
1535 7 : case GF_M2TS_DVB_STREAM_IDENTIFIER_DESCRIPTOR:
1536 7 : if (len>=1) {
1537 7 : es->component_tag = data[2];
1538 7 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Component Tag: %d on Program %d\n", es->component_tag, es->program->number));
1539 : }
1540 : break;
1541 6 : case GF_M2TS_DVB_TELETEXT_DESCRIPTOR:
1542 6 : es->stream_type = GF_M2TS_DVB_TELETEXT;
1543 6 : break;
1544 0 : case GF_M2TS_DVB_VBI_DATA_DESCRIPTOR:
1545 0 : es->stream_type = GF_M2TS_DVB_VBI;
1546 0 : break;
1547 4 : case GF_M2TS_HIERARCHY_DESCRIPTOR:
1548 4 : if (pes && (len>=4)) {
1549 : u8 hierarchy_embedded_layer_index;
1550 4 : GF_BitStream *hbs = gf_bs_new((const char *)data, data_size, GF_BITSTREAM_READ);
1551 4 : /*u32 skip = */gf_bs_read_int(hbs, 16);
1552 4 : /*u8 res1 = */gf_bs_read_int(hbs, 1);
1553 4 : /*u8 temp_scal = */gf_bs_read_int(hbs, 1);
1554 4 : /*u8 spatial_scal = */gf_bs_read_int(hbs, 1);
1555 4 : /*u8 quality_scal = */gf_bs_read_int(hbs, 1);
1556 4 : /*u8 hierarchy_type = */gf_bs_read_int(hbs, 4);
1557 4 : /*u8 res2 = */gf_bs_read_int(hbs, 2);
1558 4 : /*u8 hierarchy_layer_index = */gf_bs_read_int(hbs, 6);
1559 4 : /*u8 tref_not_present = */gf_bs_read_int(hbs, 1);
1560 4 : /*u8 res3 = */gf_bs_read_int(hbs, 1);
1561 4 : hierarchy_embedded_layer_index = gf_bs_read_int(hbs, 6);
1562 4 : /*u8 res4 = */gf_bs_read_int(hbs, 2);
1563 4 : /*u8 hierarchy_channel = */gf_bs_read_int(hbs, 6);
1564 4 : gf_bs_del(hbs);
1565 :
1566 4 : pes->depends_on_pid = 1+hierarchy_embedded_layer_index;
1567 : }
1568 : break;
1569 12 : case GF_M2TS_METADATA_DESCRIPTOR:
1570 : {
1571 : GF_BitStream *metadatad_bs;
1572 : GF_M2TS_MetadataDescriptor *metad;
1573 12 : metadatad_bs = gf_bs_new((char *)data+2, len, GF_BITSTREAM_READ);
1574 12 : metad = gf_m2ts_read_metadata_descriptor(metadatad_bs, len);
1575 12 : gf_bs_del(metadatad_bs);
1576 24 : if (metad->application_format_identifier == GF_M2TS_META_ID3 &&
1577 12 : metad->format_identifier == GF_M2TS_META_ID3) {
1578 : /*HLS ID3 Metadata */
1579 12 : if (pes) {
1580 12 : pes->metadata_descriptor = metad;
1581 12 : pes->stream_type = GF_M2TS_METADATA_ID3_HLS;
1582 : }
1583 : } else {
1584 : /* don't know what to do with it for now, delete */
1585 0 : gf_m2ts_metadata_descriptor_del(metad);
1586 : }
1587 : }
1588 : break;
1589 :
1590 42 : default:
1591 42 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] skipping descriptor (0x%x) not supported\n", tag));
1592 : break;
1593 : }
1594 0 : }
1595 :
1596 197 : data += len+2;
1597 : pos += len+2;
1598 197 : if (desc_len < len+2) {
1599 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid PMT es descriptor size for PID %d\n", pid ) );
1600 : break;
1601 : }
1602 197 : desc_len-=len+2;
1603 : }
1604 301 : if (es && !es->stream_type) {
1605 0 : gf_free(es);
1606 : es = NULL;
1607 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Private Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) );
1608 : }
1609 :
1610 301 : if (!es) continue;
1611 :
1612 301 : if (ts->ess[pid]) {
1613 : //this is component reuse across programs, overwrite the previously declared stream ...
1614 0 : if (status & GF_M2TS_TABLE_FOUND) {
1615 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d reused across programs %d and %d, not completely supported\n", pid, ts->ess[pid]->program->number, es->program->number ) );
1616 :
1617 : //add stream to program but don't reassign the pid table until the stream is playing (>GF_M2TS_PES_FRAMING_SKIP)
1618 0 : gf_list_add(pmt->program->streams, es);
1619 0 : if (!(es->flags & GF_M2TS_ES_IS_SECTION) ) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP);
1620 :
1621 0 : nb_es++;
1622 : //skip assignment below
1623 : es = NULL;
1624 : }
1625 : /*watchout for pmt update - FIXME this likely won't work in most cases*/
1626 : else {
1627 :
1628 0 : GF_M2TS_ES *o_es = ts->ess[es->pid];
1629 :
1630 0 : if ((o_es->stream_type == es->stream_type)
1631 0 : && ((o_es->flags & GF_M2TS_ES_STATIC_FLAGS_MASK) == (es->flags & GF_M2TS_ES_STATIC_FLAGS_MASK))
1632 0 : && (o_es->mpeg4_es_id == es->mpeg4_es_id)
1633 0 : && ((o_es->flags & GF_M2TS_ES_IS_SECTION) || ((GF_M2TS_PES *)o_es)->lang == ((GF_M2TS_PES *)es)->lang)
1634 : ) {
1635 0 : gf_free(es);
1636 : es = NULL;
1637 : } else {
1638 0 : gf_m2ts_es_del(o_es, ts);
1639 0 : ts->ess[es->pid] = NULL;
1640 : }
1641 : }
1642 : }
1643 :
1644 : if (es) {
1645 301 : ts->ess[es->pid] = es;
1646 301 : gf_list_add(pmt->program->streams, es);
1647 301 : if (!(es->flags & GF_M2TS_ES_IS_SECTION) ) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP);
1648 :
1649 301 : nb_es++;
1650 :
1651 301 : if (es->stream_type == GF_M2TS_VIDEO_HEVC) nb_hevc++;
1652 301 : else if (es->stream_type == GF_M2TS_VIDEO_HEVC_TEMPORAL) nb_hevc_temp++;
1653 301 : else if (es->stream_type == GF_M2TS_VIDEO_SHVC) nb_shvc++;
1654 297 : else if (es->stream_type == GF_M2TS_VIDEO_SHVC_TEMPORAL) nb_shvc_temp++;
1655 297 : else if (es->stream_type == GF_M2TS_VIDEO_MHVC) nb_mhvc++;
1656 297 : else if (es->stream_type == GF_M2TS_VIDEO_MHVC_TEMPORAL) nb_mhvc_temp++;
1657 : }
1658 : }
1659 :
1660 : //Table 2-139, implied hierarchy indexes
1661 134 : if (nb_hevc_temp + nb_shvc + nb_shvc_temp + nb_mhvc+ nb_mhvc_temp) {
1662 8 : for (i=0; i<gf_list_count(pmt->program->streams); i++) {
1663 8 : GF_M2TS_PES *es = (GF_M2TS_PES *)gf_list_get(pmt->program->streams, i);
1664 8 : if ( !(es->flags & GF_M2TS_ES_IS_PES)) continue;
1665 4 : if (es->depends_on_pid) continue;
1666 :
1667 0 : switch (es->stream_type) {
1668 0 : case GF_M2TS_VIDEO_HEVC_TEMPORAL:
1669 0 : es->depends_on_pid = 1;
1670 0 : break;
1671 0 : case GF_M2TS_VIDEO_SHVC:
1672 0 : if (!nb_hevc_temp) es->depends_on_pid = 1;
1673 0 : else es->depends_on_pid = 2;
1674 : break;
1675 0 : case GF_M2TS_VIDEO_SHVC_TEMPORAL:
1676 0 : es->depends_on_pid = 3;
1677 0 : break;
1678 0 : case GF_M2TS_VIDEO_MHVC:
1679 0 : if (!nb_hevc_temp) es->depends_on_pid = 1;
1680 0 : else es->depends_on_pid = 2;
1681 : break;
1682 0 : case GF_M2TS_VIDEO_MHVC_TEMPORAL:
1683 0 : if (!nb_hevc_temp) es->depends_on_pid = 2;
1684 0 : else es->depends_on_pid = 3;
1685 : break;
1686 : }
1687 : }
1688 : }
1689 :
1690 134 : if (nb_es) {
1691 : //translate hierarchy descriptors indexes into PIDs - check whether the PMT-index rules are the same for HEVC
1692 435 : for (i=0; i<gf_list_count(pmt->program->streams); i++) {
1693 : GF_M2TS_PES *an_es = NULL;
1694 435 : GF_M2TS_PES *es = (GF_M2TS_PES *)gf_list_get(pmt->program->streams, i);
1695 435 : if ( !(es->flags & GF_M2TS_ES_IS_PES)) continue;
1696 288 : if (!es->depends_on_pid) continue;
1697 :
1698 : //fixeme we are not always assured that hierarchy_layer_index matches the stream index...
1699 : //+1 is because our first stream is the PMT
1700 4 : an_es = (GF_M2TS_PES *)gf_list_get(pmt->program->streams, es->depends_on_pid);
1701 4 : if (an_es) {
1702 0 : es->depends_on_pid = an_es->pid;
1703 : } else {
1704 4 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS] Wrong dependency index in hierarchy descriptor, assuming non-scalable stream\n"));
1705 4 : es->depends_on_pid = 0;
1706 : }
1707 : }
1708 :
1709 134 : evt_type = (status&GF_M2TS_TABLE_FOUND) ? GF_M2TS_EVT_PMT_FOUND : GF_M2TS_EVT_PMT_UPDATE;
1710 134 : if (ts->on_event) ts->on_event(ts, evt_type, pmt->program);
1711 : } else {
1712 : /* if we found no new ES it's simply a repeat of the PMT */
1713 0 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PMT_REPEAT, pmt->program);
1714 : }
1715 : }
1716 :
1717 3341 : static void gf_m2ts_process_pat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
1718 : {
1719 : GF_M2TS_Program *prog;
1720 : GF_M2TS_SECTION_ES *pmt;
1721 : u32 i, nb_progs, evt_type;
1722 : u32 nb_sections;
1723 : u32 data_size;
1724 : unsigned char *data;
1725 : GF_M2TS_Section *section;
1726 :
1727 : /*wait for the last section */
1728 3341 : if (!(status&GF_M2TS_TABLE_END)) return;
1729 :
1730 : /*skip if already received*/
1731 3341 : if (status&GF_M2TS_TABLE_REPEAT) {
1732 3217 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PAT_REPEAT, NULL);
1733 : return;
1734 : }
1735 :
1736 124 : nb_sections = gf_list_count(sections);
1737 124 : if (nb_sections > 1) {
1738 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PAT on multiple sections not supported\n"));
1739 : }
1740 :
1741 124 : section = (GF_M2TS_Section *)gf_list_get(sections, 0);
1742 124 : data = section->data;
1743 124 : data_size = section->data_size;
1744 :
1745 124 : if (!(status&GF_M2TS_TABLE_UPDATE) && gf_list_count(ts->programs)) {
1746 32 : if (ts->pat->demux_restarted) {
1747 32 : ts->pat->demux_restarted = 0;
1748 : } else {
1749 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Multiple different PAT on single TS found, ignoring new PAT declaration (table id %d - extended table id %d)\n", table_id, ex_table_id));
1750 : }
1751 : return;
1752 : }
1753 92 : nb_progs = data_size / 4;
1754 :
1755 239 : for (i=0; i<nb_progs; i++) {
1756 : u16 number, pid;
1757 147 : number = (data[0]<<8) | data[1];
1758 147 : pid = (data[2]&0x1f)<<8 | data[3];
1759 147 : data += 4;
1760 147 : if (number==0) {
1761 13 : if (!ts->nit) {
1762 0 : ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0);
1763 : }
1764 134 : } else if (!pid) {
1765 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken PAT found reserved PID 0, ignoring\n", pid));
1766 134 : } else if (! ts->ess[pid]) {
1767 134 : GF_SAFEALLOC(prog, GF_M2TS_Program);
1768 134 : if (!prog) {
1769 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Fail to allocate program for pid %d\n", pid));
1770 : return;
1771 : }
1772 134 : prog->streams = gf_list_new();
1773 134 : prog->pmt_pid = pid;
1774 134 : prog->number = number;
1775 134 : prog->ts = ts;
1776 134 : gf_list_add(ts->programs, prog);
1777 134 : GF_SAFEALLOC(pmt, GF_M2TS_SECTION_ES);
1778 134 : if (!pmt) {
1779 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Fail to allocate pmt filter for pid %d\n", pid));
1780 : return;
1781 : }
1782 134 : pmt->flags = GF_M2TS_ES_IS_SECTION | GF_M2TS_ES_IS_PMT;
1783 134 : gf_list_add(prog->streams, pmt);
1784 134 : pmt->pid = prog->pmt_pid;
1785 134 : pmt->program = prog;
1786 : /* if (ts->ess[pmt->pid]) {
1787 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("Redefinition of pmt for pid %d\n", pid));
1788 : gf_m2ts_es_del(ts->ess[pmt->pid], ts);
1789 : }
1790 : */
1791 134 : ts->ess[pmt->pid] = (GF_M2TS_ES *)pmt;
1792 134 : pmt->sec = gf_m2ts_section_filter_new(gf_m2ts_process_pmt, 0);
1793 : }
1794 : }
1795 :
1796 92 : evt_type = (status&GF_M2TS_TABLE_UPDATE) ? GF_M2TS_EVT_PAT_UPDATE : GF_M2TS_EVT_PAT_FOUND;
1797 92 : if (ts->on_event) {
1798 : GF_M2TS_SectionInfo sinfo;
1799 65 : sinfo.ex_table_id = ex_table_id;
1800 65 : sinfo.table_id = table_id;
1801 65 : sinfo.version_number = version_number;
1802 65 : ts->on_event(ts, evt_type, &sinfo);
1803 : }
1804 : }
1805 :
1806 288 : static void gf_m2ts_process_cat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
1807 : {
1808 : u32 evt_type;
1809 : /*
1810 : GF_M2TS_Program *prog;
1811 : GF_M2TS_SECTION_ES *pmt;
1812 : u32 i, nb_progs;
1813 : u32 nb_sections;
1814 : u32 data_size;
1815 : unsigned char *data;
1816 : GF_M2TS_Section *section;
1817 : */
1818 :
1819 : /*wait for the last section */
1820 288 : if (!(status&GF_M2TS_TABLE_END)) return;
1821 :
1822 : /*skip if already received*/
1823 288 : if (status&GF_M2TS_TABLE_REPEAT) {
1824 282 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_CAT_REPEAT, NULL);
1825 : return;
1826 : }
1827 : /*
1828 : nb_sections = gf_list_count(sections);
1829 : if (nb_sections > 1) {
1830 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("CAT on multiple sections not supported\n"));
1831 : }
1832 :
1833 : section = (GF_M2TS_Section *)gf_list_get(sections, 0);
1834 : data = section->data;
1835 : data_size = section->data_size;
1836 :
1837 : nb_progs = data_size / 4;
1838 :
1839 : for (i=0; i<nb_progs; i++) {
1840 : u16 number, pid;
1841 : number = (data[0]<<8) | data[1];
1842 : pid = (data[2]&0x1f)<<8 | data[3];
1843 : data += 4;
1844 : if (number==0) {
1845 : if (!ts->nit) {
1846 : ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0);
1847 : }
1848 : } else {
1849 : GF_SAFEALLOC(prog, GF_M2TS_Program);
1850 : prog->streams = gf_list_new();
1851 : prog->pmt_pid = pid;
1852 : prog->number = number;
1853 : gf_list_add(ts->programs, prog);
1854 : GF_SAFEALLOC(pmt, GF_M2TS_SECTION_ES);
1855 : pmt->flags = GF_M2TS_ES_IS_SECTION;
1856 : gf_list_add(prog->streams, pmt);
1857 : pmt->pid = prog->pmt_pid;
1858 : pmt->program = prog;
1859 : ts->ess[pmt->pid] = (GF_M2TS_ES *)pmt;
1860 : pmt->sec = gf_m2ts_section_filter_new(gf_m2ts_process_pmt, 0);
1861 : }
1862 : }
1863 : */
1864 :
1865 6 : evt_type = (status&GF_M2TS_TABLE_UPDATE) ? GF_M2TS_EVT_CAT_UPDATE : GF_M2TS_EVT_CAT_FOUND;
1866 6 : if (ts->on_event) ts->on_event(ts, evt_type, NULL);
1867 : }
1868 :
1869 0 : u64 gf_m2ts_get_pts(unsigned char *data)
1870 : {
1871 : u64 pts;
1872 : u32 val;
1873 31715 : pts = (u64)((data[0] >> 1) & 0x07) << 30;
1874 31715 : val = (data[1] << 8) | data[2];
1875 31715 : pts |= (u64)(val >> 1) << 15;
1876 31715 : val = (data[3] << 8) | data[4];
1877 31715 : pts |= (u64)(val >> 1);
1878 0 : return pts;
1879 : }
1880 :
1881 25704 : void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_size, GF_M2TS_PESHeader *pesh)
1882 : {
1883 : u32 has_pts, has_dts;
1884 : u32 len_check;
1885 :
1886 : memset(pesh, 0, sizeof(GF_M2TS_PESHeader));
1887 :
1888 25704 : if (data_size < 6) {
1889 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PES Header is too small (%d < 6)\n", data_size));
1890 : return;
1891 : }
1892 :
1893 : len_check = 0;
1894 :
1895 25704 : pesh->id = data[0];
1896 25704 : pesh->pck_len = (data[1]<<8) | data[2];
1897 : /*
1898 : 2bits
1899 : scrambling_control = gf_bs_read_int(bs,2);
1900 : priority = gf_bs_read_int(bs,1);
1901 : */
1902 25704 : pesh->data_alignment = (data[3] & 0x4) ? 1 : 0;
1903 : /*
1904 : copyright = gf_bs_read_int(bs,1);
1905 : original = gf_bs_read_int(bs,1);
1906 : */
1907 25704 : has_pts = (data[4]&0x80);
1908 25704 : has_dts = has_pts ? (data[4]&0x40) : 0;
1909 : /*
1910 : ESCR_flag = gf_bs_read_int(bs,1);
1911 : ES_rate_flag = gf_bs_read_int(bs,1);
1912 : DSM_flag = gf_bs_read_int(bs,1);
1913 : additional_copy_flag = gf_bs_read_int(bs,1);
1914 : prev_crc_flag = gf_bs_read_int(bs,1);
1915 : extension_flag = gf_bs_read_int(bs,1);
1916 : */
1917 :
1918 25704 : pesh->hdr_data_len = data[5];
1919 :
1920 25704 : data += 6;
1921 25704 : if (has_pts) {
1922 25702 : pesh->PTS = gf_m2ts_get_pts(data);
1923 25702 : data+=5;
1924 : len_check += 5;
1925 : }
1926 25704 : if (has_dts) {
1927 6011 : pesh->DTS = gf_m2ts_get_pts(data);
1928 : //data+=5;
1929 6011 : len_check += 5;
1930 : } else {
1931 19693 : pesh->DTS = pesh->PTS;
1932 : }
1933 25704 : if (len_check < pesh->hdr_data_len) {
1934 2664 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Skipping %d bytes in pes header\n", pes->pid, pesh->hdr_data_len - len_check));
1935 23040 : } else if (len_check > pesh->hdr_data_len) {
1936 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Wrong pes_header_data_length field %d bytes - read %d\n", pes->pid, pesh->hdr_data_len, len_check));
1937 : }
1938 :
1939 25704 : if ((pesh->PTS<90000) && ((s32)pesh->DTS<0)) {
1940 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Wrong DTS %d negative for PTS %d - forcing to 0\n", pes->pid, pesh->DTS, pesh->PTS));
1941 0 : pesh->DTS=0;
1942 : }
1943 : }
1944 :
1945 3140 : static void gf_m2ts_store_temi(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes)
1946 : {
1947 3140 : GF_BitStream *bs = gf_bs_new(pes->temi_tc_desc, pes->temi_tc_desc_len, GF_BITSTREAM_READ);
1948 3140 : u32 has_timestamp = gf_bs_read_int(bs, 2);
1949 3140 : Bool has_ntp = (Bool) gf_bs_read_int(bs, 1);
1950 3140 : /*u32 has_ptp = */gf_bs_read_int(bs, 1);
1951 3140 : /*u32 has_timecode = */gf_bs_read_int(bs, 2);
1952 :
1953 3140 : memset(&pes->temi_tc, 0, sizeof(GF_M2TS_TemiTimecodeDescriptor));
1954 3140 : pes->temi_tc.force_reload = gf_bs_read_int(bs, 1);
1955 3140 : pes->temi_tc.is_paused = gf_bs_read_int(bs, 1);
1956 3140 : pes->temi_tc.is_discontinuity = gf_bs_read_int(bs, 1);
1957 3140 : gf_bs_read_int(bs, 7);
1958 3140 : pes->temi_tc.timeline_id = gf_bs_read_int(bs, 8);
1959 3140 : if (has_timestamp) {
1960 3140 : pes->temi_tc.media_timescale = gf_bs_read_u32(bs);
1961 3140 : if (has_timestamp==2)
1962 0 : pes->temi_tc.media_timestamp = gf_bs_read_u64(bs);
1963 : else
1964 3140 : pes->temi_tc.media_timestamp = gf_bs_read_u32(bs);
1965 : }
1966 3140 : if (has_ntp) {
1967 0 : pes->temi_tc.ntp = gf_bs_read_u64(bs);
1968 : }
1969 3140 : gf_bs_del(bs);
1970 3140 : pes->temi_tc_desc_len = 0;
1971 3140 : pes->temi_pending = 1;
1972 3140 : }
1973 :
1974 25862 : void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes)
1975 : {
1976 : GF_M2TS_PESHeader pesh;
1977 25862 : if (!ts) return;
1978 :
1979 : /*we need at least a full, valid start code and PES header !!*/
1980 25862 : if ((pes->pck_data_len >= 4) && !pes->pck_data[0] && !pes->pck_data[1] && (pes->pck_data[2] == 0x1)) {
1981 : u32 len;
1982 : Bool has_pes_header = GF_TRUE;
1983 25797 : u32 stream_id = pes->pck_data[3];
1984 : Bool same_pts = GF_FALSE;
1985 :
1986 25797 : switch (stream_id) {
1987 : case GF_M2_STREAMID_PROGRAM_STREAM_MAP:
1988 : case GF_M2_STREAMID_PADDING:
1989 : case GF_M2_STREAMID_PRIVATE_2:
1990 : case GF_M2_STREAMID_ECM:
1991 : case GF_M2_STREAMID_EMM:
1992 : case GF_M2_STREAMID_PROGRAM_STREAM_DIRECTORY:
1993 : case GF_M2_STREAMID_DSMCC:
1994 : case GF_M2_STREAMID_H222_TYPE_E:
1995 : has_pes_header = GF_FALSE;
1996 : break;
1997 : }
1998 :
1999 : if (has_pes_header) {
2000 :
2001 : /*OK read header*/
2002 25704 : gf_m2ts_pes_header(pes, pes->pck_data + 3, pes->pck_data_len - 3, &pesh);
2003 :
2004 : /*send PES timing*/
2005 25704 : if (ts->notify_pes_timing) {
2006 : GF_M2TS_PES_PCK pck;
2007 : memset(&pck, 0, sizeof(GF_M2TS_PES_PCK));
2008 767 : pck.PTS = pesh.PTS;
2009 767 : pck.DTS = pesh.DTS;
2010 767 : pck.stream = pes;
2011 767 : if (pes->rap) pck.flags |= GF_M2TS_PES_PCK_RAP;
2012 767 : pes->pes_end_packet_number = ts->pck_number;
2013 767 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PES_TIMING, &pck);
2014 : }
2015 25704 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Got PES header DTS %d PTS %d\n", pes->pid, pesh.DTS, pesh.PTS));
2016 :
2017 25704 : if (pesh.PTS) {
2018 25678 : if (pesh.PTS == pes->PTS) {
2019 : same_pts = GF_TRUE;
2020 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - same PTS "LLU" for two consecutive PES packets \n", pes->pid, pes->PTS));
2021 : }
2022 : #ifndef GPAC_DISABLE_LOG
2023 : /*FIXME - this test should only be done for non bi-directionally coded media
2024 : else if (pesh.PTS < pes->PTS) {
2025 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - PTS "LLU" less than previous packet PTS "LLU"\n", pes->pid, pesh.PTS, pes->PTS) );
2026 : }
2027 : */
2028 : #endif
2029 :
2030 25678 : pes->PTS = pesh.PTS;
2031 : #ifndef GPAC_DISABLE_LOG
2032 : {
2033 25678 : if (pes->DTS && (pesh.DTS == pes->DTS)) {
2034 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - same DTS "LLU" for two consecutive PES packets \n", pes->pid, pes->DTS));
2035 : }
2036 25678 : if (pesh.DTS < pes->DTS) {
2037 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d - DTS "LLU" less than previous DTS "LLU"\n", pes->pid, pesh.DTS, pes->DTS));
2038 : }
2039 : }
2040 : #endif
2041 25678 : pes->DTS = pesh.DTS;
2042 : }
2043 : /*no PTSs were coded, same time*/
2044 26 : else if (!pesh.hdr_data_len) {
2045 : same_pts = GF_TRUE;
2046 : }
2047 :
2048 :
2049 : /*3-byte start-code + 6 bytes header + hdr extensions*/
2050 25704 : len = 9 + pesh.hdr_data_len;
2051 :
2052 : } else {
2053 : /*3-byte start-code + 1 byte streamid*/
2054 : len = 4;
2055 : memset(&pesh, 0, sizeof(pesh));
2056 : }
2057 :
2058 25797 : if ((u8) pes->pck_data[3]==0xfa) {
2059 : GF_M2TS_SL_PCK sl_pck;
2060 :
2061 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] SL Packet in PES for %d - ES ID %d\n", pes->pid, pes->mpeg4_es_id));
2062 :
2063 0 : if (pes->pck_data_len > len) {
2064 0 : sl_pck.data = (char *)pes->pck_data + len;
2065 0 : sl_pck.data_len = pes->pck_data_len - len;
2066 0 : sl_pck.stream = (GF_M2TS_ES *)pes;
2067 0 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SL_PCK, &sl_pck);
2068 : } else {
2069 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Bad SL Packet size: (%d indicated < %d header)\n", pes->pid, pes->pck_data_len, len));
2070 : }
2071 25797 : } else if (pes->reframe) {
2072 : u32 remain = 0;
2073 : u32 offset = len;
2074 :
2075 25797 : if (pesh.pck_len && (pesh.pck_len-3-pesh.hdr_data_len != pes->pck_data_len-len)) {
2076 25 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PES payload size %d but received %d bytes\n", pes->pid, (u32) ( pesh.pck_len-3-pesh.hdr_data_len), pes->pck_data_len-len));
2077 : }
2078 : //copy over the remaining of previous PES payload before start of this PES payload
2079 25797 : if (pes->prev_data_len) {
2080 0 : if (pes->prev_data_len < len) {
2081 0 : offset = len - pes->prev_data_len;
2082 0 : memcpy(pes->pck_data + offset, pes->prev_data, pes->prev_data_len);
2083 : } else {
2084 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PES reassembly buffer overflow (%d bytes not processed from previous PES) - discarding prev data\n", pes->pid, pes->prev_data_len ));
2085 : }
2086 : }
2087 :
2088 25797 : if (!pes->temi_pending && pes->temi_tc_desc_len) {
2089 460 : gf_m2ts_store_temi(ts, pes);
2090 : }
2091 :
2092 25797 : if (pes->temi_pending) {
2093 1782 : pes->temi_pending = 0;
2094 1782 : pes->temi_tc.pes_pts = pes->PTS;
2095 1782 : pes->temi_tc.pid = pes->pid;
2096 1782 : if (ts->on_event)
2097 1776 : ts->on_event(ts, GF_M2TS_EVT_TEMI_TIMECODE, &pes->temi_tc);
2098 : }
2099 :
2100 25797 : if (! ts->seek_mode)
2101 21687 : remain = pes->reframe(ts, pes, same_pts, pes->pck_data+offset, pes->pck_data_len-offset, &pesh);
2102 :
2103 : //CLEANUP alloc stuff
2104 25797 : if (pes->prev_data) gf_free(pes->prev_data);
2105 25797 : pes->prev_data = NULL;
2106 25797 : pes->prev_data_len = 0;
2107 25797 : if (remain) {
2108 0 : pes->prev_data = gf_malloc(sizeof(char)*remain);
2109 : assert(pes->pck_data_len >= remain);
2110 0 : memcpy(pes->prev_data, pes->pck_data + pes->pck_data_len - remain, remain);
2111 0 : pes->prev_data_len = remain;
2112 : }
2113 : }
2114 65 : } else if (pes->pck_data_len) {
2115 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Bad PES Header, discarding packet (maybe stream is encrypted ?)\n", pes->pid));
2116 : }
2117 25862 : pes->pck_data_len = 0;
2118 25862 : pes->pes_len = 0;
2119 25862 : pes->rap = 0;
2120 : }
2121 :
2122 964050 : static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Header *hdr, unsigned char *data, u32 data_size, GF_M2TS_AdaptationField *paf)
2123 : {
2124 : u8 expect_cc;
2125 : Bool disc=0;
2126 : Bool flush_pes = 0;
2127 :
2128 : /*duplicated packet, NOT A DISCONTINUITY, we should discard the packet - however we may encounter this configuration in DASH at segment boundaries.
2129 : If payload start is set, ignore duplication*/
2130 964050 : if (hdr->continuity_counter==pes->cc) {
2131 0 : if (!hdr->payload_start || (hdr->adaptation_field!=3) ) {
2132 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Duplicated Packet found (CC %d) - skipping\n", pes->pid, pes->cc));
2133 : return;
2134 : }
2135 : } else {
2136 964050 : expect_cc = (pes->cc<0) ? hdr->continuity_counter : (pes->cc + 1) & 0xf;
2137 964050 : if (expect_cc != hdr->continuity_counter)
2138 : disc = 1;
2139 : }
2140 964050 : pes->cc = hdr->continuity_counter;
2141 :
2142 964050 : if (disc) {
2143 57 : if (pes->flags & GF_M2TS_ES_IGNORE_NEXT_DISCONTINUITY) {
2144 0 : pes->flags &= ~GF_M2TS_ES_IGNORE_NEXT_DISCONTINUITY;
2145 : disc = 0;
2146 : }
2147 : if (disc) {
2148 57 : if (hdr->payload_start) {
2149 0 : if (pes->pck_data_len) {
2150 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Packet discontinuity (%d expected - got %d) - may have lost end of previous PES\n", pes->pid, expect_cc, hdr->continuity_counter));
2151 : }
2152 : } else {
2153 57 : if (pes->pck_data_len) {
2154 9 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Packet discontinuity (%d expected - got %d) - trashing PES packet\n", pes->pid, expect_cc, hdr->continuity_counter));
2155 : }
2156 57 : pes->pck_data_len = 0;
2157 57 : pes->pes_len = 0;
2158 57 : pes->cc = -1;
2159 57 : return;
2160 : }
2161 : }
2162 : }
2163 :
2164 963993 : if (!pes->reframe) return;
2165 :
2166 963993 : if (hdr->payload_start) {
2167 : flush_pes = 1;
2168 25902 : pes->pes_start_packet_number = ts->pck_number;
2169 25902 : pes->before_last_pcr_value = pes->program->before_last_pcr_value;
2170 25902 : pes->before_last_pcr_value_pck_number = pes->program->before_last_pcr_value_pck_number;
2171 25902 : pes->last_pcr_value = pes->program->last_pcr_value;
2172 25902 : pes->last_pcr_value_pck_number = pes->program->last_pcr_value_pck_number;
2173 938091 : } else if (pes->pes_len && (pes->pck_data_len + data_size == pes->pes_len + 6)) {
2174 : /* 6 = startcode+stream_id+length*/
2175 : /*reassemble pes*/
2176 15186 : if (pes->pck_data_len + data_size > pes->pck_alloc_len) {
2177 413 : pes->pck_alloc_len = pes->pck_data_len + data_size;
2178 413 : pes->pck_data = (u8*)gf_realloc(pes->pck_data, pes->pck_alloc_len);
2179 : }
2180 15186 : memcpy(pes->pck_data+pes->pck_data_len, data, data_size);
2181 15186 : pes->pck_data_len += data_size;
2182 : /*force discard*/
2183 : data_size = 0;
2184 : flush_pes = 1;
2185 : }
2186 :
2187 : /*PES first fragment: flush previous packet*/
2188 41088 : if (flush_pes && pes->pck_data_len) {
2189 22022 : gf_m2ts_flush_pes(ts, pes);
2190 22022 : if (!data_size) return;
2191 : }
2192 : /*we need to wait for first packet of PES*/
2193 948807 : if (!pes->pck_data_len && !hdr->payload_start) {
2194 6429 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Waiting for PES header, trashing data\n", hdr->pid));
2195 : return;
2196 : }
2197 : /*reassemble*/
2198 942378 : if (pes->pck_data_len + data_size > pes->pck_alloc_len ) {
2199 30989 : pes->pck_alloc_len = pes->pck_data_len + data_size;
2200 30989 : pes->pck_data = (u8*)gf_realloc(pes->pck_data, pes->pck_alloc_len);
2201 : }
2202 942378 : memcpy(pes->pck_data + pes->pck_data_len, data, data_size);
2203 942378 : pes->pck_data_len += data_size;
2204 :
2205 942378 : if (paf && paf->random_access_indicator) pes->rap = 1;
2206 942378 : if (hdr->payload_start && !pes->pes_len && (pes->pck_data_len>=6)) {
2207 25902 : pes->pes_len = (pes->pck_data[4]<<8) | pes->pck_data[5];
2208 25902 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Got PES packet len %d\n", pes->pid, pes->pes_len));
2209 :
2210 25902 : if (pes->pes_len + 6 == pes->pck_data_len) {
2211 3723 : gf_m2ts_flush_pes(ts, pes);
2212 : }
2213 : }
2214 : }
2215 :
2216 34 : void gf_m2ts_flush_all(GF_M2TS_Demuxer *ts)
2217 : {
2218 : u32 i;
2219 278562 : for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {
2220 278528 : GF_M2TS_ES *stream = ts->ess[i];
2221 278528 : if (stream && (stream->flags & GF_M2TS_ES_IS_PES)) {
2222 117 : gf_m2ts_flush_pes(ts, (GF_M2TS_PES *) stream);
2223 : }
2224 : }
2225 34 : }
2226 :
2227 :
2228 47443 : static void gf_m2ts_get_adaptation_field(GF_M2TS_Demuxer *ts, GF_M2TS_AdaptationField *paf, u8 *data, u32 size, u32 pid)
2229 : {
2230 : unsigned char *af_extension;
2231 47443 : paf->discontinuity_indicator = (data[0] & 0x80) ? 1 : 0;
2232 47443 : paf->random_access_indicator = (data[0] & 0x40) ? 1 : 0;
2233 47443 : paf->priority_indicator = (data[0] & 0x20) ? 1 : 0;
2234 47443 : paf->PCR_flag = (data[0] & 0x10) ? 1 : 0;
2235 47443 : paf->OPCR_flag = (data[0] & 0x8) ? 1 : 0;
2236 47443 : paf->splicing_point_flag = (data[0] & 0x4) ? 1 : 0;
2237 47443 : paf->transport_private_data_flag = (data[0] & 0x2) ? 1 : 0;
2238 47443 : paf->adaptation_field_extension_flag = (data[0] & 0x1) ? 1 : 0;
2239 :
2240 47443 : af_extension = data + 1;
2241 :
2242 47443 : if (paf->PCR_flag == 1) {
2243 17744 : u32 base = ((u32)data[1] << 24) | ((u32)data[2] << 16) | ((u32)data[3] << 8) | (u32) data[4];
2244 17744 : u64 PCR = (u64) base;
2245 17744 : paf->PCR_base = (PCR << 1) | (data[5] >> 7);
2246 17744 : paf->PCR_ext = ((data[5] & 1) << 8) | data[6];
2247 17744 : af_extension += 6;
2248 : }
2249 :
2250 47443 : if (paf->adaptation_field_extension_flag) {
2251 : u32 afext_bytes;
2252 : Bool ltw_flag, pwr_flag, seamless_flag, af_desc_not_present;
2253 1826 : if (paf->OPCR_flag) {
2254 0 : af_extension += 6;
2255 : }
2256 1826 : if (paf->splicing_point_flag) {
2257 12 : af_extension += 1;
2258 : }
2259 1826 : if (paf->transport_private_data_flag) {
2260 11 : u32 priv_bytes = af_extension[0];
2261 11 : af_extension += 1 + priv_bytes;
2262 : }
2263 :
2264 1826 : if ((u32)(af_extension-data) >= size) {
2265 11 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Bad Adaptation Extension found\n", pid));
2266 : return;
2267 : }
2268 1815 : afext_bytes = af_extension[0];
2269 1815 : ltw_flag = (af_extension[1] & 0x80) ? 1 : 0;
2270 1815 : pwr_flag = (af_extension[1] & 0x40) ? 1 : 0;
2271 1815 : seamless_flag = (af_extension[1] & 0x20) ? 1 : 0;
2272 1815 : af_desc_not_present = (af_extension[1] & 0x10) ? 1 : 0;
2273 1815 : af_extension += 2;
2274 1815 : if (!afext_bytes) {
2275 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Bad Adaptation Extension found\n", pid));
2276 : return;
2277 : }
2278 1815 : afext_bytes-=1;
2279 1815 : if (ltw_flag) {
2280 0 : af_extension += 2;
2281 0 : if (afext_bytes<2) {
2282 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Bad Adaptation Extension found\n", pid));
2283 : return;
2284 : }
2285 0 : afext_bytes-=2;
2286 : }
2287 1815 : if (pwr_flag) {
2288 1 : af_extension += 3;
2289 1 : if (afext_bytes<3) {
2290 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Bad Adaptation Extension found\n", pid));
2291 : return;
2292 : }
2293 1 : afext_bytes-=3;
2294 : }
2295 1815 : if (seamless_flag) {
2296 1 : af_extension += 3;
2297 1 : if (afext_bytes<3) {
2298 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Bad Adaptation Extension found\n", pid));
2299 : return;
2300 : }
2301 1 : afext_bytes-=3;
2302 : }
2303 :
2304 1815 : if (! af_desc_not_present) {
2305 5041 : while (afext_bytes) {
2306 : GF_BitStream *bs;
2307 : char *desc;
2308 3227 : u8 desc_tag = af_extension[0];
2309 3227 : u8 desc_len = af_extension[1];
2310 3227 : if (!desc_len || (u32) desc_len+2 > afext_bytes) {
2311 1 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Bad Adaptation Descriptor found (tag %d) size is %d but only %d bytes available\n", pid, desc_tag, desc_len, afext_bytes));
2312 : break;
2313 : }
2314 3226 : desc = (char *) af_extension+2;
2315 :
2316 3226 : bs = gf_bs_new(desc, desc_len, GF_BITSTREAM_READ);
2317 3226 : switch (desc_tag) {
2318 : case GF_M2TS_AFDESC_LOCATION_DESCRIPTOR:
2319 : {
2320 : Bool use_base_temi_url;
2321 : char URL[255];
2322 : GF_M2TS_TemiLocationDescriptor temi_loc;
2323 : memset(&temi_loc, 0, sizeof(GF_M2TS_TemiLocationDescriptor) );
2324 64 : temi_loc.pid = pid;
2325 64 : temi_loc.reload_external = gf_bs_read_int(bs, 1);
2326 64 : temi_loc.is_announce = gf_bs_read_int(bs, 1);
2327 64 : temi_loc.is_splicing = gf_bs_read_int(bs, 1);
2328 64 : use_base_temi_url = gf_bs_read_int(bs, 1);
2329 64 : gf_bs_read_int(bs, 5); //reserved
2330 64 : temi_loc.timeline_id = gf_bs_read_int(bs, 7);
2331 64 : if (!use_base_temi_url) {
2332 : char *_url = URL;
2333 64 : u8 scheme = gf_bs_read_int(bs, 8);
2334 64 : u8 url_len = gf_bs_read_int(bs, 8);
2335 64 : switch (scheme) {
2336 : case 1:
2337 : strcpy(URL, "http://");
2338 : _url = URL+7;
2339 64 : break;
2340 : case 2:
2341 : strcpy(URL, "https://");
2342 : _url = URL+8;
2343 0 : break;
2344 : }
2345 64 : gf_bs_read_data(bs, _url, url_len);
2346 64 : _url[url_len] = 0;
2347 : }
2348 64 : temi_loc.external_URL = URL;
2349 :
2350 64 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d AF Location descriptor found - URL %s\n", pid, URL));
2351 64 : if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TEMI_LOCATION, &temi_loc);
2352 : }
2353 64 : break;
2354 3162 : case GF_M2TS_AFDESC_TIMELINE_DESCRIPTOR:
2355 3162 : if (ts->ess[pid] && (ts->ess[pid]->flags & GF_M2TS_ES_IS_PES)) {
2356 : GF_M2TS_PES *pes = (GF_M2TS_PES *) ts->ess[pid];
2357 :
2358 3162 : if (pes->temi_tc_desc_len)
2359 2680 : gf_m2ts_store_temi(ts, pes);
2360 :
2361 3162 : if (pes->temi_tc_desc_alloc_size < desc_len) {
2362 24 : pes->temi_tc_desc = gf_realloc(pes->temi_tc_desc, desc_len);
2363 24 : pes->temi_tc_desc_alloc_size = desc_len;
2364 : }
2365 3162 : memcpy(pes->temi_tc_desc, desc, desc_len);
2366 3162 : pes->temi_tc_desc_len = desc_len;
2367 :
2368 3162 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d AF Timeline descriptor found\n", pid));
2369 : }
2370 : break;
2371 : }
2372 3226 : gf_bs_del(bs);
2373 :
2374 3226 : af_extension += 2+desc_len;
2375 3226 : afext_bytes -= 2+desc_len;
2376 : }
2377 :
2378 : }
2379 : }
2380 :
2381 47432 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Adaptation Field found: Discontinuity %d - RAP %d - PCR: "LLD"\n", pid, paf->discontinuity_indicator, paf->random_access_indicator, paf->PCR_flag ? paf->PCR_base * 300 + paf->PCR_ext : 0));
2382 : }
2383 :
2384 1215026 : static GF_Err gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data)
2385 : {
2386 : GF_M2TS_ES *es;
2387 : GF_M2TS_Header hdr;
2388 : GF_M2TS_AdaptationField af, *paf;
2389 : u32 payload_size, af_size;
2390 : u32 pos = 0;
2391 :
2392 1215026 : ts->pck_number++;
2393 :
2394 : /* read TS packet header*/
2395 1215026 : hdr.sync = data[0];
2396 1215026 : if (hdr.sync != 0x47) {
2397 5669 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d does not start with sync marker\n", ts->pck_number));
2398 : return GF_CORRUPTED_DATA;
2399 : }
2400 1209357 : hdr.error = (data[1] & 0x80) ? 1 : 0;
2401 1209357 : hdr.payload_start = (data[1] & 0x40) ? 1 : 0;
2402 1209357 : hdr.priority = (data[1] & 0x20) ? 1 : 0;
2403 1209357 : hdr.pid = ( (data[1]&0x1f) << 8) | data[2];
2404 1209357 : hdr.scrambling_ctrl = (data[3] >> 6) & 0x3;
2405 1209357 : hdr.adaptation_field = (data[3] >> 4) & 0x3;
2406 1209357 : hdr.continuity_counter = data[3] & 0xf;
2407 :
2408 1209357 : if (hdr.error) {
2409 478 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d has error (PID could be %d)\n", ts->pck_number, hdr.pid));
2410 : return GF_CORRUPTED_DATA;
2411 : }
2412 : //#if DEBUG_TS_PACKET
2413 1208879 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d PID %d CC %d Encrypted %d\n", ts->pck_number, hdr.pid, hdr.continuity_counter, hdr.scrambling_ctrl));
2414 : //#endif
2415 :
2416 1208879 : if (hdr.scrambling_ctrl) {
2417 : //TODO add decyphering
2418 594 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d is scrambled - not supported\n", ts->pck_number, hdr.pid));
2419 : return GF_NOT_SUPPORTED;
2420 : }
2421 :
2422 : paf = NULL;
2423 : payload_size = 184;
2424 : pos = 4;
2425 1208285 : switch (hdr.adaptation_field) {
2426 : /*adaptation+data*/
2427 46638 : case 3:
2428 46638 : af_size = data[4];
2429 46638 : if (af_size>183) {
2430 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d AF field larger than 183 !\n", ts->pck_number));
2431 : //error
2432 : return GF_CORRUPTED_DATA;
2433 : }
2434 : paf = ⁡
2435 : memset(paf, 0, sizeof(GF_M2TS_AdaptationField));
2436 : //this will stop you when processing invalid (yet existing) mpeg2ts streams in debug
2437 : assert( af_size<=183);
2438 : if (af_size>183)
2439 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d Detected wrong adaption field size %u when control value is 3\n", ts->pck_number, af_size));
2440 46638 : if (af_size) gf_m2ts_get_adaptation_field(ts, paf, data+5, af_size, hdr.pid);
2441 46638 : pos += 1+af_size;
2442 46638 : payload_size = 183 - af_size;
2443 46638 : break;
2444 : /*adaptation only - still process in case of PCR*/
2445 906 : case 2:
2446 906 : af_size = data[4];
2447 906 : if (af_size != 183) {
2448 89 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet %d AF size is %d when it must be 183 for AF type 2\n", ts->pck_number, af_size));
2449 : return GF_CORRUPTED_DATA;
2450 : }
2451 : paf = ⁡
2452 : memset(paf, 0, sizeof(GF_M2TS_AdaptationField));
2453 817 : gf_m2ts_get_adaptation_field(ts, paf, data+5, af_size, hdr.pid);
2454 : payload_size = 0;
2455 : /*no payload and no PCR, return*/
2456 817 : if (!paf->PCR_flag)
2457 : return GF_OK;
2458 : break;
2459 : /*reserved*/
2460 : case 0:
2461 : return GF_OK;
2462 : default:
2463 : break;
2464 : }
2465 1207955 : data += pos;
2466 :
2467 : /*PAT*/
2468 1207955 : if (hdr.pid == GF_M2TS_PID_PAT) {
2469 3341 : gf_m2ts_gather_section(ts, ts->pat, NULL, &hdr, data, payload_size);
2470 3341 : return GF_OK;
2471 : }
2472 :
2473 1204614 : es = ts->ess[hdr.pid];
2474 : //we work in split mode
2475 1204614 : if (ts->split_mode) {
2476 : GF_M2TS_TSPCK tspck;
2477 : //process PMT table
2478 149859 : if (es && (es->flags & GF_M2TS_ES_IS_PMT)) {
2479 : GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
2480 633 : if (ses->sec) gf_m2ts_gather_section(ts, ses->sec, ses, &hdr, data, payload_size);
2481 : }
2482 : //and forward every packet other than PAT
2483 149859 : tspck.stream = es;
2484 149859 : tspck.pid = hdr.pid;
2485 149859 : tspck.data = data - pos;
2486 149859 : ts->on_event(ts, GF_M2TS_EVT_PCK, &tspck);
2487 : return GF_OK;
2488 : }
2489 :
2490 1054755 : if (hdr.pid == GF_M2TS_PID_CAT) {
2491 354 : gf_m2ts_gather_section(ts, ts->cat, NULL, &hdr, data, payload_size);
2492 354 : return GF_OK;
2493 : }
2494 :
2495 1054401 : if (paf && paf->PCR_flag) {
2496 16127 : if (!es) {
2497 : u32 i, j;
2498 1239 : for(i=0; i<gf_list_count(ts->programs); i++) {
2499 : GF_M2TS_PES *first_pes = NULL;
2500 546 : GF_M2TS_Program *program = (GF_M2TS_Program *)gf_list_get(ts->programs,i);
2501 546 : if(program->pcr_pid != hdr.pid) continue;
2502 0 : for (j=0; j<gf_list_count(program->streams); j++) {
2503 0 : GF_M2TS_PES *pes = (GF_M2TS_PES *) gf_list_get(program->streams, j);
2504 0 : if (pes->flags & GF_M2TS_INHERIT_PCR) {
2505 0 : ts->ess[hdr.pid] = (GF_M2TS_ES *) pes;
2506 0 : pes->flags |= GF_M2TS_FAKE_PCR;
2507 0 : break;
2508 : }
2509 0 : if (pes->flags & GF_M2TS_ES_IS_PES) {
2510 : first_pes = pes;
2511 : }
2512 : }
2513 : //non found, use the first media stream as a PCR destination - Q: is it legal to have PCR only streams not declared in PMT ?
2514 0 : if (!es && first_pes) {
2515 : es = (GF_M2TS_ES *) first_pes;
2516 0 : first_pes->flags |= GF_M2TS_FAKE_PCR;
2517 : }
2518 : break;
2519 : }
2520 147 : if (!es)
2521 147 : es = ts->ess[hdr.pid];
2522 : }
2523 16127 : if (es) {
2524 : GF_M2TS_PES_PCK pck;
2525 : s64 prev_diff_in_us;
2526 : Bool discontinuity;
2527 : s32 cc = -1;
2528 :
2529 15980 : if (es->flags & GF_M2TS_FAKE_PCR) {
2530 0 : cc = es->program->pcr_cc;
2531 0 : es->program->pcr_cc = hdr.continuity_counter;
2532 : }
2533 15980 : else if (es->flags & GF_M2TS_ES_IS_PES) cc = ((GF_M2TS_PES*)es)->cc;
2534 0 : else if (((GF_M2TS_SECTION_ES*)es)->sec) cc = ((GF_M2TS_SECTION_ES*)es)->sec->cc;
2535 :
2536 15980 : discontinuity = paf->discontinuity_indicator;
2537 15980 : if ((cc>=0) && es->program->before_last_pcr_value) {
2538 : //no increment of CC if AF only packet
2539 15629 : if (hdr.adaptation_field == 2) {
2540 564 : if (hdr.continuity_counter != cc) {
2541 : discontinuity = GF_TRUE;
2542 : }
2543 15065 : } else if (hdr.continuity_counter != ((cc + 1) & 0xF)) {
2544 : discontinuity = GF_TRUE;
2545 : }
2546 : }
2547 :
2548 : memset(&pck, 0, sizeof(GF_M2TS_PES_PCK));
2549 15980 : prev_diff_in_us = (s64) (es->program->last_pcr_value /27- es->program->before_last_pcr_value/27);
2550 15980 : es->program->before_last_pcr_value = es->program->last_pcr_value;
2551 15980 : es->program->before_last_pcr_value_pck_number = es->program->last_pcr_value_pck_number;
2552 15980 : es->program->last_pcr_value_pck_number = ts->pck_number;
2553 15980 : es->program->last_pcr_value = paf->PCR_base * 300 + paf->PCR_ext;
2554 15980 : if (!es->program->last_pcr_value) es->program->last_pcr_value = 1;
2555 :
2556 15980 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PCR found "LLU" ("LLU" at 90kHz) - PCR diff is %d us\n", hdr.pid, es->program->last_pcr_value, es->program->last_pcr_value/300, (s32) (es->program->last_pcr_value - es->program->before_last_pcr_value)/27 ));
2557 :
2558 15980 : pck.PTS = es->program->last_pcr_value;
2559 15980 : pck.stream = (GF_M2TS_PES *)es;
2560 :
2561 : //try to ignore all discontinuities that are less than 200 ms (seen in some HLS setup ...)
2562 15980 : if (discontinuity) {
2563 0 : s64 diff_in_us = (s64) (es->program->last_pcr_value - es->program->before_last_pcr_value) / 27;
2564 0 : u64 diff = ABS(diff_in_us - prev_diff_in_us);
2565 :
2566 0 : if ((diff_in_us<0) && (diff_in_us >= -200000)) {
2567 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d new PCR, with discontinuity signaled, is less than previously received PCR (diff %d us) but not too large, trying to ignore discontinuity\n", hdr.pid, diff_in_us));
2568 : }
2569 :
2570 : //ignore PCR discontinuity indicator if PCR found is larger than previously received PCR and diffence between PCR before and after discontinuity indicator is smaller than 50ms
2571 0 : else if ((diff_in_us > 0) && (diff < 200000)) {
2572 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PCR discontinuity signaled but diff is small (diff %d us - PCR diff %d vs prev PCR diff %d) - ignore it\n", hdr.pid, diff, diff_in_us, prev_diff_in_us));
2573 0 : } else if (paf->discontinuity_indicator) {
2574 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PCR discontinuity signaled (diff %d us - PCR diff %d vs prev PCR diff %d)\n", hdr.pid, diff, diff_in_us, prev_diff_in_us));
2575 0 : pck.flags = GF_M2TS_PES_PCK_DISCONTINUITY;
2576 : } else {
2577 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PCR discontinuity not signaled (diff %d us - PCR diff %d vs prev PCR diff %d)\n", hdr.pid, diff, diff_in_us, prev_diff_in_us));
2578 0 : pck.flags = GF_M2TS_PES_PCK_DISCONTINUITY;
2579 : }
2580 : }
2581 15980 : else if ( (es->program->last_pcr_value < es->program->before_last_pcr_value) ) {
2582 3 : s64 diff_in_us = (s64) (es->program->last_pcr_value - es->program->before_last_pcr_value) / 27;
2583 : //if less than 200 ms before PCR loop at the last PCR, this is a PCR loop
2584 3 : if (GF_M2TS_MAX_PCR - es->program->before_last_pcr_value < 5400000 /*2*2700000*/) {
2585 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PCR loop found from "LLU" to "LLU" \n", hdr.pid, es->program->before_last_pcr_value, es->program->last_pcr_value));
2586 3 : } else if ((diff_in_us<0) && (diff_in_us >= -200000)) {
2587 3 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d new PCR, without discontinuity signaled, is less than previously received PCR (diff %d us) but not too large, trying to ignore discontinuity\n", hdr.pid, diff_in_us));
2588 : } else {
2589 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d PCR found "LLU" is less than previously received PCR "LLU" (PCR diff %g sec) but no discontinuity signaled\n", hdr.pid, es->program->last_pcr_value, es->program->before_last_pcr_value, (GF_M2TS_MAX_PCR - es->program->before_last_pcr_value + es->program->last_pcr_value) / 27000000.0));
2590 :
2591 0 : pck.flags = GF_M2TS_PES_PCK_DISCONTINUITY;
2592 : }
2593 : }
2594 :
2595 15980 : if (pck.flags & GF_M2TS_PES_PCK_DISCONTINUITY) {
2596 0 : gf_m2ts_reset_parsers_for_program(ts, es->program);
2597 : }
2598 :
2599 15980 : if (ts->on_event) {
2600 15874 : ts->on_event(ts, GF_M2TS_EVT_PES_PCR, &pck);
2601 : }
2602 : }
2603 : }
2604 :
2605 : /*check for DVB reserved PIDs*/
2606 1054401 : if (!es) {
2607 81817 : if (hdr.pid == GF_M2TS_PID_SDT_BAT_ST) {
2608 104 : gf_m2ts_gather_section(ts, ts->sdt, NULL, &hdr, data, payload_size);
2609 104 : return GF_OK;
2610 81713 : } else if (hdr.pid == GF_M2TS_PID_NIT_ST) {
2611 : /*ignore them, unused at application level*/
2612 117 : gf_m2ts_gather_section(ts, ts->nit, NULL, &hdr, data, payload_size);
2613 117 : return GF_OK;
2614 81596 : } else if (hdr.pid == GF_M2TS_PID_EIT_ST_CIT) {
2615 : /* ignore EIT messages for the moment */
2616 552 : gf_m2ts_gather_section(ts, ts->eit, NULL, &hdr, data, payload_size);
2617 552 : return GF_OK;
2618 81044 : } else if (hdr.pid == GF_M2TS_PID_TDT_TOT_ST) {
2619 0 : gf_m2ts_gather_section(ts, ts->tdt_tot, NULL, &hdr, data, payload_size);
2620 : } else {
2621 : /* ignore packet */
2622 : }
2623 972584 : } else if (es->flags & GF_M2TS_ES_IS_SECTION) { /* The stream uses sections to carry its payload */
2624 : GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
2625 5660 : if (ses->sec) gf_m2ts_gather_section(ts, ses->sec, ses, &hdr, data, payload_size);
2626 : } else {
2627 : GF_M2TS_PES *pes = (GF_M2TS_PES *)es;
2628 : /* regular stream using PES packets */
2629 966924 : if (pes->reframe && payload_size) gf_m2ts_process_pes(ts, pes, &hdr, data, payload_size, paf);
2630 : }
2631 :
2632 : return GF_OK;
2633 : }
2634 :
2635 : GF_EXPORT
2636 84223 : GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, u8 *data, u32 data_size)
2637 : {
2638 : GF_Err e=GF_OK;
2639 : u32 pos, pck_size;
2640 : Bool is_align = 1;
2641 :
2642 84223 : if (ts->buffer_size) {
2643 : //we are sync, copy remaining bytes
2644 73270 : if ( (ts->buffer[0]==0x47) && (ts->buffer_size<200)) {
2645 : u32 copy_size;
2646 36635 : pck_size = ts->prefix_present ? 192 : 188;
2647 :
2648 36635 : if (ts->alloc_size < 200) {
2649 0 : ts->alloc_size = 200;
2650 0 : ts->buffer = (char*)gf_realloc(ts->buffer, sizeof(char)*ts->alloc_size);
2651 : }
2652 36635 : copy_size = pck_size - ts->buffer_size;
2653 36635 : if (copy_size > data_size) {
2654 0 : memcpy(ts->buffer + ts->buffer_size, data, data_size);
2655 0 : ts->buffer_size += data_size;
2656 0 : return GF_OK;
2657 : }
2658 36635 : memcpy(ts->buffer + ts->buffer_size, data, copy_size);
2659 36635 : e |= gf_m2ts_process_packet(ts, (unsigned char *)ts->buffer);
2660 36635 : data += copy_size;
2661 36635 : data_size = data_size - copy_size;
2662 : assert((s32)data_size >= 0);
2663 : }
2664 : //not sync, copy over the complete buffer
2665 : else {
2666 0 : if (ts->alloc_size < ts->buffer_size+data_size) {
2667 0 : ts->alloc_size = ts->buffer_size+data_size;
2668 0 : ts->buffer = (char*)gf_realloc(ts->buffer, sizeof(char)*ts->alloc_size);
2669 : }
2670 0 : memcpy(ts->buffer + ts->buffer_size, data, sizeof(char)*data_size);
2671 0 : ts->buffer_size += data_size;
2672 : is_align = 0;
2673 0 : data = ts->buffer;
2674 : data_size = ts->buffer_size;
2675 : }
2676 : }
2677 :
2678 : /*sync input data*/
2679 84223 : pos = gf_m2ts_sync(ts, data, data_size, is_align);
2680 84223 : if (pos==data_size) {
2681 2415 : if (is_align) {
2682 2415 : if (ts->alloc_size<data_size) {
2683 2413 : ts->buffer = (char*)gf_realloc(ts->buffer, sizeof(char)*data_size);
2684 2413 : ts->alloc_size = data_size;
2685 : }
2686 2415 : memcpy(ts->buffer, data, sizeof(char)*data_size);
2687 2415 : ts->buffer_size = data_size;
2688 : }
2689 : return GF_OK;
2690 : }
2691 81808 : pck_size = ts->prefix_present ? 192 : 188;
2692 : for (;;) {
2693 : /*wait for a complete packet*/
2694 2438590 : if (data_size < pos + pck_size) {
2695 81808 : ts->buffer_size = data_size - pos;
2696 81808 : data += pos;
2697 81808 : if (!ts->buffer_size) {
2698 : return e;
2699 : }
2700 : assert(ts->buffer_size<pck_size);
2701 :
2702 37213 : if (is_align) {
2703 : u32 s = ts->buffer_size;
2704 37213 : if (s<200) s = 200;
2705 :
2706 37213 : if (ts->alloc_size < s) {
2707 576 : ts->alloc_size = s;
2708 576 : ts->buffer = (char*)gf_realloc(ts->buffer, sizeof(char)*ts->alloc_size);
2709 : }
2710 37213 : memcpy(ts->buffer, data, sizeof(char)*ts->buffer_size);
2711 : } else {
2712 0 : memmove(ts->buffer, data, sizeof(char)*ts->buffer_size);
2713 : }
2714 : return e;
2715 : }
2716 : /*process*/
2717 1178391 : e |= gf_m2ts_process_packet(ts, (unsigned char *)data + pos);
2718 : pos += pck_size;
2719 : }
2720 : return e;
2721 : }
2722 :
2723 : //unused
2724 : #if 0
2725 : GF_ESD *gf_m2ts_get_esd(GF_M2TS_ES *es)
2726 : {
2727 : GF_ESD *esd;
2728 : u32 k, esd_count;
2729 :
2730 : esd = NULL;
2731 : if (es->program->pmt_iod && es->program->pmt_iod->ESDescriptors) {
2732 : esd_count = gf_list_count(es->program->pmt_iod->ESDescriptors);
2733 : for (k = 0; k < esd_count; k++) {
2734 : GF_ESD *esd_tmp = (GF_ESD *)gf_list_get(es->program->pmt_iod->ESDescriptors, k);
2735 : if (esd_tmp->ESID != es->mpeg4_es_id) continue;
2736 : esd = esd_tmp;
2737 : break;
2738 : }
2739 : }
2740 :
2741 : if (!esd && es->program->additional_ods) {
2742 : u32 od_count, od_index;
2743 : od_count = gf_list_count(es->program->additional_ods);
2744 : for (od_index = 0; od_index < od_count; od_index++) {
2745 : GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(es->program->additional_ods, od_index);
2746 : esd_count = gf_list_count(od->ESDescriptors);
2747 : for (k = 0; k < esd_count; k++) {
2748 : GF_ESD *esd_tmp = (GF_ESD *)gf_list_get(od->ESDescriptors, k);
2749 : if (esd_tmp->ESID != es->mpeg4_es_id) continue;
2750 : esd = esd_tmp;
2751 : break;
2752 : }
2753 : }
2754 : }
2755 :
2756 : return esd;
2757 : }
2758 : void gf_m2ts_set_segment_switch(GF_M2TS_Demuxer *ts)
2759 : {
2760 : u32 i;
2761 : for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {
2762 : GF_M2TS_ES *es = (GF_M2TS_ES *) ts->ess[i];
2763 : if (!es) continue;
2764 : es->flags |= GF_M2TS_ES_IGNORE_NEXT_DISCONTINUITY;
2765 : }
2766 : }
2767 :
2768 :
2769 : #endif
2770 :
2771 :
2772 : GF_EXPORT
2773 32 : void gf_m2ts_reset_parsers_for_program(GF_M2TS_Demuxer *ts, GF_M2TS_Program *prog)
2774 : {
2775 : u32 i;
2776 :
2777 262176 : for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {
2778 262144 : GF_M2TS_ES *es = (GF_M2TS_ES *) ts->ess[i];
2779 262144 : if (!es) continue;
2780 167 : if (prog && (es->program != prog) ) continue;
2781 :
2782 167 : if (es->flags & GF_M2TS_ES_IS_SECTION) {
2783 : GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
2784 55 : gf_m2ts_section_filter_reset(ses->sec);
2785 : } else {
2786 : GF_M2TS_PES *pes = (GF_M2TS_PES *)es;
2787 112 : if (pes->pid==pes->program->pmt_pid) continue;
2788 112 : pes->cc = -1;
2789 112 : pes->pck_data_len = 0;
2790 112 : if (pes->prev_data) gf_free(pes->prev_data);
2791 112 : pes->prev_data = NULL;
2792 112 : pes->prev_data_len = 0;
2793 112 : pes->PTS = pes->DTS = 0;
2794 : // pes->prev_PTS = 0;
2795 : // pes->first_dts = 0;
2796 112 : pes->pes_len = pes->pes_end_packet_number = pes->pes_start_packet_number = 0;
2797 112 : if (pes->temi_tc_desc) gf_free(pes->temi_tc_desc);
2798 112 : pes->temi_tc_desc = NULL;
2799 112 : pes->temi_tc_desc_len = pes->temi_tc_desc_alloc_size = 0;
2800 :
2801 112 : pes->before_last_pcr_value = pes->before_last_pcr_value_pck_number = 0;
2802 112 : pes->last_pcr_value = pes->last_pcr_value_pck_number = 0;
2803 112 : if (pes->program->pcr_pid==pes->pid) {
2804 47 : pes->program->last_pcr_value = pes->program->last_pcr_value_pck_number = 0;
2805 47 : pes->program->before_last_pcr_value = pes->program->before_last_pcr_value_pck_number = 0;
2806 : }
2807 : }
2808 : }
2809 32 : }
2810 :
2811 : GF_EXPORT
2812 32 : void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts)
2813 : {
2814 32 : gf_m2ts_reset_parsers_for_program(ts, NULL);
2815 :
2816 32 : ts->pck_number = 0;
2817 32 : ts->buffer_size = 0;
2818 :
2819 32 : gf_m2ts_section_filter_reset(ts->cat);
2820 32 : gf_m2ts_section_filter_reset(ts->pat);
2821 32 : gf_m2ts_section_filter_reset(ts->sdt);
2822 32 : gf_m2ts_section_filter_reset(ts->nit);
2823 32 : gf_m2ts_section_filter_reset(ts->eit);
2824 32 : gf_m2ts_section_filter_reset(ts->tdt_tot);
2825 :
2826 32 : }
2827 :
2828 0 : void gf_m2ts_mark_seg_start(GF_M2TS_Demuxer *ts)
2829 : {
2830 : u32 i;
2831 0 : for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {
2832 0 : GF_M2TS_ES *es = (GF_M2TS_ES *) ts->ess[i];
2833 0 : if (!es) continue;
2834 :
2835 0 : if (es->flags & GF_M2TS_ES_IS_SECTION) {
2836 : GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es;
2837 0 : ses->is_seg_start = GF_TRUE;
2838 : } else {
2839 : GF_M2TS_PES *pes = (GF_M2TS_PES *)es;
2840 0 : pes->is_seg_start = GF_TRUE;
2841 : }
2842 : }
2843 0 : }
2844 :
2845 :
2846 : #if 0 //unused
2847 : u32 gf_m2ts_pes_get_framing_mode(GF_M2TS_PES *pes)
2848 : {
2849 : if (pes->flags & GF_M2TS_ES_IS_SECTION) {
2850 : if (pes->flags & GF_M2TS_ES_IS_SL) {
2851 : if ( ((GF_M2TS_SECTION_ES *)pes)->sec->process_section == NULL)
2852 : return GF_M2TS_PES_FRAMING_DEFAULT;
2853 :
2854 : }
2855 : return GF_M2TS_PES_FRAMING_SKIP_NO_RESET;
2856 : }
2857 :
2858 : if (!pes->reframe ) return GF_M2TS_PES_FRAMING_SKIP_NO_RESET;
2859 : if (pes->reframe == gf_m2ts_reframe_default) return GF_M2TS_PES_FRAMING_RAW;
2860 : if (pes->reframe == gf_m2ts_reframe_reset) return GF_M2TS_PES_FRAMING_SKIP;
2861 : return GF_M2TS_PES_FRAMING_DEFAULT;
2862 : }
2863 : #endif
2864 :
2865 :
2866 : GF_EXPORT
2867 475 : GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, GF_M2TSPesFraming mode)
2868 : {
2869 475 : if (!pes) return GF_BAD_PARAM;
2870 :
2871 475 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Setting pes framing mode of PID %d to %d\n", pes->pid, mode) );
2872 : /*ignore request for section PIDs*/
2873 475 : if (pes->flags & GF_M2TS_ES_IS_SECTION) {
2874 4 : if (pes->flags & GF_M2TS_ES_IS_SL) {
2875 4 : if (mode==GF_M2TS_PES_FRAMING_DEFAULT) {
2876 4 : ((GF_M2TS_SECTION_ES *)pes)->sec->process_section = gf_m2ts_process_mpeg4section;
2877 : } else {
2878 0 : ((GF_M2TS_SECTION_ES *)pes)->sec->process_section = NULL;
2879 : }
2880 : }
2881 : return GF_OK;
2882 : }
2883 :
2884 471 : if (pes->pid==pes->program->pmt_pid) return GF_BAD_PARAM;
2885 :
2886 : //if component reuse, disable previous pes
2887 471 : if ((mode > GF_M2TS_PES_FRAMING_SKIP) && (pes->program->ts->ess[pes->pid] != (GF_M2TS_ES *) pes)) {
2888 : GF_M2TS_PES *o_pes = (GF_M2TS_PES *) pes->program->ts->ess[pes->pid];
2889 0 : if (o_pes->flags & GF_M2TS_ES_IS_PES)
2890 0 : gf_m2ts_set_pes_framing(o_pes, GF_M2TS_PES_FRAMING_SKIP);
2891 :
2892 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS] Reassinging PID %d from program %d to program %d\n", pes->pid, o_pes->program->number, pes->program->number) );
2893 0 : gf_m2ts_es_del((GF_M2TS_ES*)o_pes, pes->program->ts);
2894 :
2895 0 : pes->program->ts->ess[pes->pid] = (GF_M2TS_ES *) pes;
2896 : }
2897 :
2898 471 : switch (mode) {
2899 0 : case GF_M2TS_PES_FRAMING_RAW:
2900 0 : pes->reframe = gf_m2ts_reframe_default;
2901 0 : break;
2902 294 : case GF_M2TS_PES_FRAMING_SKIP:
2903 294 : pes->reframe = gf_m2ts_reframe_reset;
2904 294 : break;
2905 0 : case GF_M2TS_PES_FRAMING_SKIP_NO_RESET:
2906 0 : pes->reframe = NULL;
2907 0 : break;
2908 177 : case GF_M2TS_PES_FRAMING_DEFAULT:
2909 : default:
2910 177 : switch (pes->stream_type) {
2911 169 : case GF_M2TS_VIDEO_MPEG1:
2912 : case GF_M2TS_VIDEO_MPEG2:
2913 : case GF_M2TS_VIDEO_H264:
2914 : case GF_M2TS_VIDEO_SVC:
2915 : case GF_M2TS_VIDEO_HEVC:
2916 : case GF_M2TS_VIDEO_HEVC_TEMPORAL:
2917 : case GF_M2TS_VIDEO_HEVC_MCTS:
2918 : case GF_M2TS_VIDEO_SHVC:
2919 : case GF_M2TS_VIDEO_SHVC_TEMPORAL:
2920 : case GF_M2TS_VIDEO_MHVC:
2921 : case GF_M2TS_VIDEO_MHVC_TEMPORAL:
2922 : case GF_M2TS_AUDIO_MPEG1:
2923 : case GF_M2TS_AUDIO_MPEG2:
2924 : case GF_M2TS_AUDIO_AAC:
2925 : case GF_M2TS_AUDIO_LATM_AAC:
2926 : case GF_M2TS_AUDIO_AC3:
2927 : case GF_M2TS_AUDIO_EC3:
2928 : case 0xA1:
2929 : //for all our supported codec types, use a reframer filter
2930 169 : pes->reframe = gf_m2ts_reframe_default;
2931 169 : break;
2932 :
2933 : case GF_M2TS_PRIVATE_DATA:
2934 : /* TODO: handle DVB subtitle streams */
2935 : break;
2936 8 : case GF_M2TS_METADATA_ID3_HLS:
2937 : //TODO
2938 8 : pes->reframe = gf_m2ts_reframe_id3_pes;
2939 8 : break;
2940 0 : default:
2941 0 : pes->reframe = gf_m2ts_reframe_default;
2942 0 : break;
2943 : }
2944 : break;
2945 : }
2946 : return GF_OK;
2947 : }
2948 :
2949 : GF_EXPORT
2950 3056 : GF_M2TS_Demuxer *gf_m2ts_demux_new()
2951 : {
2952 : GF_M2TS_Demuxer *ts;
2953 :
2954 3056 : GF_SAFEALLOC(ts, GF_M2TS_Demuxer);
2955 3056 : if (!ts) return NULL;
2956 3056 : ts->programs = gf_list_new();
2957 3056 : ts->SDTs = gf_list_new();
2958 :
2959 3056 : ts->pat = gf_m2ts_section_filter_new(gf_m2ts_process_pat, 0);
2960 3056 : ts->cat = gf_m2ts_section_filter_new(gf_m2ts_process_cat, 0);
2961 3056 : ts->sdt = gf_m2ts_section_filter_new(gf_m2ts_process_sdt, 1);
2962 3056 : ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0);
2963 3056 : ts->eit = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_eit*/, 1);
2964 3056 : ts->tdt_tot = gf_m2ts_section_filter_new(gf_m2ts_process_tdt_tot, 1);
2965 :
2966 : #ifdef GPAC_ENABLE_MPE
2967 : gf_dvb_mpe_init(ts);
2968 : #endif
2969 :
2970 3056 : ts->nb_prog_pmt_received = 0;
2971 3056 : ts->ChannelAppList = gf_list_new();
2972 3056 : return ts;
2973 : }
2974 :
2975 : GF_EXPORT
2976 1 : void gf_m2ts_demux_dmscc_init(GF_M2TS_Demuxer *ts) {
2977 :
2978 : char temp_dir[GF_MAX_PATH];
2979 : u32 length;
2980 : GF_Err e;
2981 :
2982 1 : ts->dsmcc_controler = gf_list_new();
2983 1 : ts->process_dmscc = 1;
2984 :
2985 1 : strcpy(temp_dir, gf_get_default_cache_directory() );
2986 1 : length = (u32) strlen(temp_dir);
2987 1 : if(temp_dir[length-1] == GF_PATH_SEPARATOR) {
2988 0 : temp_dir[length-1] = 0;
2989 : }
2990 :
2991 1 : ts->dsmcc_root_dir = (char*)gf_calloc(strlen(temp_dir)+strlen("CarouselData")+2,sizeof(char));
2992 : sprintf(ts->dsmcc_root_dir,"%s%cCarouselData",temp_dir,GF_PATH_SEPARATOR);
2993 1 : e = gf_mkdir(ts->dsmcc_root_dir);
2994 1 : if(e) {
2995 0 : GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error during the creation of the directory %s \n",ts->dsmcc_root_dir));
2996 : }
2997 :
2998 1 : }
2999 :
3000 : GF_EXPORT
3001 3056 : void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts)
3002 : {
3003 : u32 i;
3004 3056 : if (ts->pat) gf_m2ts_section_filter_del(ts->pat);
3005 3056 : if (ts->cat) gf_m2ts_section_filter_del(ts->cat);
3006 3056 : if (ts->sdt) gf_m2ts_section_filter_del(ts->sdt);
3007 3056 : if (ts->nit) gf_m2ts_section_filter_del(ts->nit);
3008 3056 : if (ts->eit) gf_m2ts_section_filter_del(ts->eit);
3009 3056 : if (ts->tdt_tot) gf_m2ts_section_filter_del(ts->tdt_tot);
3010 :
3011 25034752 : for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {
3012 : //bacause of pure PCR streams, en ES might be reassigned on 2 PIDs, one for the ES and one for the PCR
3013 25034752 : if (ts->ess[i] && (ts->ess[i]->pid==i)) {
3014 435 : gf_m2ts_es_del(ts->ess[i], ts);
3015 : }
3016 : }
3017 3056 : if (ts->buffer) gf_free(ts->buffer);
3018 3190 : while (gf_list_count(ts->programs)) {
3019 134 : GF_M2TS_Program *p = (GF_M2TS_Program *)gf_list_last(ts->programs);
3020 134 : gf_list_rem_last(ts->programs);
3021 :
3022 268 : while (gf_list_count(p->streams)) {
3023 0 : GF_M2TS_ES *es = (GF_M2TS_ES *)gf_list_last(p->streams);
3024 0 : gf_list_rem_last(p->streams);
3025 0 : gf_m2ts_es_del(es, ts);
3026 : }
3027 134 : gf_list_del(p->streams);
3028 : /*reset OD list*/
3029 134 : if (p->additional_ods) {
3030 3 : gf_odf_desc_list_del(p->additional_ods);
3031 3 : gf_list_del(p->additional_ods);
3032 : }
3033 134 : if (p->pmt_iod) gf_odf_desc_del((GF_Descriptor *)p->pmt_iod);
3034 134 : if (p->metadata_pointer_descriptor) gf_m2ts_metadata_pointer_descriptor_del(p->metadata_pointer_descriptor);
3035 134 : gf_free(p);
3036 : }
3037 3056 : gf_list_del(ts->programs);
3038 :
3039 3056 : if (ts->TDT_time) gf_free(ts->TDT_time);
3040 3056 : gf_m2ts_reset_sdt(ts);
3041 3056 : if (ts->tdt_tot)
3042 3056 : gf_list_del(ts->SDTs);
3043 :
3044 : #ifdef GPAC_ENABLE_MPE
3045 : gf_dvb_mpe_shutdown(ts);
3046 : #endif
3047 :
3048 3056 : if (ts->dsmcc_controler) {
3049 1 : if (gf_list_count(ts->dsmcc_controler)) {
3050 : #ifdef GPAC_ENABLE_DSMCC
3051 : GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord = (GF_M2TS_DSMCC_OVERLORD*)gf_list_get(ts->dsmcc_controler,0);
3052 : gf_dir_cleanup(dsmcc_overlord->root_dir);
3053 : gf_rmdir(dsmcc_overlord->root_dir);
3054 : gf_m2ts_delete_dsmcc_overlord(dsmcc_overlord);
3055 : if(ts->dsmcc_root_dir) {
3056 : gf_free(ts->dsmcc_root_dir);
3057 : }
3058 : #endif
3059 : }
3060 1 : gf_list_del(ts->dsmcc_controler);
3061 : }
3062 :
3063 3056 : while(gf_list_count(ts->ChannelAppList)) {
3064 : #ifdef GPAC_ENABLE_DSMCC
3065 : GF_M2TS_CHANNEL_APPLICATION_INFO* ChanAppInfo = (GF_M2TS_CHANNEL_APPLICATION_INFO*)gf_list_get(ts->ChannelAppList,0);
3066 : gf_m2ts_delete_channel_application_info(ChanAppInfo);
3067 : gf_list_rem(ts->ChannelAppList,0);
3068 : #endif
3069 : }
3070 3056 : gf_list_del(ts->ChannelAppList);
3071 :
3072 3056 : if (ts->dsmcc_root_dir) gf_free(ts->dsmcc_root_dir);
3073 3056 : gf_free(ts);
3074 3056 : }
3075 :
3076 : #if 0//unused
3077 : void gf_m2ts_print_info(GF_M2TS_Demuxer *ts)
3078 : {
3079 : #ifdef GPAC_ENABLE_MPE
3080 : gf_m2ts_print_mpe_info(ts);
3081 : #endif
3082 : }
3083 : #endif
3084 :
3085 : #define M2TS_PROBE_SIZE 188000
3086 2991 : static Bool gf_m2ts_probe_buffer(char *buf, u32 size)
3087 : {
3088 : GF_Err e;
3089 : GF_M2TS_Demuxer *ts;
3090 : u32 lt;
3091 :
3092 2991 : lt = gf_log_get_tool_level(GF_LOG_CONTAINER);
3093 2991 : gf_log_set_tool_level(GF_LOG_CONTAINER, GF_LOG_QUIET);
3094 :
3095 2991 : ts = gf_m2ts_demux_new();
3096 2991 : e = gf_m2ts_process_data(ts, buf, size);
3097 :
3098 2991 : if (!ts->pck_number) {
3099 : e = GF_BAD_PARAM;
3100 : } else {
3101 : u32 nb_pck;
3102 : //max number of packets
3103 578 : if (ts->prefix_present)
3104 123 : nb_pck = size/192;
3105 : else
3106 455 : nb_pck = size/188;
3107 : //probe success if after align we have nb_pck - 2 and at least 2 packets
3108 578 : if ((nb_pck<2) || (ts->pck_number + 2 < nb_pck))
3109 : e = GF_BAD_PARAM;
3110 : }
3111 2991 : gf_m2ts_demux_del(ts);
3112 :
3113 2991 : gf_log_set_tool_level(GF_LOG_CONTAINER, lt);
3114 :
3115 2991 : if (e) return GF_FALSE;
3116 34 : return GF_TRUE;
3117 :
3118 : }
3119 : GF_EXPORT
3120 1 : Bool gf_m2ts_probe_file(const char *fileName)
3121 : {
3122 : char buf[M2TS_PROBE_SIZE];
3123 : u32 size;
3124 :
3125 1 : if (!strncmp(fileName, "gmem://", 7)) {
3126 : u8 *mem_address;
3127 0 : if (gf_blob_get(fileName, &mem_address, &size, NULL) != GF_OK) {
3128 0 : return GF_FALSE;
3129 : }
3130 0 : if (size>M2TS_PROBE_SIZE) size = M2TS_PROBE_SIZE;
3131 0 : memcpy(buf, mem_address, size);
3132 0 : gf_blob_release(fileName);
3133 : } else {
3134 1 : FILE *t = gf_fopen(fileName, "rb");
3135 1 : if (!t) return 0;
3136 1 : size = (u32) gf_fread(buf, M2TS_PROBE_SIZE, t);
3137 1 : gf_fclose(t);
3138 1 : if ((s32) size <= 0) return 0;
3139 : }
3140 1 : return gf_m2ts_probe_buffer(buf, size);
3141 : }
3142 :
3143 : GF_EXPORT
3144 3074 : Bool gf_m2ts_probe_data(const u8 *data, u32 size)
3145 : {
3146 3074 : size /= 188;
3147 3074 : size *= 188;
3148 3074 : if (!size) return GF_FALSE;
3149 2990 : return gf_m2ts_probe_buffer((char *) data, size);
3150 : }
3151 :
3152 :
3153 : static void rewrite_pts_dts(unsigned char *ptr, u64 TS)
3154 : {
3155 2 : ptr[0] &= 0xf1;
3156 2 : ptr[0] |= (unsigned char)((TS&0x1c0000000ULL)>>29);
3157 2 : ptr[1] = (unsigned char)((TS&0x03fc00000ULL)>>22);
3158 2 : ptr[2] &= 0x1;
3159 2 : ptr[2] |= (unsigned char)((TS&0x0003f8000ULL)>>14);
3160 2 : ptr[3] = (unsigned char)((TS&0x000007f80ULL)>>7);
3161 2 : ptr[4] &= 0x1;
3162 2 : ptr[4] |= (unsigned char)((TS&0x00000007fULL)<<1);
3163 :
3164 : assert(((u64)(ptr[0]&0xe)<<29) + ((u64)ptr[1]<<22) + ((u64)(ptr[2]&0xfe)<<14) + ((u64)ptr[3]<<7) + ((ptr[4]&0xfe)>>1) == TS);
3165 : }
3166 :
3167 : #define ADJUST_TIMESTAMP(_TS) \
3168 : if (_TS < (u64) -ts_shift) _TS = pcr_mod + _TS + ts_shift; \
3169 : else _TS = _TS + ts_shift; \
3170 : while (_TS > pcr_mod) _TS -= pcr_mod; \
3171 :
3172 : GF_EXPORT
3173 1 : GF_Err gf_m2ts_restamp(u8 *buffer, u32 size, s64 ts_shift, u8 is_pes[GF_M2TS_MAX_STREAMS])
3174 : {
3175 : u32 done = 0;
3176 : u64 pcr_mod;
3177 : // if (!ts_shift) return GF_OK;
3178 :
3179 : pcr_mod = 0x80000000;
3180 : pcr_mod*=4;
3181 3 : while (done + 188 <= size) {
3182 : u8 *pesh;
3183 : u8 *pck;
3184 : u64 pcr_base=0, pcr_ext=0;
3185 : u16 pid;
3186 : u8 adaptation_field, adaptation_field_length;
3187 :
3188 1 : pck = (u8*) buffer+done;
3189 1 : if (pck[0]!=0x47) {
3190 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS Restamp] Invalid sync byte %X\n", pck[0]));
3191 : return GF_NON_COMPLIANT_BITSTREAM;
3192 : }
3193 1 : pid = ((pck[1] & 0x1f) <<8 ) + pck[2];
3194 :
3195 : adaptation_field_length = 0;
3196 1 : adaptation_field = (pck[3] >> 4) & 0x3;
3197 1 : if ((adaptation_field==2) || (adaptation_field==3)) {
3198 0 : adaptation_field_length = pck[4];
3199 0 : if ( pck[5]&0x10 /*PCR_flag*/) {
3200 0 : pcr_base = (((u64)pck[6])<<25) + (pck[7]<<17) + (pck[8]<<9) + (pck[9]<<1) + (pck[10]>>7);
3201 0 : pcr_ext = ((pck[10]&1)<<8) + pck[11];
3202 :
3203 0 : ADJUST_TIMESTAMP(pcr_base);
3204 :
3205 0 : pck[6] = (unsigned char)(0xff&(pcr_base>>25));
3206 0 : pck[7] = (unsigned char)(0xff&(pcr_base>>17));
3207 0 : pck[8] = (unsigned char)(0xff&(pcr_base>>9));
3208 0 : pck[9] = (unsigned char)(0xff&(pcr_base>>1));
3209 0 : pck[10] = (unsigned char)(((0x1&pcr_base)<<7) | 0x7e | ((0x100&pcr_ext)>>8));
3210 0 : if (pcr_ext != ((pck[10]&1)<<8) + pck[11]) {
3211 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS Restamp] Sanity check failed for PCR restamping\n"));
3212 : return GF_IO_ERR;
3213 : }
3214 0 : pck[11] = (unsigned char)(0xff&pcr_ext);
3215 : }
3216 : /*add adaptation_field_length field*/
3217 0 : adaptation_field_length++;
3218 : }
3219 1 : if (!is_pes[pid] || !(pck[1]&0x40)) {
3220 : done+=188;
3221 0 : continue;
3222 : }
3223 :
3224 1 : pesh = &pck[4+adaptation_field_length];
3225 :
3226 1 : if ((pesh[0]==0x00) && (pesh[1]==0x00) && (pesh[2]==0x01)) {
3227 : Bool has_pts, has_dts;
3228 1 : if ((pesh[6]&0xc0)!=0x80) {
3229 : done+=188;
3230 0 : continue;
3231 : }
3232 1 : has_pts = (pesh[7]&0x80);
3233 1 : has_dts = has_pts ? (pesh[7]&0x40) : 0;
3234 :
3235 1 : if (has_pts) {
3236 : u64 PTS;
3237 1 : if (((pesh[9]&0xe0)>>4)!=0x2) {
3238 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS Restamp] PID %4d: Wrong PES header, PTS decoding: '0010' expected\n", pid));
3239 : done+=188;
3240 0 : continue;
3241 : }
3242 :
3243 : PTS = gf_m2ts_get_pts(pesh + 9);
3244 1 : ADJUST_TIMESTAMP(PTS);
3245 : rewrite_pts_dts(pesh+9, PTS);
3246 : }
3247 :
3248 1 : if (has_dts) {
3249 : u64 DTS = gf_m2ts_get_pts(pesh + 14);
3250 1 : ADJUST_TIMESTAMP(DTS);
3251 : rewrite_pts_dts(pesh+14, DTS);
3252 : }
3253 : } else {
3254 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS Restamp] PID %4d: Wrong PES not beginning with start code\n", pid));
3255 : }
3256 : done+=188;
3257 : }
3258 : return GF_OK;
3259 : }
3260 :
3261 : #endif /*GPAC_DISABLE_MPEG2TS*/
|