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

📄 mpegenc.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            if (pes_flags & 0x01) {  /*write pes extension*/                put_byte(ctx->pb, 0x10); /* flags */                /* P-STD buffer info */                if (id == AUDIO_ID)                    put_be16(ctx->pb, 0x4000 | stream->max_buffer_size/128);                else                    put_be16(ctx->pb, 0x6000 | stream->max_buffer_size/1024);            }        } else {            if (pts != AV_NOPTS_VALUE) {                if (dts != pts) {                    put_timestamp(ctx->pb, 0x03, pts);                    put_timestamp(ctx->pb, 0x01, dts);                } else {                    put_timestamp(ctx->pb, 0x02, pts);                }            } else {                put_byte(ctx->pb, 0x0f);            }        }        if (s->is_mpeg2) {            /* special stuffing byte that is always written               to prevent accidental generation of start codes. */            put_byte(ctx->pb, 0xff);            for(i=0;i<stuffing_size;i++)                put_byte(ctx->pb, 0xff);        }        if (startcode == PRIVATE_STREAM_1) {            put_byte(ctx->pb, id);            if (id >= 0xa0) {                /* LPCM (XXX: check nb_frames) */                put_byte(ctx->pb, 7);                put_be16(ctx->pb, 4); /* skip 3 header bytes */                put_byte(ctx->pb, stream->lpcm_header[0]);                put_byte(ctx->pb, stream->lpcm_header[1]);                put_byte(ctx->pb, stream->lpcm_header[2]);            } else if (id >= 0x40) {                /* AC3 */                put_byte(ctx->pb, nb_frames);                put_be16(ctx->pb, trailer_size+1);            }        }        /* output data */        assert(payload_size - stuffing_size <= av_fifo_size(&stream->fifo));#ifdef __CW32__        av_fifo_generic_read(&stream->fifo, payload_size - stuffing_size, (void (*)(void*, void*, int))&put_buffer, ctx->pb);#else        av_fifo_generic_read(&stream->fifo, payload_size - stuffing_size, &put_buffer, ctx->pb);#endif        stream->bytes_to_iframe -= payload_size - stuffing_size;    }else{        payload_size=        stuffing_size= 0;    }    if (pad_packet_bytes > 0)        put_padding_packet(ctx,ctx->pb, pad_packet_bytes);    for(i=0;i<zero_trail_bytes;i++)        put_byte(ctx->pb, 0x00);    put_flush_packet(ctx->pb);    s->packet_number++;    /* only increase the stream packet number if this pack actually contains       something that is specific to this stream! I.e. a dedicated header       or some data.*/    if (!general_pack)        stream->packet_number++;    return payload_size - stuffing_size;}static void put_vcd_padding_sector(AVFormatContext *ctx){    /* There are two ways to do this padding: writing a sector/pack       of 0 values, or writing an MPEG padding pack. Both seem to       work with most decoders, BUT the VCD standard only allows a 0-sector       (see standard p. IV-4, IV-5).       So a 0-sector it is...*/    MpegMuxContext *s = ctx->priv_data;    int i;    for(i=0;i<s->packet_size;i++)        put_byte(ctx->pb, 0);    s->vcd_padding_bytes_written += s->packet_size;    put_flush_packet(ctx->pb);    /* increasing the packet number is correct. The SCR of the following packs       is calculated from the packet_number and it has to include the padding       sector (it represents the sector index, not the MPEG pack index)       (see VCD standard p. IV-6)*/    s->packet_number++;}#if 0 /* unused, remove? */static int64_t get_vcd_scr(AVFormatContext *ctx,int stream_index,int64_t pts){    MpegMuxContext *s = ctx->priv_data;    int64_t scr;        /* Since the data delivery rate is constant, SCR is computed           using the formula C + i * 1200 where C is the start constant           and i is the pack index.           It is recommended that SCR 0 is at the beginning of the VCD front           margin (a sequence of empty Form 2 sectors on the CD).           It is recommended that the front margin is 30 sectors long, so           we use C = 30*1200 = 36000           (Note that even if the front margin is not 30 sectors the file           will still be correct according to the standard. It just won't have           the "recommended" value).*/        scr = 36000 + s->packet_number * 1200;    return scr;}#endifstatic int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){//    MpegMuxContext *s = ctx->priv_data;    int i;    for(i=0; i<ctx->nb_streams; i++){        AVStream *st = ctx->streams[i];        StreamInfo *stream = st->priv_data;        PacketDesc *pkt_desc;        while((pkt_desc= stream->predecode_packet)              && scr > pkt_desc->dts){ //FIXME > vs >=            if(stream->buffer_index < pkt_desc->size ||               stream->predecode_packet == stream->premux_packet){                av_log(ctx, AV_LOG_ERROR,                       "buffer underflow i=%d bufi=%d size=%d\n",                       i, stream->buffer_index, pkt_desc->size);                break;            }            stream->buffer_index -= pkt_desc->size;            stream->predecode_packet= pkt_desc->next;            av_freep(&pkt_desc);        }    }    return 0;}static int output_packet(AVFormatContext *ctx, int flush){    MpegMuxContext *s = ctx->priv_data;    AVStream *st;    StreamInfo *stream;    int i, avail_space=0, es_size, trailer_size;    int best_i= -1;    int best_score= INT_MIN;    int ignore_constraints=0;    int64_t scr= s->last_scr;    PacketDesc *timestamp_packet;    const int64_t max_delay= av_rescale(ctx->max_delay, 90000, AV_TIME_BASE);retry:    for(i=0; i<ctx->nb_streams; i++){        AVStream *st = ctx->streams[i];        StreamInfo *stream = st->priv_data;        const int avail_data=  av_fifo_size(&stream->fifo);        const int space= stream->max_buffer_size - stream->buffer_index;        int rel_space= 1024*space / stream->max_buffer_size;        PacketDesc *next_pkt= stream->premux_packet;        /* for subtitle, a single PES packet must be generated,           so we flush after every single subtitle packet */        if(s->packet_size > avail_data && !flush           && st->codec->codec_type != CODEC_TYPE_SUBTITLE)            return 0;        if(avail_data==0)            continue;        assert(avail_data>0);        if(space < s->packet_size && !ignore_constraints)            continue;        if(next_pkt && next_pkt->dts - scr > max_delay)            continue;        if(rel_space > best_score){            best_score= rel_space;            best_i = i;            avail_space= space;        }    }    if(best_i < 0){        int64_t best_dts= INT64_MAX;        for(i=0; i<ctx->nb_streams; i++){            AVStream *st = ctx->streams[i];            StreamInfo *stream = st->priv_data;            PacketDesc *pkt_desc= stream->predecode_packet;            if(pkt_desc && pkt_desc->dts < best_dts)                best_dts= pkt_desc->dts;        }#if 0        av_log(ctx, AV_LOG_DEBUG, "bumping scr, scr:%f, dts:%f\n",               scr/90000.0, best_dts/90000.0);#endif        if(best_dts == INT64_MAX)            return 0;        if(scr >= best_dts+1 && !ignore_constraints){            av_log(ctx, AV_LOG_ERROR, "packet too large, ignoring buffer limits to mux it\n");            ignore_constraints= 1;        }        scr= FFMAX(best_dts+1, scr);        if(remove_decoded_packets(ctx, scr) < 0)            return -1;        goto retry;    }    assert(best_i >= 0);    st = ctx->streams[best_i];    stream = st->priv_data;    assert(av_fifo_size(&stream->fifo) > 0);    assert(avail_space >= s->packet_size || ignore_constraints);    timestamp_packet= stream->premux_packet;    if(timestamp_packet->unwritten_size == timestamp_packet->size){        trailer_size= 0;    }else{        trailer_size= timestamp_packet->unwritten_size;        timestamp_packet= timestamp_packet->next;    }    if(timestamp_packet){//av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f scr:%f stream:%d\n", timestamp_packet->dts/90000.0, timestamp_packet->pts/90000.0, scr/90000.0, best_i);        es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size);    }else{        assert(av_fifo_size(&stream->fifo) == trailer_size);        es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size);    }    if (s->is_vcd) {        /* Write one or more padding sectors, if necessary, to reach           the constant overall bitrate.*/        int vcd_pad_bytes;        while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->premux_packet->pts) ) >= s->packet_size){ //FIXME pts cannot be correct here            put_vcd_padding_sector(ctx);            s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet        }    }    stream->buffer_index += es_size;    s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet    while(stream->premux_packet && stream->premux_packet->unwritten_size <= es_size){        es_size -= stream->premux_packet->unwritten_size;        stream->premux_packet= stream->premux_packet->next;    }    if(es_size)        stream->premux_packet->unwritten_size -= es_size;    if(remove_decoded_packets(ctx, s->last_scr) < 0)        return -1;    return 1;}static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt){    MpegMuxContext *s = ctx->priv_data;    int stream_index= pkt->stream_index;    int size= pkt->size;    uint8_t *buf= pkt->data;    AVStream *st = ctx->streams[stream_index];    StreamInfo *stream = st->priv_data;    int64_t pts, dts;    PacketDesc *pkt_desc;    const int preload= av_rescale(ctx->preload, 90000, AV_TIME_BASE);    const int is_iframe = st->codec->codec_type == CODEC_TYPE_VIDEO && (pkt->flags & PKT_FLAG_KEY);    pts= pkt->pts;    dts= pkt->dts;    if(pts != AV_NOPTS_VALUE) pts += preload;    if(dts != AV_NOPTS_VALUE) dts += preload;//av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", dts/90000.0, pts/90000.0, pkt->flags, pkt->stream_index, pts != AV_NOPTS_VALUE);    if (!stream->premux_packet)        stream->next_packet = &stream->premux_packet;    *stream->next_packet=    pkt_desc= av_mallocz(sizeof(PacketDesc));    pkt_desc->pts= pts;    pkt_desc->dts= dts;    pkt_desc->unwritten_size=    pkt_desc->size= size;    if(!stream->predecode_packet)        stream->predecode_packet= pkt_desc;    stream->next_packet= &pkt_desc->next;    av_fifo_realloc(&stream->fifo, av_fifo_size(&stream->fifo) + size);    if (s->is_dvd){        if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder)            stream->bytes_to_iframe = av_fifo_size(&stream->fifo);            stream->align_iframe = 1;            stream->vobu_start_pts = pts;        }    }    av_fifo_generic_write(&stream->fifo, buf, size, NULL);    for(;;){        int ret= output_packet(ctx, 0);        if(ret<=0)            return ret;    }}static int mpeg_mux_end(AVFormatContext *ctx){//    MpegMuxContext *s = ctx->priv_data;    StreamInfo *stream;    int i;    for(;;){        int ret= output_packet(ctx, 1);        if(ret<0)            return ret;        else if(ret==0)            break;    }    /* End header according to MPEG1 systems standard. We do not write       it as it is usually not needed by decoders and because it       complicates MPEG stream concatenation. */    //put_be32(ctx->pb, ISO_11172_END_CODE);    //put_flush_packet(ctx->pb);    for(i=0;i<ctx->nb_streams;i++) {        stream = ctx->streams[i]->priv_data;        assert(av_fifo_size(&stream->fifo) == 0);        av_fifo_free(&stream->fifo);    }    return 0;}#ifdef CONFIG_MPEG1SYSTEM_MUXERAVOutputFormat mpeg1system_muxer = {    "mpeg",    NULL_IF_CONFIG_SMALL("MPEG-1 System format"),    "video/mpeg",    "mpg,mpeg",    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG1VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};#endif#ifdef CONFIG_MPEG1VCD_MUXERAVOutputFormat mpeg1vcd_muxer = {    "vcd",    NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"),    "video/mpeg",    NULL,    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG1VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};#endif#ifdef CONFIG_MPEG2VOB_MUXERAVOutputFormat mpeg2vob_muxer = {    "vob",    NULL_IF_CONFIG_SMALL("MPEG-2 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/* Same as mpeg2vob_mux except that the pack size is 2324 */#ifdef CONFIG_MPEG2SVCD_MUXERAVOutputFormat mpeg2svcd_muxer = {    "svcd",    NULL_IF_CONFIG_SMALL("MPEG-2 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/*  Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */#ifdef CONFIG_MPEG2DVD_MUXERAVOutputFormat mpeg2dvd_muxer = {    "dvd",    NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"),    "video/mpeg",    "dvd",    sizeof(MpegMuxContext),    CODEC_ID_MP2,    CODEC_ID_MPEG2VIDEO,    mpeg_mux_init,    mpeg_mux_write_packet,    mpeg_mux_end,};#endif

⌨️ 快捷键说明

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