static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)

{

    MpegTSContext *ts = filter->u.section_filter.opaque;

    MpegTSSectionFilter *tssf = &filter->u.section_filter;

    SectionHeader h1, *h = &h1;

    PESContext *pes;

    AVStream *st;

    const uint8_t *p, *p_end, *desc_list_end;

    int program_info_length, pcr_pid, pid, stream_type;

    int desc_list_len;

    uint32_t prog_reg_desc = 0; /* registration descriptor */



    int mp4_descr_count = 0;

    Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } };

    int i;



    av_log(ts->stream, AV_LOG_TRACE, "PMT: len %i\n", section_len);

    hex_dump_debug(ts->stream, section, section_len);



    p_end = section + section_len - 4;

    p = section;

    if (parse_section_header(h, &p, p_end) < 0)

        return;

    if (h->version == tssf->last_ver)

        return;

    tssf->last_ver = h->version;



    av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d\n",

            h->id, h->sec_num, h->last_sec_num, h->version);



    if (h->tid != PMT_TID)

        return;

    if (!ts->scan_all_pmts && ts->skip_changes)

        return;



    if (!ts->skip_clear)

        clear_program(ts, h->id);



    pcr_pid = get16(&p, p_end);

    if (pcr_pid < 0)

        return;

    pcr_pid &= 0x1fff;

    add_pid_to_pmt(ts, h->id, pcr_pid);

    set_pcr_pid(ts->stream, h->id, pcr_pid);



    av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid);



    program_info_length = get16(&p, p_end);

    if (program_info_length < 0)

        return;

    program_info_length &= 0xfff;

    while (program_info_length >= 2) {

        uint8_t tag, len;

        tag = get8(&p, p_end);

        len = get8(&p, p_end);



        av_log(ts->stream, AV_LOG_TRACE, "program tag: 0x%02x len=%d\n", tag, len);



        if (len > program_info_length - 2)

            // something else is broken, exit the program_descriptors_loop

            break;

        program_info_length -= len + 2;

        if (tag == 0x1d) { // IOD descriptor

            get8(&p, p_end); // scope

            get8(&p, p_end); // label

            len -= 2;

            mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count,

                          &mp4_descr_count, MAX_MP4_DESCR_COUNT);

        } else if (tag == 0x05 && len >= 4) { // registration descriptor

            prog_reg_desc = bytestream_get_le32(&p);

            len -= 4;

        }

        p += len;

    }

    p += program_info_length;

    if (p >= p_end)

        goto out;



    // stop parsing after pmt, we found header

    if (!ts->stream->nb_streams)

        ts->stop_parse = 2;



    set_pmt_found(ts, h->id);





    for (;;) {

        st = 0;

        pes = NULL;

        stream_type = get8(&p, p_end);

        if (stream_type < 0)

            break;

        pid = get16(&p, p_end);

        if (pid < 0)

            goto out;

        pid &= 0x1fff;

        if (pid == ts->current_pid)

            goto out;



        /* now create stream */

        if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {

            pes = ts->pids[pid]->u.pes_filter.opaque;

            if (!pes->st) {

                pes->st     = avformat_new_stream(pes->stream, NULL);

                if (!pes->st)

                    goto out;

                pes->st->id = pes->pid;

            }

            st = pes->st;

        } else if (stream_type != 0x13) {

            if (ts->pids[pid])

                mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably

            pes = add_pes_stream(ts, pid, pcr_pid);

            if (pes) {

                st = avformat_new_stream(pes->stream, NULL);

                if (!st)

                    goto out;

                st->id = pes->pid;

            }

        } else {

            int idx = ff_find_stream_index(ts->stream, pid);

            if (idx >= 0) {

                st = ts->stream->streams[idx];

            } else {

                st = avformat_new_stream(ts->stream, NULL);

                if (!st)

                    goto out;

                st->id = pid;

                st->codec->codec_type = AVMEDIA_TYPE_DATA;

            }

        }



        if (!st)

            goto out;



        if (pes && !pes->stream_type)

            mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);



        add_pid_to_pmt(ts, h->id, pid);



        ff_program_add_stream_index(ts->stream, h->id, st->index);



        desc_list_len = get16(&p, p_end);

        if (desc_list_len < 0)

            goto out;

        desc_list_len &= 0xfff;

        desc_list_end  = p + desc_list_len;

        if (desc_list_end > p_end)

            goto out;

        for (;;) {

            if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p,

                                          desc_list_end, mp4_descr,

                                          mp4_descr_count, pid, ts) < 0)

                break;



            if (pes && prog_reg_desc == AV_RL32("HDMV") &&

                stream_type == 0x83 && pes->sub_st) {

                ff_program_add_stream_index(ts->stream, h->id,

                                            pes->sub_st->index);

                pes->sub_st->codec->codec_tag = st->codec->codec_tag;

            }

        }

        p = desc_list_end;

    }



    if (!ts->pids[pcr_pid])

        mpegts_open_pcr_filter(ts, pcr_pid);



out:

    for (i = 0; i < mp4_descr_count; i++)

        av_free(mp4_descr[i].dec_config_descr);

}

static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)

{

    MpegTSContext *ts = filter->u.section_filter.opaque;

    MpegTSSectionFilter *tssf = &filter->u.section_filter;

    SectionHeader h1, *h = &h1;

    PESContext *pes;

    AVStream *st;

    const uint8_t *p, *p_end, *desc_list_end;

    int program_info_length, pcr_pid, pid, stream_type;

    int desc_list_len;

    uint32_t prog_reg_desc = 0; 



    int mp4_descr_count = 0;

    Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } };

    int i;



    av_log(ts->stream, AV_LOG_TRACE, "PMT: len %i\n", section_len);

    hex_dump_debug(ts->stream, section, section_len);



    p_end = section + section_len - 4;

    p = section;

    if (parse_section_header(h, &p, p_end) < 0)

        return;

    if (h->version == tssf->last_ver)

        return;

    tssf->last_ver = h->version;



    av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d\n",

            h->id, h->sec_num, h->last_sec_num, h->version);



    if (h->tid != PMT_TID)

        return;

    if (!ts->scan_all_pmts && ts->skip_changes)

        return;



    if (!ts->skip_clear)

        clear_program(ts, h->id);



    pcr_pid = get16(&p, p_end);

    if (pcr_pid < 0)

        return;

    pcr_pid &= 0x1fff;

    add_pid_to_pmt(ts, h->id, pcr_pid);

    set_pcr_pid(ts->stream, h->id, pcr_pid);



    av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid);



    program_info_length = get16(&p, p_end);

    if (program_info_length < 0)

        return;

    program_info_length &= 0xfff;

    while (program_info_length >= 2) {

        uint8_t tag, len;

        tag = get8(&p, p_end);

        len = get8(&p, p_end);



        av_log(ts->stream, AV_LOG_TRACE, "program tag: 0x%02x len=%d\n", tag, len);



        if (len > program_info_length - 2)

            

            break;

        program_info_length -= len + 2;

        if (tag == 0x1d) { 

            get8(&p, p_end); 

            get8(&p, p_end); 

            len -= 2;

            mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count,

                          &mp4_descr_count, MAX_MP4_DESCR_COUNT);

        } else if (tag == 0x05 && len >= 4) { 

            prog_reg_desc = bytestream_get_le32(&p);

            len -= 4;

        }

        p += len;

    }

    p += program_info_length;

    if (p >= p_end)

        goto out;



    

    if (!ts->stream->nb_streams)

        ts->stop_parse = 2;



    set_pmt_found(ts, h->id);





    for (;;) {

        st = 0;

        pes = NULL;

        stream_type = get8(&p, p_end);

        if (stream_type < 0)

            break;

        pid = get16(&p, p_end);

        if (pid < 0)

            goto out;

        pid &= 0x1fff;

        if (pid == ts->current_pid)

            goto out;



        

        if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {

            pes = ts->pids[pid]->u.pes_filter.opaque;

            if (!pes->st) {

                pes->st     = avformat_new_stream(pes->stream, NULL);

                if (!pes->st)

                    goto out;

                pes->st->id = pes->pid;

            }

            st = pes->st;

        } else if (stream_type != 0x13) {

            if (ts->pids[pid])

                mpegts_close_filter(ts, ts->pids[pid]); 

            pes = add_pes_stream(ts, pid, pcr_pid);

            if (pes) {

                st = avformat_new_stream(pes->stream, NULL);

                if (!st)

                    goto out;

                st->id = pes->pid;

            }

        } else {

            int idx = ff_find_stream_index(ts->stream, pid);

            if (idx >= 0) {

                st = ts->stream->streams[idx];

            } else {

                st = avformat_new_stream(ts->stream, NULL);

                if (!st)

                    goto out;

                st->id = pid;

                st->codec->codec_type = AVMEDIA_TYPE_DATA;

            }

        }



        if (!st)

            goto out;



        if (pes && !pes->stream_type)

            mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);



        add_pid_to_pmt(ts, h->id, pid);



        ff_program_add_stream_index(ts->stream, h->id, st->index);



        desc_list_len = get16(&p, p_end);

        if (desc_list_len < 0)

            goto out;

        desc_list_len &= 0xfff;

        desc_list_end  = p + desc_list_len;

        if (desc_list_end > p_end)

            goto out;

        for (;;) {

            if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p,

                                          desc_list_end, mp4_descr,

                                          mp4_descr_count, pid, ts) < 0)

                break;



            if (pes && prog_reg_desc == AV_RL32("HDMV") &&

                stream_type == 0x83 && pes->sub_st) {

                ff_program_add_stream_index(ts->stream, h->id,

                                            pes->sub_st->index);

                pes->sub_st->codec->codec_tag = st->codec->codec_tag;

            }

        }

        p = desc_list_end;

    }



    if (!ts->pids[pcr_pid])

        mpegts_open_pcr_filter(ts, pcr_pid);



out:

    for (i = 0; i < mp4_descr_count; i++)

        av_free(mp4_descr[i].dec_config_descr);

}

static void FUNC_0(MpegTSFilter *VAR_0, const uint8_t *VAR_1, int VAR_2)

{

    MpegTSContext *ts = VAR_0->u.section_filter.opaque;

    MpegTSSectionFilter *tssf = &VAR_0->u.section_filter;

    SectionHeader h1, *h = &h1;

    PESContext *pes;

    AVStream *st;

    const uint8_t *VAR_3, *p_end, *desc_list_end;

    int VAR_4, VAR_5, VAR_6, VAR_7;

    int VAR_8;

    uint32_t prog_reg_desc = 0; 



    int VAR_9 = 0;

    Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } };

    int VAR_10;



    av_log(ts->stream, AV_LOG_TRACE, "PMT: len %VAR_10\n", VAR_2);

    hex_dump_debug(ts->stream, VAR_1, VAR_2);



    p_end = VAR_1 + VAR_2 - 4;

    VAR_3 = VAR_1;

    if (parse_section_header(h, &VAR_3, p_end) < 0)

        return;

    if (h->version == tssf->last_ver)

        return;

    tssf->last_ver = h->version;



    av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d\n",

            h->id, h->sec_num, h->last_sec_num, h->version);



    if (h->tid != PMT_TID)

        return;

    if (!ts->scan_all_pmts && ts->skip_changes)

        return;



    if (!ts->skip_clear)

        clear_program(ts, h->id);



    VAR_5 = get16(&VAR_3, p_end);

    if (VAR_5 < 0)

        return;

    VAR_5 &= 0x1fff;

    add_pid_to_pmt(ts, h->id, VAR_5);

    set_pcr_pid(ts->stream, h->id, VAR_5);



    av_log(ts->stream, AV_LOG_TRACE, "VAR_5=0x%x\n", VAR_5);



    VAR_4 = get16(&VAR_3, p_end);

    if (VAR_4 < 0)

        return;

    VAR_4 &= 0xfff;

    while (VAR_4 >= 2) {

        uint8_t tag, len;

        tag = get8(&VAR_3, p_end);

        len = get8(&VAR_3, p_end);



        av_log(ts->stream, AV_LOG_TRACE, "program tag: 0x%02x len=%d\n", tag, len);



        if (len > VAR_4 - 2)

            

            break;

        VAR_4 -= len + 2;

        if (tag == 0x1d) { 

            get8(&VAR_3, p_end); 

            get8(&VAR_3, p_end); 

            len -= 2;

            mp4_read_iods(ts->stream, VAR_3, len, mp4_descr + VAR_9,

                          &VAR_9, MAX_MP4_DESCR_COUNT);

        } else if (tag == 0x05 && len >= 4) { 

            prog_reg_desc = bytestream_get_le32(&VAR_3);

            len -= 4;

        }

        VAR_3 += len;

    }

    VAR_3 += VAR_4;

    if (VAR_3 >= p_end)

        goto out;



    

    if (!ts->stream->nb_streams)

        ts->stop_parse = 2;



    set_pmt_found(ts, h->id);





    for (;;) {

        st = 0;

        pes = NULL;

        VAR_7 = get8(&VAR_3, p_end);

        if (VAR_7 < 0)

            break;

        VAR_6 = get16(&VAR_3, p_end);

        if (VAR_6 < 0)

            goto out;

        VAR_6 &= 0x1fff;

        if (VAR_6 == ts->current_pid)

            goto out;



        

        if (ts->pids[VAR_6] && ts->pids[VAR_6]->type == MPEGTS_PES) {

            pes = ts->pids[VAR_6]->u.pes_filter.opaque;

            if (!pes->st) {

                pes->st     = avformat_new_stream(pes->stream, NULL);

                if (!pes->st)

                    goto out;

                pes->st->id = pes->VAR_6;

            }

            st = pes->st;

        } else if (VAR_7 != 0x13) {

            if (ts->pids[VAR_6])

                mpegts_close_filter(ts, ts->pids[VAR_6]); 

            pes = add_pes_stream(ts, VAR_6, VAR_5);

            if (pes) {

                st = avformat_new_stream(pes->stream, NULL);

                if (!st)

                    goto out;

                st->id = pes->VAR_6;

            }

        } else {

            int VAR_11 = ff_find_stream_index(ts->stream, VAR_6);

            if (VAR_11 >= 0) {

                st = ts->stream->streams[VAR_11];

            } else {

                st = avformat_new_stream(ts->stream, NULL);

                if (!st)

                    goto out;

                st->id = VAR_6;

                st->codec->codec_type = AVMEDIA_TYPE_DATA;

            }

        }



        if (!st)

            goto out;



        if (pes && !pes->VAR_7)

            mpegts_set_stream_info(st, pes, VAR_7, prog_reg_desc);



        add_pid_to_pmt(ts, h->id, VAR_6);



        ff_program_add_stream_index(ts->stream, h->id, st->index);



        VAR_8 = get16(&VAR_3, p_end);

        if (VAR_8 < 0)

            goto out;

        VAR_8 &= 0xfff;

        desc_list_end  = VAR_3 + VAR_8;

        if (desc_list_end > p_end)

            goto out;

        for (;;) {

            if (ff_parse_mpeg2_descriptor(ts->stream, st, VAR_7, &VAR_3,

                                          desc_list_end, mp4_descr,

                                          VAR_9, VAR_6, ts) < 0)

                break;



            if (pes && prog_reg_desc == AV_RL32("HDMV") &&

                VAR_7 == 0x83 && pes->sub_st) {

                ff_program_add_stream_index(ts->stream, h->id,

                                            pes->sub_st->index);

                pes->sub_st->codec->codec_tag = st->codec->codec_tag;

            }

        }

        VAR_3 = desc_list_end;

    }



    if (!ts->pids[VAR_5])

        mpegts_open_pcr_filter(ts, VAR_5);



out:

    for (VAR_10 = 0; VAR_10 < VAR_9; VAR_10++)

        av_free(mp4_descr[VAR_10].dec_config_descr);

}

static void FUNC_0(MpegTSFilter *VAR_0, const uint8_t *VAR_1, int VAR_2)
{ MpegTSContext *ts = VAR_0->u.section_filter.opaque; MpegTSSectionFilter *tssf = &VAR_0->u.section_filter; SectionHeader h1, *h = &h1; PESContext *pes; AVStream *st; const uint8_t *VAR_3, *p_end, *desc_list_end; int VAR_4, VAR_5, VAR_6, VAR_7; int VAR_8; uint32_t prog_reg_desc = 0; int VAR_9 = 0; Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } }; int VAR_10; av_log(ts->stream, AV_LOG_TRACE, "PMT: len %VAR_10\n", VAR_2); hex_dump_debug(ts->stream, VAR_1, VAR_2); p_end = VAR_1 + VAR_2 - 4; VAR_3 = VAR_1; if (parse_section_header(h, &VAR_3, p_end) < 0)
return; if (h->version == tssf->last_ver)
return; tssf->last_ver = h->version; av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d\n",
h->id, h->sec_num, h->last_sec_num, h->version); if (h->tid != PMT_TID)
return; if (!ts->scan_all_pmts && ts->skip_changes)
return; if (!ts->skip_clear)
clear_program(ts, h->id); VAR_5 = get16(&VAR_3, p_end); if (VAR_5 < 0)
return; VAR_5 &= 0x1fff; add_pid_to_pmt(ts, h->id, VAR_5); set_pcr_pid(ts->stream, h->id, VAR_5); av_log(ts->stream, AV_LOG_TRACE, "VAR_5=0x%x\n", VAR_5); VAR_4 = get16(&VAR_3, p_end); if (VAR_4 < 0)
return; VAR_4 &= 0xfff; while (VAR_4 >= 2) { uint8_t tag, len; tag = get8(&VAR_3, p_end); len = get8(&VAR_3, p_end); av_log(ts->stream, AV_LOG_TRACE, "program tag: 0x%02x len=%d\n", tag, len); if (len > VAR_4 - 2)
break; VAR_4 -= len + 2; if (tag == 0x1d) { get8(&VAR_3, p_end); get8(&VAR_3, p_end); len -= 2; mp4_read_iods(ts->stream, VAR_3, len, mp4_descr + VAR_9,
&VAR_9, MAX_MP4_DESCR_COUNT); } else if (tag == 0x05 && len >= 4) { prog_reg_desc = bytestream_get_le32(&VAR_3); len -= 4; } VAR_3 += len; } VAR_3 += VAR_4; if (VAR_3 >= p_end)
goto out; if (!ts->stream->nb_streams)
ts->stop_parse = 2; set_pmt_found(ts, h->id); for (;;) { st = 0; pes = NULL; VAR_7 = get8(&VAR_3, p_end); if (VAR_7 < 0)
break; VAR_6 = get16(&VAR_3, p_end); if (VAR_6 < 0)
goto out; VAR_6 &= 0x1fff; if (VAR_6 == ts->current_pid)
goto out; if (ts->pids[VAR_6] && ts->pids[VAR_6]->type == MPEGTS_PES) { pes = ts->pids[VAR_6]->u.pes_filter.opaque; if (!pes->st) { pes->st     = avformat_new_stream(pes->stream, NULL); if (!pes->st)
goto out; pes->st->id = pes->VAR_6; } st = pes->st; } else if (VAR_7 != 0x13) { if (ts->pids[VAR_6])
mpegts_close_filter(ts, ts->pids[VAR_6]); pes = add_pes_stream(ts, VAR_6, VAR_5); if (pes) { st = avformat_new_stream(pes->stream, NULL); if (!st)
goto out; st->id = pes->VAR_6; } } else { int VAR_11 = ff_find_stream_index(ts->stream, VAR_6); if (VAR_11 >= 0) { st = ts->stream->streams[VAR_11]; } else { st = avformat_new_stream(ts->stream, NULL); if (!st)
goto out; st->id = VAR_6; st->codec->codec_type = AVMEDIA_TYPE_DATA; } } if (!st)
goto out; if (pes && !pes->VAR_7)
mpegts_set_stream_info(st, pes, VAR_7, prog_reg_desc); add_pid_to_pmt(ts, h->id, VAR_6); ff_program_add_stream_index(ts->stream, h->id, st->index); VAR_8 = get16(&VAR_3, p_end); if (VAR_8 < 0)
goto out; VAR_8 &= 0xfff; desc_list_end  = VAR_3 + VAR_8; if (desc_list_end > p_end)
goto out; for (;;) { if (ff_parse_mpeg2_descriptor(ts->stream, st, VAR_7, &VAR_3,
desc_list_end, mp4_descr,
VAR_9, VAR_6, ts) < 0)
break; if (pes && prog_reg_desc == AV_RL32("HDMV") &&
VAR_7 == 0x83 && pes->sub_st) { ff_program_add_stream_index(ts->stream, h->id,
pes->sub_st->index); pes->sub_st->codec->codec_tag = st->codec->codec_tag; } } VAR_3 = desc_list_end; } if (!ts->pids[VAR_5])
mpegts_open_pcr_filter(ts, VAR_5); out:
for (VAR_10 = 0; VAR_10 < VAR_9; VAR_10++) av_free(mp4_descr[VAR_10].dec_config_descr); }