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

📄 mpeg.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * MPEG1/2 mux/demux * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "avformat.h"#include "bitstream.h"#define MAX_PAYLOAD_SIZE 4096//#define DEBUG_SEEK#undef NDEBUG#include <assert.h>typedef struct PacketDesc {    int64_t pts;    int64_t dts;    int size;    int unwritten_size;    int flags;    struct PacketDesc *next;} PacketDesc;typedef struct {    FifoBuffer fifo;    uint8_t id;    int max_buffer_size; /* in bytes */    int buffer_index;    PacketDesc *predecode_packet;    PacketDesc *premux_packet;    PacketDesc **next_packet;    int packet_number;    uint8_t lpcm_header[3];    int lpcm_align;    uint8_t *fifo_iframe_ptr;    int align_iframe;    int64_t vobu_start_pts;} StreamInfo;typedef struct {    int packet_size; /* required packet size */    int packet_number;    int pack_header_freq;     /* frequency (in packets^-1) at which we send pack headers */    int system_header_freq;    int system_header_size;    int mux_rate; /* bitrate in units of 50 bytes/s */    /* stream info */    int audio_bound;    int video_bound;    int is_mpeg2;    int is_vcd;    int is_svcd;    int is_dvd;    int64_t last_scr; /* current system clock */    double vcd_padding_bitrate; //FIXME floats    int64_t vcd_padding_bytes_written;} MpegMuxContext;#define PACK_START_CODE             ((unsigned int)0x000001ba)#define SYSTEM_HEADER_START_CODE    ((unsigned int)0x000001bb)#define SEQUENCE_END_CODE           ((unsigned int)0x000001b7)#define PACKET_START_CODE_MASK      ((unsigned int)0xffffff00)#define PACKET_START_CODE_PREFIX    ((unsigned int)0x00000100)#define ISO_11172_END_CODE          ((unsigned int)0x000001b9)/* mpeg2 */#define PROGRAM_STREAM_MAP 0x1bc#define PRIVATE_STREAM_1   0x1bd#define PADDING_STREAM     0x1be#define PRIVATE_STREAM_2   0x1bf#define AUDIO_ID 0xc0#define VIDEO_ID 0xe0#define AC3_ID   0x80#define DTS_ID   0x8a#define LPCM_ID  0xa0#define SUB_ID   0x20#define STREAM_TYPE_VIDEO_MPEG1     0x01#define STREAM_TYPE_VIDEO_MPEG2     0x02#define STREAM_TYPE_AUDIO_MPEG1     0x03#define STREAM_TYPE_AUDIO_MPEG2     0x04#define STREAM_TYPE_PRIVATE_SECTION 0x05#define STREAM_TYPE_PRIVATE_DATA    0x06#define STREAM_TYPE_AUDIO_AAC       0x0f#define STREAM_TYPE_VIDEO_MPEG4     0x10#define STREAM_TYPE_VIDEO_H264      0x1b#define STREAM_TYPE_AUDIO_AC3       0x81#define STREAM_TYPE_AUDIO_DTS       0x8astatic const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };#ifdef CONFIG_MUXERSstatic AVOutputFormat mpeg1system_mux;static AVOutputFormat mpeg1vcd_mux;static AVOutputFormat mpeg2vob_mux;static AVOutputFormat mpeg2svcd_mux;static AVOutputFormat mpeg2dvd_mux;static int put_pack_header(AVFormatContext *ctx,                           uint8_t *buf, int64_t timestamp){    MpegMuxContext *s = ctx->priv_data;    PutBitContext pb;    init_put_bits(&pb, buf, 128);    put_bits(&pb, 32, PACK_START_CODE);    if (s->is_mpeg2) {        put_bits(&pb, 2, 0x1);    } else {        put_bits(&pb, 4, 0x2);    }    put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07));    put_bits(&pb, 1, 1);    put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff));    put_bits(&pb, 1, 1);    put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff));    put_bits(&pb, 1, 1);    if (s->is_mpeg2) {        /* clock extension */        put_bits(&pb, 9, 0);    }    put_bits(&pb, 1, 1);    put_bits(&pb, 22, s->mux_rate);    put_bits(&pb, 1, 1);    if (s->is_mpeg2) {        put_bits(&pb, 1, 1);        put_bits(&pb, 5, 0x1f); /* reserved */        put_bits(&pb, 3, 0); /* stuffing length */    }    flush_put_bits(&pb);    return pbBufPtr(&pb) - pb.buf;}static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_stream_id){    MpegMuxContext *s = ctx->priv_data;    int size, i, private_stream_coded, id;    PutBitContext pb;    init_put_bits(&pb, buf, 128);    put_bits(&pb, 32, SYSTEM_HEADER_START_CODE);    put_bits(&pb, 16, 0);    put_bits(&pb, 1, 1);    put_bits(&pb, 22, s->mux_rate); /* maximum bit rate of the multiplexed stream */    put_bits(&pb, 1, 1); /* marker */    if (s->is_vcd && only_for_stream_id==VIDEO_ID) {        /* This header applies only to the video stream (see VCD standard p. IV-7)*/        put_bits(&pb, 6, 0);    } else        put_bits(&pb, 6, s->audio_bound);    if (s->is_vcd) {        /* see VCD standard, p. IV-7*/        put_bits(&pb, 1, 0);        put_bits(&pb, 1, 1);    } else {        put_bits(&pb, 1, 0); /* variable bitrate*/        put_bits(&pb, 1, 0); /* non constrainted bit stream */    }    if (s->is_vcd || s->is_dvd) {        /* see VCD standard p IV-7 */        put_bits(&pb, 1, 1); /* audio locked */        put_bits(&pb, 1, 1); /* video locked */    } else {        put_bits(&pb, 1, 0); /* audio locked */        put_bits(&pb, 1, 0); /* video locked */    }    put_bits(&pb, 1, 1); /* marker */    if (s->is_vcd && only_for_stream_id==AUDIO_ID) {        /* This header applies only to the audio stream (see VCD standard p. IV-7)*/        put_bits(&pb, 5, 0);    } else        put_bits(&pb, 5, s->video_bound);    if (s->is_dvd) {        put_bits(&pb, 1, 0);    /* packet_rate_restriction_flag */        put_bits(&pb, 7, 0x7f); /* reserved byte */    } else        put_bits(&pb, 8, 0xff); /* reserved byte */    /* DVD-Video Stream_bound entries    id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1)    id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0)    id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1)    id (0xBF) private stream 2, NAV packs, set to 2x1024. */    if (s->is_dvd) {        int P_STD_max_video = 0;        int P_STD_max_mpeg_audio = 0;        int P_STD_max_mpeg_PS1 = 0;        for(i=0;i<ctx->nb_streams;i++) {            StreamInfo *stream = ctx->streams[i]->priv_data;            id = stream->id;            if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) {                P_STD_max_mpeg_PS1 = stream->max_buffer_size;            } else if (id >= 0xc0 && id <= 0xc7 && stream->max_buffer_size > P_STD_max_mpeg_audio) {                P_STD_max_mpeg_audio = stream->max_buffer_size;            } else if (id == 0xe0 && stream->max_buffer_size > P_STD_max_video) {                P_STD_max_video = stream->max_buffer_size;            }        }        /* video */        put_bits(&pb, 8, 0xb9); /* stream ID */        put_bits(&pb, 2, 3);        put_bits(&pb, 1, 1);        put_bits(&pb, 13, P_STD_max_video / 1024);        /* audio */        if (P_STD_max_mpeg_audio == 0)            P_STD_max_mpeg_audio = 4096;        put_bits(&pb, 8, 0xb8); /* stream ID */        put_bits(&pb, 2, 3);        put_bits(&pb, 1, 0);        put_bits(&pb, 13, P_STD_max_mpeg_audio / 128);        /* private stream 1 */        put_bits(&pb, 8, 0xbd); /* stream ID */        put_bits(&pb, 2, 3);        put_bits(&pb, 1, 0);        put_bits(&pb, 13, P_STD_max_mpeg_PS1 / 128);        /* private stream 2 */        put_bits(&pb, 8, 0xbf); /* stream ID */        put_bits(&pb, 2, 3);        put_bits(&pb, 1, 1);        put_bits(&pb, 13, 2);    }    else {        /* audio stream info */        private_stream_coded = 0;        for(i=0;i<ctx->nb_streams;i++) {            StreamInfo *stream = ctx->streams[i]->priv_data;            /* For VCDs, only include the stream info for the stream            that the pack which contains this system belongs to.            (see VCD standard p. IV-7) */            if ( !s->is_vcd || stream->id==only_for_stream_id                || only_for_stream_id==0) {                id = stream->id;                if (id < 0xc0) {                    /* special case for private streams (AC3 use that) */                    if (private_stream_coded)                        continue;                    private_stream_coded = 1;                    id = 0xbd;                }                put_bits(&pb, 8, id); /* stream ID */                put_bits(&pb, 2, 3);                if (id < 0xe0) {                    /* audio */                    put_bits(&pb, 1, 0);                    put_bits(&pb, 13, stream->max_buffer_size / 128);                } else {                    /* video */                    put_bits(&pb, 1, 1);                    put_bits(&pb, 13, stream->max_buffer_size / 1024);                }            }        }    }    flush_put_bits(&pb);    size = pbBufPtr(&pb) - pb.buf;    /* patch packet size */    buf[4] = (size - 6) >> 8;    buf[5] = (size - 6) & 0xff;    return size;}static int get_system_header_size(AVFormatContext *ctx){    int buf_index, i, private_stream_coded;    StreamInfo *stream;    MpegMuxContext *s = ctx->priv_data;    if (s->is_dvd)       return 18; // DVD-Video system headers are 18 bytes fixed length.    buf_index = 12;    private_stream_coded = 0;    for(i=0;i<ctx->nb_streams;i++) {        stream = ctx->streams[i]->priv_data;        if (stream->id < 0xc0) {            if (private_stream_coded)                continue;            private_stream_coded = 1;        }        buf_index += 3;    }    return buf_index;}static int mpeg_mux_init(AVFormatContext *ctx){    MpegMuxContext *s = ctx->priv_data;    int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j;    AVStream *st;    StreamInfo *stream;    int audio_bitrate;    int video_bitrate;    s->packet_number = 0;    s->is_vcd = (ctx->oformat == &mpeg1vcd_mux);    s->is_svcd = (ctx->oformat == &mpeg2svcd_mux);    s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux || ctx->oformat == &mpeg2svcd_mux || ctx->oformat == &mpeg2dvd_mux);    s->is_dvd = (ctx->oformat == &mpeg2dvd_mux);    if(ctx->packet_size)        s->packet_size = ctx->packet_size;    else        s->packet_size = 2048;    s->vcd_padding_bytes_written = 0;    s->vcd_padding_bitrate=0;    s->audio_bound = 0;    s->video_bound = 0;    mpa_id = AUDIO_ID;    ac3_id = AC3_ID;    dts_id = DTS_ID;    mpv_id = VIDEO_ID;    mps_id = SUB_ID;    lpcm_id = LPCM_ID;    for(i=0;i<ctx->nb_streams;i++) {        st = ctx->streams[i];        stream = av_mallocz(sizeof(StreamInfo));        if (!stream)            goto fail;        st->priv_data = stream;        av_set_pts_info(st, 64, 1, 90000);        switch(st->codec->codec_type) {        case CODEC_TYPE_AUDIO:            if (st->codec->codec_id == CODEC_ID_AC3) {                stream->id = ac3_id++;            } else if (st->codec->codec_id == CODEC_ID_DTS) {                stream->id = dts_id++;            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {                stream->id = lpcm_id++;                for(j = 0; j < 4; j++) {                    if (lpcm_freq_tab[j] == st->codec->sample_rate)                        break;                }                if (j == 4)                    goto fail;                if (st->codec->channels > 8)                    return -1;                stream->lpcm_header[0] = 0x0c;                stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4);                stream->lpcm_header[2] = 0x80;                stream->lpcm_align = st->codec->channels * 2;            } else {                stream->id = mpa_id++;            }            /* This value HAS to be used for VCD (see VCD standard, p. IV-7).               Right now it is also used for everything else.*/            stream->max_buffer_size = 4 * 1024;            s->audio_bound++;            break;        case CODEC_TYPE_VIDEO:            stream->id = mpv_id++;            if (st->codec->rc_buffer_size)                stream->max_buffer_size = 6*1024 + st->codec->rc_buffer_size/8;            else                stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default#if 0                /* see VCD standard, p. IV-7*/                stream->max_buffer_size = 46 * 1024;            else                /* This value HAS to be used for SVCD (see SVCD standard, p. 26 V.2.3.2).                   Right now it is also used for everything else.*/                stream->max_buffer_size = 230 * 1024;#endif            s->video_bound++;            break;        case CODEC_TYPE_SUBTITLE:            stream->id = mps_id++;            stream->max_buffer_size = 16 * 1024;            break;        default:            return -1;        }        fifo_init(&stream->fifo, 16);    }    bitrate = 0;    audio_bitrate = 0;    video_bitrate = 0;    for(i=0;i<ctx->nb_streams;i++) {        int codec_rate;        st = ctx->streams[i];        stream = (StreamInfo*) st->priv_data;        if(st->codec->rc_max_rate || stream->id==VIDEO_ID)            codec_rate= st->codec->rc_max_rate;        else            codec_rate= st->codec->bit_rate;        if(!codec_rate)            codec_rate= (1<<21)*8*50/ctx->nb_streams;        bitrate += codec_rate;        if (stream->id==AUDIO_ID)            audio_bitrate += codec_rate;        else if (stream->id==VIDEO_ID)            video_bitrate += codec_rate;    }    if(ctx->mux_rate){        s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50);    } else {        /* we increase slightly the bitrate to take into account the           headers. XXX: compute it exactly */        bitrate += bitrate*5/100;        bitrate += 10000;        s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);    }

⌨️ 快捷键说明

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