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

📄 mpeg.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    val = -1; found:    *header_state = state;    *size_ptr = n;    return val;}/* XXX: optimize */static int find_prev_start_code(ByteIOContext *pb, int *size_ptr){    int64_t pos, pos_start;    int max_size, start_code;    max_size = *size_ptr;    pos_start = url_ftell(pb);    /* in order to go faster, we fill the buffer */    pos = pos_start - 16386;    if (pos < 0)        pos = 0;    url_fseek(pb, pos, SEEK_SET);    get_byte(pb);    pos = pos_start;    for(;;) {        pos--;        if (pos < 0 || (pos_start - pos) >= max_size) {            start_code = -1;            goto the_end;        }        url_fseek(pb, pos, SEEK_SET);        start_code = get_be32(pb);        if ((start_code & 0xffffff00) == 0x100)            break;    } the_end:    *size_ptr = pos_start - pos;    return start_code;}/* read the next PES header. Return its position in ppos    (if not NULL), and its start code, pts and dts. */static int mpegps_read_pes_header(AVFormatContext *s,                                  int64_t *ppos, int *pstart_code,                                   int64_t *ppts, int64_t *pdts){    MpegDemuxContext *m = s->priv_data;    int len, size, startcode, c, flags, header_len;    int64_t pts, dts, last_pos;    last_pos = -1; redo:        /* next start code (should be immediately after) */        m->header_state = 0xff;        size = MAX_SYNC_SIZE;        startcode = find_next_start_code(&s->pb, &size, &m->header_state);    //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb));    if (startcode < 0)        return AVERROR_IO;    if (startcode == PACK_START_CODE)        goto redo;    if (startcode == SYSTEM_HEADER_START_CODE)        goto redo;    if (startcode == PADDING_STREAM ||        startcode == PRIVATE_STREAM_2) {        /* skip them */        len = get_be16(&s->pb);        url_fskip(&s->pb, len);        goto redo;    }    /* find matching stream */    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||          (startcode >= 0x1e0 && startcode <= 0x1ef) ||          (startcode == 0x1bd)))        goto redo;    if (ppos) {        *ppos = url_ftell(&s->pb) - 4;    }    len = get_be16(&s->pb);    pts = AV_NOPTS_VALUE;    dts = AV_NOPTS_VALUE;    /* stuffing */    for(;;) {        if (len < 1)            goto 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 */        if (len < 2)            goto redo;        get_byte(&s->pb);        c = get_byte(&s->pb);        len -= 2;    }    if ((c & 0xf0) == 0x20) {        if (len < 4)            goto redo;        dts = pts = get_pts(&s->pb, c);        len -= 4;    } else if ((c & 0xf0) == 0x30) {        if (len < 9)            goto redo;        pts = get_pts(&s->pb, c);        dts = get_pts(&s->pb, -1);        len -= 9;    } else if ((c & 0xc0) == 0x80) {        /* mpeg 2 PES */        if ((c & 0x30) != 0) {            /* Encrypted multiplex not handled */            goto redo;        }        flags = get_byte(&s->pb);        header_len = get_byte(&s->pb);        len -= 2;        if (header_len > len)            goto redo;        if ((flags & 0xc0) == 0x80) {            dts = pts = get_pts(&s->pb, -1);            if (header_len < 5)                goto redo;            header_len -= 5;            len -= 5;        } if ((flags & 0xc0) == 0xc0) {            pts = get_pts(&s->pb, -1);            dts = get_pts(&s->pb, -1);            if (header_len < 10)                goto redo;            header_len -= 10;            len -= 10;        }        len -= header_len;        while (header_len > 0) {            get_byte(&s->pb);            header_len--;        }    }    else if( c!= 0xf )        goto redo;    if (startcode == 0x1bd) {        if (len < 1)            goto redo;        startcode = get_byte(&s->pb);        len--;        if (startcode >= 0x80 && startcode <= 0xbf) {            /* audio: skip header */            if (len < 3)                goto redo;            get_byte(&s->pb);            get_byte(&s->pb);            get_byte(&s->pb);            len -= 3;        }    }    if(dts != AV_NOPTS_VALUE && ppos){        int i;        for(i=0; i<s->nb_streams; i++){            if(startcode == s->streams[i]->id) {                av_add_index_entry(s->streams[i], *ppos, dts, 0, 0 /* FIXME keyframe? */);            }        }    }        *pstart_code = startcode;    *ppts = pts;    *pdts = dts;    return len;}static int mpegps_read_packet(AVFormatContext *s,                              AVPacket *pkt){    AVStream *st;    int len, startcode, i, type, codec_id = 0;    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;    }    if (startcode >= 0x1e0 && startcode <= 0x1ef) {        type = CODEC_TYPE_VIDEO;        codec_id = CODEC_ID_MPEG2VIDEO;    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_MP2;    } else if (startcode >= 0x80 && startcode <= 0x9f) {        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_AC3;    } else if (startcode >= 0xa0 && startcode <= 0xbf) {        type = CODEC_TYPE_AUDIO;        codec_id = CODEC_ID_PCM_S16BE;    } 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 = 1; found:    if (startcode >= 0xa0 && startcode <= 0xbf) {        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\n",           pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0);#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%llx 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%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0);#endif    *ppos = pos;    return dts;}#ifdef CONFIG_ENCODERSstatic AVOutputFormat mpeg1system_mux = {    "mpeg",    "MPEG1 System format",    "video/mpeg",    "mpg,mpeg",    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG1VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};static AVOutputFormat mpeg1vcd_mux = {    "vcd",    "MPEG1 System format (VCD)",    "video/mpeg",    NULL,    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG1VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};static AVOutputFormat mpeg2vob_mux = {    "vob",    "MPEG2 PS format (VOB)",    "video/mpeg",    "vob",    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG2VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};/* Same as mpeg2vob_mux except that the pack size is 2324 */static AVOutputFormat mpeg2svcd_mux = {    "svcd",    "MPEG2 PS format (VOB)",    "video/mpeg",    "vob",    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG2VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};#endif //CONFIG_ENCODERSAVInputFormat mpegps_demux = {    "mpeg",    "MPEG PS format",    sizeof(MpegDemuxContext),    mpegps_probe,    mpegps_read_header,    mpegps_read_packet,    mpegps_read_close,    NULL, //mpegps_read_seek,    mpegps_read_dts,};int mpegps_init(void){#ifdef CONFIG_ENCODERS    av_register_output_format(&mpeg1system_mux);    av_register_output_format(&mpeg1vcd_mux);    av_register_output_format(&mpeg2vob_mux);    av_register_output_format(&mpeg2svcd_mux);#endif //CONFIG_ENCODERS    av_register_input_format(&mpegps_demux);    return 0;}

⌨️ 快捷键说明

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