Exemple #1
0
/* add all services found in the PAT */
static void pat_scan_cb(void *opaque, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = opaque;
    SectionHeader h1, *h = &h1;
    const uint8_t *p, *p_end;
    int sid, pmt_pid;
    char *provider_name, *name;
    char buf[256];

#ifdef DEBUG_SI
    printf("PAT:\n");
    av_hex_dump(stdout, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
    if (h->tid != PAT_TID)
        return;

    for(;;) {
        sid = get16(&p, p_end);
        if (sid < 0)
            break;
        pmt_pid = get16(&p, p_end) & 0x1fff;
        if (pmt_pid < 0)
            break;
#ifdef DEBUG_SI
        printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
#endif
        if (sid == 0x0000) {
            /* NIT info */
        } else {
            /* add the service with a dummy name */
            snprintf(buf, sizeof(buf), "Service %x\n", sid);
            name = av_strdup(buf);
            provider_name = av_strdup("");
            if (name && provider_name) {
                new_service(ts, sid, provider_name, name);
            } else {
                av_freep(&name);
                av_freep(&provider_name);
            }
        }
    }
    ts->stop_parse = 1;

    /* remove filter */
    mpegts_close_filter(ts, ts->pat_filter);
    ts->pat_filter = NULL;
}
Exemple #2
0
static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = filter->u.section_filter.opaque;
    SectionHeader h1, *h = &h1;
    const uint8_t *p, *p_end;
    int sid, pmt_pid;

#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "PAT:\n");
    av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
    if (h->tid != PAT_TID)
        return;

    clear_programs(ts);
    for(;;) {
        sid = get16(&p, p_end);
        if (sid < 0)
            break;
        pmt_pid = get16(&p, p_end) & 0x1fff;
        if (pmt_pid < 0)
            break;
#ifdef DEBUG_SI
        av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x pid=0x%x\n", sid, pmt_pid);
#endif
        if (sid == 0x0000) {
            /* NIT info */
        } else {
            av_new_program(ts->stream, sid);
            ts->stop_parse--;
            mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
            add_pat_entry(ts, sid);
            add_pid_to_pmt(ts, sid, 0); //add pat pid to program
            add_pid_to_pmt(ts, sid, pmt_pid);
        }
    }
    /* not found */
    ts->stop_parse++;

    mpegts_close_filter(ts, filter);
}
Exemple #3
0
static void pat_cb(void *opaque, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = opaque;
    SectionHeader h1, *h = &h1;
    const uint8_t *p, *p_end;
    int sid, pmt_pid;

#ifdef DEBUG_SI
    printf("PAT:\n");
    av_hex_dump(stdout, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
    if (h->tid != PAT_TID)
        return;

    for(;;) {
        sid = get16(&p, p_end);
        if (sid < 0)
            break;
        pmt_pid = get16(&p, p_end) & 0x1fff;
        if (pmt_pid < 0)
            break;
#ifdef DEBUG_SI
        printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
#endif
        if (sid == 0x0000) {
            /* NIT info */
        } else {
            if (ts->req_sid == sid) {
                ts->pmt_filter = mpegts_open_section_filter(ts, pmt_pid, 
                                                            pmt_cb, ts, 1);
                goto found;
            }
        }
    }
    /* not found */
    ts->set_service_cb(ts->set_service_opaque, -1);

 found:
    mpegts_close_filter(ts, ts->pat_filter);
    ts->pat_filter = NULL;
}
Exemple #4
0
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = filter->u.section_filter.opaque;
    SectionHeader h1, *h = &h1;
    PESContext *pes;
    AVStream *st;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int program_info_length, pcr_pid, pid, stream_type;
    int desc_list_len, desc_len, desc_tag;
    int comp_page = 0, anc_page = 0; /* initialize to kill warnings */
    char language[4] = {0}; /* initialize to kill warnings */
    int has_hdmv_descr = 0;
    int has_dirac_descr = 0;

#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "PMT: len %i\n", section_len);
    av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x sec_num=%d/%d\n",
           h->id, h->sec_num, h->last_sec_num);
#endif
    if (h->tid != PMT_TID)
        return;

    clear_program(ts, h->id);
    pcr_pid = get16(&p, p_end) & 0x1fff;
    if (pcr_pid < 0)
        return;
    add_pid_to_pmt(ts, h->id, pcr_pid);
#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "pcr_pid=0x%x\n", pcr_pid);
#endif
    program_info_length = get16(&p, p_end) & 0xfff;
    if (program_info_length < 0)
        return;
    while(program_info_length >= 2) {
        uint8_t tag, len;
        tag = get8(&p, p_end);
        len = get8(&p, p_end);
        if(len > program_info_length - 2)
            //something else is broken, exit the program_descriptors_loop
            break;
        program_info_length -= len + 2;
        if(tag == REGISTRATION_DESCRIPTOR && len >= 4) {
            uint8_t bytes[4];
            bytes[0] = get8(&p, p_end);
            bytes[1] = get8(&p, p_end);
            bytes[2] = get8(&p, p_end);
            bytes[3] = get8(&p, p_end);
            len -= 4;
            if(bytes[0] == 'H' && bytes[1] == 'D' &&
               bytes[2] == 'M' && bytes[3] == 'V')
                has_hdmv_descr = 1;
        }
        p += len;
    }
    p += program_info_length;
    if (p >= p_end)
        return;
    for(;;) {
        language[0] = 0;
        st = 0;
        stream_type = get8(&p, p_end);
        if (stream_type < 0)
            break;
        pid = get16(&p, p_end) & 0x1fff;
        if (pid < 0)
            break;
        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            if (stream_type == STREAM_TYPE_PRIVATE_DATA) {
                if((desc_tag == 0x6A) || (desc_tag == 0x7A)) {
                    /*assume DVB AC-3 Audio*/
                    stream_type = STREAM_TYPE_AUDIO_AC3;
                } else if(desc_tag == 0x7B) {
                    /* DVB DTS audio */
                    stream_type = STREAM_TYPE_AUDIO_DTS;
                }
            }
            desc_len = get8(&p, desc_list_end);
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;
#ifdef DEBUG_SI
            av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n",
                   desc_tag, desc_len);
#endif
            switch(desc_tag) {
            case DVB_SUBT_DESCID:
                if (stream_type == STREAM_TYPE_PRIVATE_DATA)
                    stream_type = STREAM_TYPE_SUBTITLE_DVB;

                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                get8(&p, desc_end);
                comp_page = get16(&p, desc_end);
                anc_page = get16(&p, desc_end);

                break;
            case 0x0a: /* ISO 639 language descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                break;
            case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */
                {
                    uint8_t bytes[4];
                    bytes[0] = get8(&p, desc_end);
                    bytes[1] = get8(&p, desc_end);
                    bytes[2] = get8(&p, desc_end);
                    bytes[3] = get8(&p, desc_end);
                    if(bytes[0] == 'd' && bytes[1] == 'r' &&
                       bytes[2] == 'a' && bytes[3] == 'c')
                        has_dirac_descr = 1;
                    break;
                }
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;

#ifdef DEBUG_SI
        av_log(ts->stream, AV_LOG_DEBUG, "stream_type=%d pid=0x%x\n",
               stream_type, pid);
#endif

        /* now create ffmpeg stream */
        switch(stream_type) {
        case STREAM_TYPE_AUDIO_MPEG1:
        case STREAM_TYPE_AUDIO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG1:
        case STREAM_TYPE_VIDEO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG4:
        case STREAM_TYPE_VIDEO_H264:
        case STREAM_TYPE_VIDEO_VC1:
        case STREAM_TYPE_VIDEO_DIRAC:
        case STREAM_TYPE_AUDIO_AAC:
        case STREAM_TYPE_AUDIO_AC3:
        case STREAM_TYPE_AUDIO_DTS:
        case STREAM_TYPE_AUDIO_HDMV_DTS:
        case STREAM_TYPE_SUBTITLE_DVB:
            if((stream_type == STREAM_TYPE_AUDIO_HDMV_DTS && !has_hdmv_descr)
            || (stream_type == STREAM_TYPE_VIDEO_DIRAC    && !has_dirac_descr))
                break;
            if(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES){
                pes= ts->pids[pid]->u.pes_filter.opaque;
                st= pes->st;
            }else{
                if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
                pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
                if (pes)
                    st = new_pes_av_stream(pes, 0);
            }
            add_pid_to_pmt(ts, h->id, pid);
            if(st)
                av_program_add_stream_index(ts->stream, h->id, st->index);
            break;
        default:
            /* we ignore the other streams */
            break;
        }

        if (st) {
            if (language[0] != 0) {
                memcpy(st->language, language, 4);
            }

            if (stream_type == STREAM_TYPE_SUBTITLE_DVB) {
                st->codec->sub_id = (anc_page << 16) | comp_page;
            }
        }
    }
    /* all parameters are there */
    ts->stop_parse++;
    mpegts_close_filter(ts, filter);
}
Exemple #5
0
static void sdt_cb(void *opaque, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = opaque;
    SectionHeader h1, *h = &h1;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
    char *name, *provider_name;

#ifdef DEBUG_SI
    printf("SDT:\n");
    av_hex_dump(stdout, (uint8_t *)section, section_len);
#endif

    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
    if (h->tid != SDT_TID)
        return;
    onid = get16(&p, p_end);
    if (onid < 0)
        return;
    val = get8(&p, p_end);
    if (val < 0)
        return;
    for(;;) {
        sid = get16(&p, p_end);
        if (sid < 0)
            break;
        val = get8(&p, p_end);
        if (val < 0)
            break;
        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            desc_len = get8(&p, desc_list_end);
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;
#ifdef DEBUG_SI
            printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
#endif
            switch(desc_tag) {
            case 0x48:
                service_type = get8(&p, p_end);
                if (service_type < 0)
                    break;
                provider_name = getstr8(&p, p_end);
                if (!provider_name)
                    break;
                name = getstr8(&p, p_end);
                if (!name)
                    break;
                new_service(ts, sid, provider_name, name);
                break;
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;
    }
    ts->stop_parse = 1;

    /* remove filter */
    mpegts_close_filter(ts, ts->sdt_filter);
    ts->sdt_filter = NULL;
}
Exemple #6
0
static void pmt_cb(void *opaque, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = opaque;
    SectionHeader h1, *h = &h1;
    const uint8_t *p, *p_end;
    int program_info_length, pcr_pid, pid, stream_type, desc_length;
    
#ifdef DEBUG_SI
    printf("PMT:\n");
    av_hex_dump(stdout, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
#ifdef DEBUG_SI
    printf("sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num);
#endif
    if (h->tid != PMT_TID || (ts->req_sid >= 0 && h->id != ts->req_sid) )
        return;

    pcr_pid = get16(&p, p_end) & 0x1fff;
    if (pcr_pid < 0)
        return;
    ts->pcr_pid = pcr_pid;
#ifdef DEBUG_SI
    printf("pcr_pid=0x%x\n", pcr_pid);
#endif
    program_info_length = get16(&p, p_end) & 0xfff;
    if (program_info_length < 0)
        return;
    p += program_info_length;
    if (p >= p_end)
        return;
    for(;;) {
        stream_type = get8(&p, p_end);
        if (stream_type < 0)
            break;
        pid = get16(&p, p_end) & 0x1fff;
        if (pid < 0)
            break;
        desc_length = get16(&p, p_end) & 0xfff;
        if (desc_length < 0)
            break;
        p += desc_length;
        if (p > p_end)
            return;

#ifdef DEBUG_SI
        printf("stream_type=%d pid=0x%x\n", stream_type, pid);
#endif

        /* now create ffmpeg stream */
        switch(stream_type) {
        case STREAM_TYPE_AUDIO_MPEG1:
        case STREAM_TYPE_AUDIO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG1:
        case STREAM_TYPE_VIDEO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG4:
        case STREAM_TYPE_VIDEO_H264:
        case STREAM_TYPE_AUDIO_AAC:
        case STREAM_TYPE_AUDIO_AC3:
            add_pes_stream(ts, pid, stream_type);
            break;
        default:
            /* we ignore the other streams */
            break;
        }
    }
    /* all parameters are there */
    ts->set_service_cb(ts->set_service_opaque, 0);
    mpegts_close_filter(ts, ts->pmt_filter);
    ts->pmt_filter = NULL;
}
Exemple #7
0
static void pmt_cb(void *opaque, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = opaque;
    SectionHeader h1, *h = &h1;
    PESContext *pes;
    AVStream *st;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int program_info_length, pcr_pid, pid, stream_type;
    int desc_list_len, desc_len, desc_tag;
    int comp_page = 0, anc_page = 0; /* initialize to kill warnings */
    char language[4];

#ifdef DEBUG_SI
    printf("PMT:\n");
    av_hex_dump(stdout, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
#ifdef DEBUG_SI
    printf("sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num);
#endif
    if (h->tid != PMT_TID || (ts->req_sid >= 0 && h->id != ts->req_sid) )
        return;

    pcr_pid = get16(&p, p_end) & 0x1fff;
    if (pcr_pid < 0)
        return;
    ts->pcr_pid = pcr_pid;
#ifdef DEBUG_SI
    printf("pcr_pid=0x%x\n", pcr_pid);
#endif
    program_info_length = get16(&p, p_end) & 0xfff;
    if (program_info_length < 0)
        return;
    p += program_info_length;
    if (p >= p_end)
        return;
    for(;;) {
        language[0] = 0;
        st = 0;
        stream_type = get8(&p, p_end);
        if (stream_type < 0)
            break;
        pid = get16(&p, p_end) & 0x1fff;
        if (pid < 0)
            break;
        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            if (stream_type == STREAM_TYPE_PRIVATE_DATA) {
                if((desc_tag == 0x6A) || (desc_tag == 0x7A)) {
                    /*assume DVB AC-3 Audio*/
                    stream_type = STREAM_TYPE_AUDIO_AC3;
                } else if(desc_tag == 0x7B) {
                    /* DVB DTS audio */
                    stream_type = STREAM_TYPE_AUDIO_DTS;
                }
            }
            desc_len = get8(&p, desc_list_end);
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;
#ifdef DEBUG_SI
            printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
#endif
            switch(desc_tag) {
            case DVB_SUBT_DESCID:
                if (stream_type == STREAM_TYPE_PRIVATE_DATA)
                    stream_type = STREAM_TYPE_SUBTITLE_DVB;

                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                get8(&p, desc_end);
                comp_page = get16(&p, desc_end);
                anc_page = get16(&p, desc_end);

                break;
            case 0x0a: /* ISO 639 language descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                break;
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;

#ifdef DEBUG_SI
        printf("stream_type=%d pid=0x%x\n", stream_type, pid);
#endif

        /* now create ffmpeg stream */
        switch(stream_type) {
        case STREAM_TYPE_AUDIO_MPEG1:
        case STREAM_TYPE_AUDIO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG1:
        case STREAM_TYPE_VIDEO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG4:
        case STREAM_TYPE_VIDEO_H264:
        case STREAM_TYPE_AUDIO_AAC:
        case STREAM_TYPE_AUDIO_AC3:
        case STREAM_TYPE_AUDIO_DTS:
        case STREAM_TYPE_SUBTITLE_DVB:
            pes = add_pes_stream(ts, pid, stream_type);
            if (pes)
                st = new_pes_av_stream(pes, 0);
            break;
        default:
            /* we ignore the other streams */
            break;
        }

        if (st) {
            if (language[0] != 0) {
                st->language[0] = language[0];
                st->language[1] = language[1];
                st->language[2] = language[2];
                st->language[3] = language[3];
            }

            if (stream_type == STREAM_TYPE_SUBTITLE_DVB) {
                st->codec->sub_id = (anc_page << 16) | comp_page;
            }
        }
    }
    /* all parameters are there */
    ts->set_service_cb(ts->set_service_opaque, 0);
    mpegts_close_filter(ts, ts->pmt_filter);
    ts->pmt_filter = NULL;
}
Exemple #8
0
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = filter->u.section_filter.opaque;
    SectionHeader h1, *h = &h1;
    PESContext *pes;
    AVStream *st;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int program_info_length, pcr_pid, pid, stream_type;
    int desc_list_len, desc_len, desc_tag;
    int comp_page = 0, anc_page = 0; /* initialize to kill warnings */
    char language[4] = {0}; /* initialize to kill warnings */

#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "PMT: len %i\n", section_len);
    av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
#endif
    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "sid=0x%x sec_num=%d/%d\n",
           h->id, h->sec_num, h->last_sec_num);
#endif
    if (h->tid != PMT_TID)
        return;

    clear_program(ts, h->id);
    pcr_pid = get16(&p, p_end) & 0x1fff;
    if (pcr_pid < 0)
        return;
    add_pid_to_pmt(ts, h->id, pcr_pid);
#ifdef DEBUG_SI
    av_log(ts->stream, AV_LOG_DEBUG, "pcr_pid=0x%x\n", pcr_pid);
#endif
    program_info_length = get16(&p, p_end) & 0xfff;
    if (program_info_length < 0)
        return;
    p += program_info_length;
    if (p >= p_end)
        return;
    for(;;) {
        language[0] = 0;
        st = 0;
        stream_type = get8(&p, p_end);
        if (stream_type < 0)
            break;
        pid = get16(&p, p_end) & 0x1fff;
        if (pid < 0)
            break;
        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            if (stream_type == STREAM_TYPE_PRIVATE_DATA) {
                if((desc_tag == 0x6A) || (desc_tag == 0x7A)) {
                    /*assume DVB AC-3 Audio*/
                    stream_type = STREAM_TYPE_AUDIO_AC3;
                } else if(desc_tag == 0x7B) {
                    /* DVB DTS audio */
                    stream_type = STREAM_TYPE_AUDIO_DTS;
                }
            }
            desc_len = get8(&p, desc_list_end);
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;
#ifdef DEBUG_SI
            av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n",
                   desc_tag, desc_len);
#endif
            switch(desc_tag) {
            case DVB_SUBT_DESCID:
                if (stream_type == STREAM_TYPE_PRIVATE_DATA)
                    stream_type = STREAM_TYPE_SUBTITLE_DVB;

                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                get8(&p, desc_end);
                comp_page = get16(&p, desc_end);
                anc_page = get16(&p, desc_end);

                break;
            case 0x0a: /* ISO 639 language descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                break;
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;

#ifdef DEBUG_SI
        av_log(ts->stream, AV_LOG_DEBUG, "stream_type=%d pid=0x%x\n",
               stream_type, pid);
#endif

        /* now create ffmpeg stream */
        switch(stream_type) {
        case STREAM_TYPE_AUDIO_MPEG1:
        case STREAM_TYPE_AUDIO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG1:
        case STREAM_TYPE_VIDEO_MPEG2:
        case STREAM_TYPE_VIDEO_MPEG4:
        case STREAM_TYPE_VIDEO_H264:
        case STREAM_TYPE_VIDEO_VC1:
        case STREAM_TYPE_AUDIO_AAC:
        case STREAM_TYPE_AUDIO_AC3:
        case STREAM_TYPE_AUDIO_DTS:
        case STREAM_TYPE_SUBTITLE_DVB:
            if(ts->pids[pid]){
                assert(ts->pids[pid]->type == MPEGTS_PES);
                pes= ts->pids[pid]->u.pes_filter.opaque;
                st= pes->st;
            }else{
                pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
                if (pes)
                    st = new_pes_av_stream(pes, 0);
            }
            add_pid_to_pmt(ts, h->id, pid);
            break;
        default:
            /* we ignore the other streams */
            break;
        }

        if (st) {
            if (language[0] != 0) {
                memcpy(st->language, language, 4);
            }

            if (stream_type == STREAM_TYPE_SUBTITLE_DVB) {
                st->codec->sub_id = (anc_page << 16) | comp_page;
            }
        }
    }
    /* all parameters are there */
    ts->stop_parse++;
    mpegts_close_filter(ts, filter);
}
Exemple #9
0
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = filter->u.section_filter.opaque;
    SectionHeader h1, *h = &h1;
    PESContext *pes;
    AVStream *st;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int program_info_length, pcr_pid, pid, stream_type;
    int desc_list_len, desc_len, desc_tag;
    int comp_page, anc_page;
    char language[4];
    uint32_t prog_reg_desc = 0; /* registration descriptor */

#ifdef DEBUG
    dprintf(ts->stream, "PMT: len %i\n", section_len);
    av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
#endif

    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;

    dprintf(ts->stream, "sid=0x%x sec_num=%d/%d\n",
           h->id, h->sec_num, h->last_sec_num);

    if (h->tid != PMT_TID)
        return;

    clear_program(ts, h->id);
    pcr_pid = get16(&p, p_end) & 0x1fff;
    if (pcr_pid < 0)
        return;
    add_pid_to_pmt(ts, h->id, pcr_pid);

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

    program_info_length = get16(&p, p_end) & 0xfff;
    if (program_info_length < 0)
        return;
    while(program_info_length >= 2) {
        uint8_t tag, len;
        tag = get8(&p, p_end);
        len = get8(&p, p_end);
        if(len > program_info_length - 2)
            //something else is broken, exit the program_descriptors_loop
            break;
        program_info_length -= len + 2;
        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)
        return;
    for(;;) {
        st = 0;
        stream_type = get8(&p, p_end);
        if (stream_type < 0)
            break;
        pid = get16(&p, p_end) & 0x1fff;
        if (pid < 0)
            break;

        /* now create ffmpeg stream */
        if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
            pes = ts->pids[pid]->u.pes_filter.opaque;
            st = pes->st;
        } else {
            if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
            pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
            if (pes)
                st = new_pes_av_stream(pes, prog_reg_desc, 0);
        }

        if (!st)
            return;

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

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

        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            desc_len = get8(&p, desc_list_end);
            if (desc_len < 0)
                break;
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;

            dprintf(ts->stream, "tag: 0x%02x len=%d\n",
                   desc_tag, desc_len);

            if (st->codec->codec_id == CODEC_ID_PROBE &&
                stream_type == STREAM_TYPE_PRIVATE_DATA)
                mpegts_find_stream_type(st, desc_tag, DESC_types);

            switch(desc_tag) {
            case 0x59: /* subtitling descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                get8(&p, desc_end);
                comp_page = get16(&p, desc_end);
                anc_page = get16(&p, desc_end);
                st->codec->sub_id = (anc_page << 16) | comp_page;
                av_metadata_set(&st->metadata, "language", language);
                break;
            case 0x0a: /* ISO 639 language descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                av_metadata_set(&st->metadata, "language", language);
                break;
            case 0x05: /* registration descriptor */
                st->codec->codec_tag = bytestream_get_le32(&p);
                dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag);
                if (st->codec->codec_id == CODEC_ID_PROBE &&
                    stream_type == STREAM_TYPE_PRIVATE_DATA)
                    mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
                break;
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;
    }
    /* all parameters are there */
    ts->stop_parse++;
    mpegts_close_filter(ts, filter);
}