Coverage Report

Created: 2026-06-15 07:02

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