LCOV - code coverage report
Current view: top level - media_tools - mpegts.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1176 1563 75.2 %
Date: 2021-04-29 23:48:07 Functions: 46 49 93.9 %

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

Generated by: LCOV version 1.13