• FFMPEG实现的转码程序


    本例子是由FFEMPG的doc/example例子transcode.c修改而来,可以根据需求任意转换音视频的编码。

    原来的例子的作用更类似于remux,并没有实现转码的功能,只是实现了格式转换,比如ts转avi等。并不能实现音视频编码格式的转换,比如将h264转为mpeg2。

    FFMPEG转码的实现有多种方式:

    一种方式是:流解复用->视频+音频流->解码->YUV/PCM等->视音频编码->重新生成的音视频流->复用->流

    另一种方式依赖AVFilter,这一部分在另外的几篇文章中解释怎么用。虽然AVFilter学习起来可能比较困难,但是在实际的编程应用中,依靠AVFilter做转码效率比第一种方式高,并且解码的CPU和时间消耗也少的多。所以,还是建议好好学习这部分的,毕竟我一直觉得FFMPEG的强项就是解码和转码。

    本例子是视频mpeg2转h264,音频mpegaudio转g711。

    [cpp] view plain copy
     
     print?
    1. <span style="font-family:SimHei;font-size:18px;">/* 
    2. * based on FFMPEG transcode.c 
    3. * modified by tongli 
    4. */  
    5. #include <stdio.h>  
    6. #include "snprintf.h"  
    7. extern "C"  
    8. {  
    9. #include <libavcodec/avcodec.h>  
    10. #include <libavformat/avformat.h>  
    11. #include <libavfilter/avfiltergraph.h>  
    12. #include <libavfilter/avcodec.h>  
    13. #include <libavfilter/buffersink.h>  
    14. #include <libavfilter/buffersrc.h>  
    15. #include <libavutil/opt.h>  
    16. #include <libavutil/pixdesc.h>  
    17. }  
    18. static AVFormatContext *ifmt_ctx;  
    19. static AVFormatContext *ofmt_ctx;  
    20. typedef struct FilteringContext {  
    21.     AVFilterContext *buffersink_ctx;  
    22.     AVFilterContext *buffersrc_ctx;  
    23.     AVFilterGraph *filter_graph;  
    24. } FilteringContext;  
    25. static FilteringContext *filter_ctx;  
    26.   
    27. static int open_input_file(const char *filename)  
    28. {  
    29.     int ret;  
    30.     unsigned int i;  
    31.   
    32.     ifmt_ctx = NULL;  
    33.     if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {  
    34.         av_log(NULL, AV_LOG_ERROR, "Cannot open input file ");  
    35.         return ret;  
    36.     }  
    37.   
    38.     if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {  
    39.         av_log(NULL, AV_LOG_ERROR, "Cannot find stream information ");  
    40.         return ret;  
    41.     }  
    42.   
    43.     for (i = 0; i < ifmt_ctx->nb_streams; i++) {  
    44.         AVStream *stream;  
    45.         AVCodecContext *codec_ctx;  
    46.         stream = ifmt_ctx->streams[i];  
    47.         codec_ctx = stream->codec;  
    48.         /* Reencode video & audio and remux subtitles etc. */  
    49.         if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO  
    50.             || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {  
    51.             /* Open decoder */  
    52.             ret = avcodec_open2(codec_ctx,  
    53.                 avcodec_find_decoder(codec_ctx->codec_id), NULL);  
    54.             if (ret < 0) {  
    55.                 av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u ", i);  
    56.                 return ret;  
    57.             }  
    58.         }  
    59.     }  
    60.   
    61.     av_dump_format(ifmt_ctx, 0, filename, 0);  
    62.     return 0;  
    63. }  
    64.   
    65. static int open_output_file(const char *filename)  
    66. {  
    67.     AVStream *out_stream;  
    68.     AVStream *in_stream;  
    69.     AVCodecContext *dec_ctx, *enc_ctx;  
    70.     AVCodec *encoder;  
    71.     int ret;  
    72.     unsigned int i;  
    73.   
    74.     ofmt_ctx = NULL;  
    75.     avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);  
    76.     if (!ofmt_ctx) {  
    77.         av_log(NULL, AV_LOG_ERROR, "Could not create output context ");  
    78.         return AVERROR_UNKNOWN;  
    79.     }  
    80.   
    81.     for (i = 0; i < ifmt_ctx->nb_streams; i++) {  
    82.         out_stream = avformat_new_stream(ofmt_ctx, NULL);  
    83.         if (!out_stream) {  
    84.             av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream ");  
    85.             return AVERROR_UNKNOWN;  
    86.         }  
    87.   
    88.         in_stream = ifmt_ctx->streams[i];  
    89.         dec_ctx = in_stream->codec;  
    90.         enc_ctx = out_stream->codec;  
    91.   
    92.         if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)   
    93.         {  
    94.             encoder = avcodec_find_encoder(AV_CODEC_ID_H264);  
    95.             if (!encoder) {  
    96.                 av_log(NULL, AV_LOG_FATAL, "Neccessary encoder not found ");  
    97.                 return AVERROR_INVALIDDATA;  
    98.             }  
    99.   
    100.             enc_ctx->height = dec_ctx->height;  
    101.             enc_ctx->width = dec_ctx->width;  
    102.             enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;  
    103.                   
    104.             enc_ctx->pix_fmt = encoder->pix_fmts[0];  
    105.                   
    106.             enc_ctx->time_base = dec_ctx->time_base;  
    107.   
    108.             enc_ctx->me_range = 16;  
    109.             enc_ctx->max_qdiff = 4;  
    110.             enc_ctx->qmin = 10;  
    111.             enc_ctx->qmax = 51;  
    112.             enc_ctx->qcompress = 0.6;  
    113.             enc_ctx->refs = 3;  
    114.             enc_ctx->bit_rate = 500000;  
    115.               
    116.             ret = avcodec_open2(enc_ctx, encoder, NULL);  
    117.             if (ret < 0) {  
    118.                 av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u ", i);  
    119.                 return ret;  
    120.             }  
    121.         }  
    122.         else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {  
    123.             av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed ", i);  
    124.             return AVERROR_INVALIDDATA;  
    125.         }  
    126.         else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO)  
    127.         {  
    128.             encoder = avcodec_find_encoder(AV_CODEC_ID_PCM_ALAW);  
    129.             enc_ctx->sample_rate = dec_ctx->sample_rate;  
    130.             enc_ctx->channel_layout = dec_ctx->channel_layout;  
    131.             enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);  
    132.             enc_ctx->sample_fmt = encoder->sample_fmts[0];  
    133.             AVRational ar = { 1, enc_ctx->sample_rate };  
    134.             enc_ctx->time_base = ar;  
    135.   
    136.             ret = avcodec_open2(enc_ctx, encoder, NULL);  
    137.             if (ret < 0) {  
    138.                 av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u ", i);  
    139.                 return ret;  
    140.             }  
    141.         }  
    142.         else {  
    143.             ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,  
    144.                 ifmt_ctx->streams[i]->codec);  
    145.             if (ret < 0) {  
    146.                 av_log(NULL, AV_LOG_ERROR, "Copying stream context failed ");  
    147.                 return ret;  
    148.             }  
    149.         }  
    150.   
    151.         if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)  
    152.             enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;  
    153.   
    154.     }  
    155.     av_dump_format(ofmt_ctx, 0, filename, 1);  
    156.   
    157.     if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {  
    158.         ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);  
    159.         if (ret < 0) {  
    160.             av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename);  
    161.             return ret;  
    162.         }  
    163.     }  
    164.   
    165.     /* init muxer, write output file header */  
    166.     ret = avformat_write_header(ofmt_ctx, NULL);  
    167.     if (ret < 0) {  
    168.         av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file ");  
    169.         return ret;  
    170.     }  
    171.   
    172.     return 0;  
    173. }  
    174.   
    175. static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,  
    176.     AVCodecContext *enc_ctx, const char *filter_spec)  
    177. {  
    178.     char args[512];  
    179.     int ret = 0;  
    180.     AVFilter *buffersrc = NULL;  
    181.     AVFilter *buffersink = NULL;  
    182.     AVFilterContext *buffersrc_ctx = NULL;  
    183.     AVFilterContext *buffersink_ctx = NULL;  
    184.     AVFilterInOut *outputs = avfilter_inout_alloc();  
    185.     AVFilterInOut *inputs = avfilter_inout_alloc();  
    186.     AVFilterGraph *filter_graph = avfilter_graph_alloc();  
    187.   
    188.     if (!outputs || !inputs || !filter_graph) {  
    189.         ret = AVERROR(ENOMEM);  
    190.         goto end;  
    191.     }  
    192.   
    193.     if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {  
    194.         buffersrc = avfilter_get_by_name("buffer");  
    195.         buffersink = avfilter_get_by_name("buffersink");  
    196.         if (!buffersrc || !buffersink) {  
    197.             av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found ");  
    198.             ret = AVERROR_UNKNOWN;  
    199.             goto end;  
    200.         }  
    201.   
    202.         snprintf(args, sizeof(args),  
    203.             "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",  
    204.             dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,  
    205.             dec_ctx->time_base.num, dec_ctx->time_base.den,  
    206.             dec_ctx->sample_aspect_ratio.num,  
    207.             dec_ctx->sample_aspect_ratio.den);  
    208.   
    209.         ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",  
    210.             args, NULL, filter_graph);  
    211.         if (ret < 0) {  
    212.             av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source ");  
    213.             goto end;  
    214.         }  
    215.   
    216.         ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",  
    217.             NULL, NULL, filter_graph);  
    218.         if (ret < 0) {  
    219.             av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink ");  
    220.             goto end;  
    221.         }  
    222.   
    223.         ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",  
    224.             (uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),  
    225.             AV_OPT_SEARCH_CHILDREN);  
    226.         if (ret < 0) {  
    227.             av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format ");  
    228.             goto end;  
    229.         }  
    230.     }  
    231.     else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {  
    232.         buffersrc = avfilter_get_by_name("abuffer");  
    233.         buffersink = avfilter_get_by_name("abuffersink");  
    234.         if (!buffersrc || !buffersink) {  
    235.             av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found ");  
    236.             ret = AVERROR_UNKNOWN;  
    237.             goto end;  
    238.         }  
    239.   
    240.         if (!dec_ctx->channel_layout)  
    241.             dec_ctx->channel_layout =  
    242.             av_get_default_channel_layout(dec_ctx->channels);  
    243.         snprintf(args, sizeof(args),  
    244.             "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,  
    245.             dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,  
    246.             av_get_sample_fmt_name(dec_ctx->sample_fmt),  
    247.             dec_ctx->channel_layout);  
    248.         ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",  
    249.             args, NULL, filter_graph);  
    250.         if (ret < 0) {  
    251.             av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source ");  
    252.             goto end;  
    253.         }  
    254.   
    255.         ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",  
    256.             NULL, NULL, filter_graph);  
    257.         if (ret < 0) {  
    258.             av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink ");  
    259.             goto end;  
    260.         }  
    261.   
    262.         ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",  
    263.             (uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),  
    264.             AV_OPT_SEARCH_CHILDREN);  
    265.         if (ret < 0) {  
    266.             av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format ");  
    267.             goto end;  
    268.         }  
    269.   
    270.         ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",  
    271.             (uint8_t*)&enc_ctx->channel_layout,  
    272.             sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);  
    273.         if (ret < 0) {  
    274.             av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout ");  
    275.             goto end;  
    276.         }  
    277.   
    278.         ret = av_opt_set_bin(buffersink_ctx, "sample_rates",  
    279.             (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),  
    280.             AV_OPT_SEARCH_CHILDREN);  
    281.         if (ret < 0) {  
    282.             av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate ");  
    283.             goto end;  
    284.         }  
    285.     }  
    286.     else {  
    287.         ret = AVERROR_UNKNOWN;  
    288.         goto end;  
    289.     }  
    290.   
    291.     /* Endpoints for the filter graph. */  
    292.     outputs->name = av_strdup("in");  
    293.     outputs->filter_ctx = buffersrc_ctx;  
    294.     outputs->pad_idx = 0;  
    295.     outputs->next = NULL;  
    296.   
    297.     inputs->name = av_strdup("out");  
    298.     inputs->filter_ctx = buffersink_ctx;  
    299.     inputs->pad_idx = 0;  
    300.     inputs->next = NULL;  
    301.   
    302.     if (!outputs->name || !inputs->name) {  
    303.         ret = AVERROR(ENOMEM);  
    304.         goto end;  
    305.     }  
    306.   
    307.     if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,  
    308.         &inputs, &outputs, NULL)) < 0)  
    309.         goto end;  
    310.   
    311.     if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)  
    312.         goto end;  
    313.   
    314.     /* Fill FilteringContext */  
    315.     fctx->buffersrc_ctx = buffersrc_ctx;  
    316.     fctx->buffersink_ctx = buffersink_ctx;  
    317.     fctx->filter_graph = filter_graph;  
    318.   
    319. end:  
    320.     avfilter_inout_free(&inputs);  
    321.     avfilter_inout_free(&outputs);  
    322.   
    323.     return ret;  
    324. }  
    325.   
    326. static int init_filters(void)  
    327. {  
    328.     const char *filter_spec;  
    329.     unsigned int i;  
    330.     int ret;  
    331.     filter_ctx = (FilteringContext*)av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));  
    332.     if (!filter_ctx)  
    333.         return AVERROR(ENOMEM);  
    334.   
    335.     for (i = 0; i < ifmt_ctx->nb_streams; i++) {  
    336.         filter_ctx[i].buffersrc_ctx = NULL;  
    337.         filter_ctx[i].buffersink_ctx = NULL;  
    338.         filter_ctx[i].filter_graph = NULL;  
    339.         if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO  
    340.             || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))  
    341.             continue;  
    342.   
    343.   
    344.         if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)  
    345.             filter_spec = "null"; /* passthrough (dummy) filter for video */  
    346.         else  
    347.             filter_spec = "anull"; /* passthrough (dummy) filter for audio */  
    348.         ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,  
    349.             ofmt_ctx->streams[i]->codec, filter_spec);  
    350.         if (ret)  
    351.             return ret;  
    352.     }  
    353.     return 0;  
    354. }  
    355.   
    356. static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {  
    357.     int ret;  
    358.     int got_frame_local;  
    359.     AVPacket enc_pkt;  
    360.     int(*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =  
    361.         (ifmt_ctx->streams[stream_index]->codec->codec_type ==  
    362.         AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;  
    363.   
    364.     if (!got_frame)  
    365.         got_frame = &got_frame_local;  
    366.   
    367.     av_log(NULL, AV_LOG_INFO, "Encoding frame ");  
    368.     /* encode filtered frame */  
    369.     enc_pkt.data = NULL;  
    370.     enc_pkt.size = 0;  
    371.     av_init_packet(&enc_pkt);  
    372.     ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,  
    373.         filt_frame, got_frame);  
    374.     av_frame_free(&filt_frame);  
    375.     if (ret < 0)  
    376.         return ret;  
    377.     if (!(*got_frame))  
    378.         return 0;  
    379.   
    380.     /* prepare packet for muxing */  
    381.     enc_pkt.stream_index = stream_index;  
    382.     av_packet_rescale_ts(&enc_pkt,  
    383.         ofmt_ctx->streams[stream_index]->codec->time_base,  
    384.         ofmt_ctx->streams[stream_index]->time_base);  
    385.   
    386.     av_log(NULL, AV_LOG_DEBUG, "Muxing frame ");  
    387.     /* mux encoded frame */  
    388.     ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);  
    389.     return ret;  
    390. }  
    391.   
    392. static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)  
    393. {  
    394.     int ret;  
    395.     AVFrame *filt_frame;  
    396.   
    397.     av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters ");  
    398.     /* push the decoded frame into the filtergraph */  
    399.     ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,  
    400.         frame, 0);  
    401.     if (ret < 0) {  
    402.         av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph ");  
    403.         return ret;  
    404.     }  
    405.   
    406.     /* pull filtered frames from the filtergraph */  
    407.     while (1) {  
    408.         filt_frame = av_frame_alloc();  
    409.         if (!filt_frame) {  
    410.             ret = AVERROR(ENOMEM);  
    411.             break;  
    412.         }  
    413.         av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters ");  
    414.         ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,  
    415.             filt_frame);  
    416.         if (ret < 0) {  
    417.             /* if no more frames for output - returns AVERROR(EAGAIN) 
    418.             * if flushed and no more frames for output - returns AVERROR_EOF 
    419.             * rewrite retcode to 0 to show it as normal procedure completion 
    420.             */  
    421.             if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)  
    422.                 ret = 0;  
    423.             av_frame_free(&filt_frame);  
    424.             break;  
    425.         }  
    426.   
    427.         filt_frame->pict_type = AV_PICTURE_TYPE_NONE;  
    428.         ret = encode_write_frame(filt_frame, stream_index, NULL);  
    429.         if (ret < 0)  
    430.             break;  
    431.     }  
    432.   
    433.     return ret;  
    434. }  
    435.   
    436. static int flush_encoder(unsigned int stream_index)  
    437. {  
    438.     int ret;  
    439.     int got_frame;  
    440.   
    441.     if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &  
    442.         CODEC_CAP_DELAY))  
    443.         return 0;  
    444.   
    445.     while (1) {  
    446.         av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder ", stream_index);  
    447.         ret = encode_write_frame(NULL, stream_index, &got_frame);  
    448.         if (ret < 0)  
    449.             break;  
    450.         if (!got_frame)  
    451.             return 0;  
    452.     }  
    453.     return ret;  
    454. }  
    455.   
    456. int main(int argc, char **argv)  
    457. {  
    458.     int ret;  
    459.     AVPacket packet; //= { .data = NULL, .size = 0 };  
    460.     packet.data = NULL;  
    461.     packet.size = 0;  
    462.     AVFrame *frame = NULL;  
    463.     enum AVMediaType type;  
    464.     unsigned int stream_index;  
    465.     unsigned int i;  
    466.     int got_frame;  
    467.     int(*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);  
    468.   
    469.     av_register_all();  
    470.     avfilter_register_all();  
    471.   
    472.     if ((ret = open_input_file("test.ts")) < 0)  
    473.         goto end;  
    474.     if ((ret = open_output_file("test.avi")) < 0)  
    475.         goto end;  
    476.     if ((ret = init_filters()) < 0)  
    477.         goto end;  
    478.   
    479.     /* read all packets */  
    480.     while (1) {  
    481.         if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)  
    482.             break;  
    483.         stream_index = packet.stream_index;  
    484.         type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;  
    485.         av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u ",  
    486.             stream_index);  
    487.   
    488.         if (filter_ctx[stream_index].filter_graph) {  
    489.             av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame ");  
    490.             frame = av_frame_alloc();  
    491.             if (!frame) {  
    492.                 ret = AVERROR(ENOMEM);  
    493.                 break;  
    494.             }  
    495.             av_packet_rescale_ts(&packet,  
    496.                 ifmt_ctx->streams[stream_index]->time_base,  
    497.                 ifmt_ctx->streams[stream_index]->codec->time_base);  
    498.             dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :  
    499.                 avcodec_decode_audio4;  
    500.             ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,  
    501.                 &got_frame, &packet);  
    502.             if (ret < 0) {  
    503.                 av_frame_free(&frame);  
    504.                 av_log(NULL, AV_LOG_ERROR, "Decoding failed ");  
    505.                 break;  
    506.             }  
    507.   
    508.             if (got_frame) {  
    509.                 frame->pts = av_frame_get_best_effort_timestamp(frame);  
    510.                 ret = filter_encode_write_frame(frame, stream_index);  
    511.                 av_frame_free(&frame);  
    512.                 if (ret < 0)  
    513.                     goto end;  
    514.             }  
    515.             else {  
    516.                 av_frame_free(&frame);  
    517.             }  
    518.         }  
    519.         else {  
    520.             /* remux this frame without reencoding */  
    521.             av_packet_rescale_ts(&packet,  
    522.                 ifmt_ctx->streams[stream_index]->time_base,  
    523.                 ofmt_ctx->streams[stream_index]->time_base);  
    524.   
    525.             ret = av_interleaved_write_frame(ofmt_ctx, &packet);  
    526.             if (ret < 0)  
    527.                 goto end;  
    528.         }  
    529.         av_free_packet(&packet);  
    530.     }  
    531.   
    532.     /* flush filters and encoders */  
    533.     for (i = 0; i < ifmt_ctx->nb_streams; i++) {  
    534.         /* flush filter */  
    535.         if (!filter_ctx[i].filter_graph)  
    536.             continue;  
    537.         ret = filter_encode_write_frame(NULL, i);  
    538.         if (ret < 0) {  
    539.             av_log(NULL, AV_LOG_ERROR, "Flushing filter failed ");  
    540.             goto end;  
    541.         }  
    542.   
    543.         /* flush encoder */  
    544.         ret = flush_encoder(i);  
    545.         if (ret < 0) {  
    546.             av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed ");  
    547.             goto end;  
    548.         }  
    549.     }  
    550.   
    551.     av_write_trailer(ofmt_ctx);  
    552. end:  
    553.     av_free_packet(&packet);  
    554.     av_frame_free(&frame);  
    555.     for (i = 0; i < ifmt_ctx->nb_streams; i++) {  
    556.         avcodec_close(ifmt_ctx->streams[i]->codec);  
    557.         if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)  
    558.             avcodec_close(ofmt_ctx->streams[i]->codec);  
    559.         if (filter_ctx && filter_ctx[i].filter_graph)  
    560.             avfilter_graph_free(&filter_ctx[i].filter_graph);  
    561.     }  
    562.     av_free(filter_ctx);  
    563.     avformat_close_input(&ifmt_ctx);  
    564.     if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))  
    565.         avio_closep(&ofmt_ctx->pb);  
    566.     avformat_free_context(ofmt_ctx);  
    567.   
    568.     if (ret < 0)  
    569.         av_log(NULL, AV_LOG_ERROR, "Error occurred: %s "); //av_err2str(ret));  
    570.   
    571.     return ret ? 1 : 0;  
    572. }  
    573.   
    574. </span>  

    源代码下载:

    csdn工程:http://download.csdn.NET/detail/rootusers/8425619

    from:http://blog.csdn.net/rootusers/article/details/43488827

  • 相关阅读:
    poj 3304线段与直线相交
    poj 1039 几何没思路
    zoj 1010 (线段相交判断+多边形求面积)
    poj 1654 Area (多边形求面积)
    poj 3348--Cows(凸包求面积)
    zoj 2107&&hdu 1007最近点对问题
    Codeforces Round #260 (Div. 2)AB
    MMORPG大型游戏设计与开发(part1 of net)
    MMORPG大型游戏设计与开发(规范)
    MMORPG大型游戏设计与开发(构架)
  • 原文地址:https://www.cnblogs.com/lidabo/p/7327113.html
Copyright © 2020-2023  润新知