⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
    /* stuffing */    for(;;) {        if (len < 1)            goto error_redo;        c = get_byte(s->pb);        len--;        /* XXX: for mpeg1, should test only bit 7 */        if (c != 0xff)            break;    }    if ((c & 0xc0) == 0x40) {        /* buffer scale & size */        get_byte(s->pb);        c = get_byte(s->pb);        len -= 2;    }    if ((c & 0xe0) == 0x20) {        dts = pts = get_pts(s->pb, c);        len -= 4;        if (c & 0x10){            dts = get_pts(s->pb, -1);            len -= 5;        }    } else if ((c & 0xc0) == 0x80) {        /* mpeg 2 PES */#if 0 /* some streams have this field set for no apparent reason */        if ((c & 0x30) != 0) {            /* Encrypted multiplex not handled */            goto redo;        }#endif        flags = get_byte(s->pb);        header_len = get_byte(s->pb);        len -= 2;        if (header_len > len)            goto error_redo;        len -= header_len;        if (flags & 0x80) {            dts = pts = get_pts(s->pb, -1);            header_len -= 5;            if (flags & 0x40) {                dts = get_pts(s->pb, -1);                header_len -= 5;            }        }        if (flags & 0x01) { /* PES extension */            pes_ext = get_byte(s->pb);            header_len--;            if (pes_ext & 0x40) { /* pack header - should be zero in PS */                goto error_redo;            }            /* Skip PES private data, program packet sequence counter and P-STD buffer */            skip = (pes_ext >> 4) & 0xb;            skip += skip & 0x9;            url_fskip(s->pb, skip);            header_len -= skip;            if (pes_ext & 0x01) { /* PES extension 2 */                ext2_len = get_byte(s->pb);                header_len--;                if ((ext2_len & 0x7f) > 0) {                    id_ext = get_byte(s->pb);                    if ((id_ext & 0x80) == 0)                        startcode = ((startcode & 0xff) << 8) | id_ext;                    header_len--;                }            }        }        if(header_len < 0)            goto error_redo;        url_fskip(s->pb, header_len);    }    else if( c!= 0xf )        goto redo;    if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {        startcode = get_byte(s->pb);        len--;        if (startcode >= 0x80 && startcode <= 0xcf) {            /* audio: skip header */            get_byte(s->pb);            get_byte(s->pb);            get_byte(s->pb);            len -= 3;            if (startcode >= 0xb0 && startcode <= 0xbf) {                /* MLP/TrueHD audio has a 4-byte header */                get_byte(s->pb);                len--;            }        }    }    if(len<0)        goto error_redo;    if(dts != AV_NOPTS_VALUE && ppos){        int i;        for(i=0; i<s->nb_streams; i++){            if(startcode == s->streams[i]->id &&               !url_is_streamed(s->pb) /* index useless on streams anyway */) {                ff_reduce_index(s, i);                av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);            }        }    }    *pstart_code = startcode;    *ppts = pts;    *pdts = dts;    return len;}static int mpegps_read_packet(AVFormatContext *s,                              AVPacket *pkt){    MpegDemuxContext *m = s->priv_data;    AVStream *st;    int len, startcode, i, type, codec_id = 0, es_type;    int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work redo:    len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);    if (len < 0)        return len;    /* now find stream */    for(i=0;i<s->nb_streams;i++) {        st = s->streams[i];        if (st->id == startcode)            goto found;    }    es_type = m->psm_es_type[startcode & 0xff];    if(es_type > 0){        if(es_type == STREAM_TYPE_VIDEO_MPEG1){            codec_id = CODEC_ID_MPEG2VIDEO;            type = CODEC_TYPE_VIDEO;        } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){            codec_id = CODEC_ID_MPEG2VIDEO;            type = CODEC_TYPE_VIDEO;        } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 ||                  es_type == STREAM_TYPE_AUDIO_MPEG2){            codec_id = CODEC_ID_MP3;            type = CODEC_TYPE_AUDIO;        } else if(es_type == STREAM_TYPE_AUDIO_AAC){            codec_id = CODEC_ID_AAC;            type = CODEC_TYPE_AUDIO;        } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){            codec_id = CODEC_ID_MPEG4;            type = CODEC_TYPE_VIDEO;        } else if(es_type == STREAM_TYPE_VIDEO_H264){            codec_id = CODEC_ID_H264;            type = CODEC_TYPE_VIDEO;        } else if(es_type == STREAM_TYPE_AUDIO_AC3){            codec_id = CODEC_ID_AC3;            type = CODEC_TYPE_AUDIO;        } else {            goto skip;        }    } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {        static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };        unsigned char buf[8];        get_buffer(s->pb, buf, 8);        url_fseek(s->pb, -8, SEEK_CUR);        if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))            codec_id = CODEC_ID_CAVS;        else            codec_id = CODEC_ID_MPEG2VIDEO;        type = CODEC_TYPE_VIDEO;    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {        type = CODEC_TYPE_AUDIO;        codec_id = m->sofdec > 0 ? CODEC_ID_ADPCM_ADX : CODEC_ID_MP2;    } else if (startcode >= 0x80 && startcode <= 0x87) {        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_AC3;    } else if ((startcode >= 0x88 && startcode <= 0x8f)               ||( startcode >= 0x98 && startcode <= 0x9f)) {        /* 0x90 - 0x97 is reserved for SDDS in DVD specs */        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_DTS;    } else if (startcode >= 0xa0 && startcode <= 0xaf) {        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_PCM_S16BE;    } else if (startcode >= 0xb0 && startcode <= 0xbf) {        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_MLP;    } else if (startcode >= 0xc0 && startcode <= 0xcf) {        /* Used for both AC-3 and E-AC-3 in EVOB files */        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_AC3;    } else if (startcode >= 0x20 && startcode <= 0x3f) {        type = CODEC_TYPE_SUBTITLE;        codec_id = CODEC_ID_DVD_SUBTITLE;    } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {        type = CODEC_TYPE_VIDEO;        codec_id = CODEC_ID_VC1;    } else {    skip:        /* skip packet */        url_fskip(s->pb, len);        goto redo;    }    /* no stream found: add a new stream */    st = av_new_stream(s, startcode);    if (!st)        goto skip;    st->codec->codec_type = type;    st->codec->codec_id = codec_id;    if (codec_id != CODEC_ID_PCM_S16BE)        st->need_parsing = AVSTREAM_PARSE_FULL; found:    if(st->discard >= AVDISCARD_ALL)        goto skip;    if (startcode >= 0xa0 && startcode <= 0xaf) {        int b1, freq;        /* for LPCM, we just skip the header and consider it is raw           audio data */        if (len <= 3)            goto skip;        get_byte(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */        b1 = get_byte(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */        get_byte(s->pb); /* dynamic range control (0x80 = off) */        len -= 3;        freq = (b1 >> 4) & 3;        st->codec->sample_rate = lpcm_freq_tab[freq];        st->codec->channels = 1 + (b1 & 7);        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 2;    }    av_new_packet(pkt, len);    get_buffer(s->pb, pkt->data, pkt->size);    pkt->pts = pts;    pkt->dts = dts;    pkt->stream_index = st->index;#if 0    av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n",           pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size);#endif    return 0;}static int mpegps_read_close(AVFormatContext *s){    return 0;}static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,                               int64_t *ppos, int64_t pos_limit){    int len, startcode;    int64_t pos, pts, dts;    pos = *ppos;#ifdef DEBUG_SEEK    printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next);#endif    url_fseek(s->pb, pos, SEEK_SET);    for(;;) {        len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);        if (len < 0) {#ifdef DEBUG_SEEK            printf("none (ret=%d)\n", len);#endif            return AV_NOPTS_VALUE;        }        if (startcode == s->streams[stream_index]->id &&            dts != AV_NOPTS_VALUE) {            break;        }        url_fskip(s->pb, len);    }#ifdef DEBUG_SEEK    printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0);#endif    *ppos = pos;    return dts;}AVInputFormat mpegps_demuxer = {    "mpeg",    "MPEG PS format",    sizeof(MpegDemuxContext),    mpegps_probe,    mpegps_read_header,    mpegps_read_packet,    mpegps_read_close,    NULL, //mpegps_read_seek,    mpegps_read_dts,    .flags = AVFMT_SHOW_IDS,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -