• 基于ffmpeg生成hls(代码)


    代码在 最简单的基于FFMPEG的转码程序(雷霄骅) 基础上简单修改

    参考 基于ffmpeg的转码代码(转码为hls)

    https://pan.baidu.com/s/1w-fF5Ojz8M1ajKsc4DKdrg

      1 /*
      2 *最简单的基于FFmpeg的转码器
      3 *Simplest FFmpeg Transcoder
      4 *
      5 *雷霄骅 Lei Xiaohua
      6 *leixiaohua1020@126.com
      7 *中国传媒大学/数字电视技术
      8 *Communication University of China / DigitalTV Technology
      9 *http://blog.csdn.net/leixiaohua1020
     10 *
     11 *本程序实现了视频格式之间的转换。是一个最简单的视频转码程序。
     12 *
     13 */
     14 
     15 #define _CRT_SECURE_NO_WARNINGS
     16 extern "C"
     17 {
     18 #include "libavcodec/avcodec.h"
     19 #include "libavformat/avformat.h"
     20 #include "libavfilter/avfiltergraph.h"
     21 #include "libavfilter/avcodec.h"
     22 #include "libavfilter/buffersink.h"
     23 #include "libavfilter/buffersrc.h"
     24 #include "libavutil/avutil.h"
     25 #include "libavutil/opt.h"
     26 #include "libavutil/pixdesc.h"
     27 };
     28 
     29 
     30 
     31 static AVFormatContext *ifmt_ctx;
     32 static AVFormatContext *ofmt_ctx;
     33 
     34 typedef struct FilteringContext{
     35     AVFilterContext* buffersink_ctx;
     36     AVFilterContext* buffersrc_ctx;
     37     AVFilterGraph*   filter_graph;
     38 } FilteringContext;
     39 
     40 static FilteringContext *filter_ctx;
     41 
     42 
     43 // 解码用
     44 static int open_input_file(const char *filename)
     45 {
     46     int ret;
     47     unsigned int i;
     48     ifmt_ctx = NULL;
     49     if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
     50         av_log(NULL, AV_LOG_ERROR, "Cannot openinput file
    ");
     51         return ret;
     52     }
     53     if ((ret = avformat_find_stream_info(ifmt_ctx, NULL))< 0) {
     54         av_log(NULL, AV_LOG_ERROR, "Cannot findstream information
    ");
     55         return ret;
     56     }
     57     for (i = 0; i < ifmt_ctx->nb_streams; i++)
     58     {
     59         AVStream*stream;
     60         AVCodecContext *codec_ctx;
     61         stream = ifmt_ctx->streams[i];
     62         codec_ctx = stream->codec;
     63         /* Reencode video & audio and remux subtitles etc. */
     64         if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
     65             || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
     66             /* Open decoder */
     67             ret = avcodec_open2(codec_ctx, avcodec_find_decoder(codec_ctx->codec_id), NULL);
     68             if (ret < 0) {
     69                 av_log(NULL, AV_LOG_ERROR, "Failed toopen decoder for stream #%u
    ", i);
     70                 return ret;
     71             }
     72         }
     73     }
     74     av_dump_format(ifmt_ctx, 0, filename, 0);
     75     return 0;
     76 }
     77 
     78 static int open_output_file(const char *filename)
     79 {
     80     AVStream*out_stream;
     81     AVStream*in_stream;
     82     AVCodecContext*dec_ctx, *enc_ctx;
     83     AVCodec*encoder;
     84     int ret;
     85     unsigned int i;
     86     ofmt_ctx = NULL;
     87     avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
     88     if (!ofmt_ctx) {
     89         av_log(NULL, AV_LOG_ERROR, "Could notcreate output context
    ");
     90         return AVERROR_UNKNOWN;
     91     }
     92 
     93     for (i = 0; i < ifmt_ctx->nb_streams; i++)
     94     {
     95         out_stream = avformat_new_stream(ofmt_ctx, NULL);
     96         if (!out_stream) {
     97             av_log(NULL, AV_LOG_ERROR, "Failedallocating output stream
    ");
     98             return AVERROR_UNKNOWN;
     99         }
    100         in_stream = ifmt_ctx->streams[i];
    101         dec_ctx = in_stream->codec;
    102         enc_ctx = out_stream->codec;
    103         if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
    104             /* in this example, we choose transcoding to same codec */
    105             encoder = avcodec_find_encoder(dec_ctx->codec_id);
    106             /* In this example, we transcode to same properties(picture size,
    107             * sample rate etc.). These properties can be changed for output
    108             * streams easily using filters */
    109             if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
    110                 enc_ctx->height = dec_ctx->height;
    111                 enc_ctx->width = dec_ctx->width;
    112                 enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
    113                 /* take first format from list of supported formats */
    114                 enc_ctx->pix_fmt = encoder->pix_fmts[0];
    115                 /* video time_base can be set to whatever is handy andsupported by encoder */
    116                 enc_ctx->time_base = dec_ctx->time_base;
    117             }
    118             else {
    119                 enc_ctx->sample_rate = dec_ctx->sample_rate;
    120                 enc_ctx->channel_layout = dec_ctx->channel_layout;
    121                 enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
    122                 /* take first format from list of supported formats */
    123                 enc_ctx->sample_fmt = encoder->sample_fmts[0];
    124                 //AVRational timebase = { 1, enc_ctx->sample_rate };
    125                 //enc_ctx->time_base = time_base;
    126                 enc_ctx->time_base.num = 1;
    127                 enc_ctx->time_base.den = enc_ctx->sample_rate;
    128             }
    129             /* Third parameter can be used to pass settings to encoder*/
    130             if (AV_CODEC_ID_H264 == encoder->id) {
    131                 enc_ctx->me_range = 16;
    132                 enc_ctx->max_qdiff = 4;
    133                 //enc_ctx->qmin = 10;
    134                 //enc_ctx->qmax = 51;
    135                 enc_ctx->qcompress = 1.0;
    136             }
    137             if (ofmt_ctx->oformat->flags &AVFMT_GLOBALHEADER)
    138                 enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
    139 
    140             ret = avcodec_open2(enc_ctx, encoder, NULL);
    141             if (ret < 0) {
    142                 av_log(NULL, AV_LOG_ERROR, "Cannot openvideo encoder for stream #%u
    ", i);
    143                 return ret;
    144             }
    145         }
    146         else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
    147             av_log(NULL, AV_LOG_FATAL, "Elementarystream #%d is of unknown type, cannot proceed
    ", i);
    148             return AVERROR_INVALIDDATA;
    149         }
    150         else {
    151             /* if this stream must be remuxed */
    152             ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,
    153                 ifmt_ctx->streams[i]->codec);
    154             if (ret < 0) {
    155                 av_log(NULL, AV_LOG_ERROR, "Copyingstream context failed
    ");
    156                 return ret;
    157             }
    158         }
    159         if (ofmt_ctx->oformat->flags &AVFMT_GLOBALHEADER)
    160             enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
    161     }
    162 
    163     //av_opt_set_int(ofmt_ctx->priv_data, "hls_time", 15, AV_OPT_SEARCH_CHILDREN); 或者
    164     av_opt_set(ofmt_ctx->priv_data, "hls_time", "15", AV_OPT_SEARCH_CHILDREN); // 设置每个ts片段的时间
    165 
    166     av_dump_format(ofmt_ctx, 0, filename, 1);
    167     if (!(ofmt_ctx->oformat->flags &AVFMT_NOFILE)) {
    168         ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
    169         if (ret < 0) {
    170             av_log(NULL, AV_LOG_ERROR, "Could notopen output file '%s'", filename);
    171             return ret;
    172         }
    173     }
    174     /* init muxer, write output file header */
    175     ret = avformat_write_header(ofmt_ctx, NULL);
    176     if (ret < 0) {
    177         av_log(NULL, AV_LOG_ERROR, "Error occurred when openingoutput file
    ");
    178         return ret;
    179     }
    180     return 0;
    181 }
    182 
    183 static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
    184     AVCodecContext *enc_ctx, const char *filter_spec)
    185 {
    186     char args[512];
    187     int ret = 0;
    188     AVFilter*buffersrc = NULL;
    189     AVFilter*buffersink = NULL;
    190     AVFilterContext*buffersrc_ctx = NULL;
    191     AVFilterContext*buffersink_ctx = NULL;
    192     AVFilterInOut*outputs = avfilter_inout_alloc();
    193     AVFilterInOut*inputs = avfilter_inout_alloc();
    194     AVFilterGraph*filter_graph = avfilter_graph_alloc();
    195     if (!outputs || !inputs || !filter_graph) {
    196         ret = AVERROR(ENOMEM);
    197         goto end;
    198     }
    199     if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
    200         buffersrc = avfilter_get_by_name("buffer");
    201         buffersink = avfilter_get_by_name("buffersink");
    202         if (!buffersrc || !buffersink) {
    203             av_log(NULL, AV_LOG_ERROR, "filteringsource or sink element not found
    ");
    204             ret = AVERROR_UNKNOWN;
    205             goto end;
    206         }
    207         _snprintf(args, sizeof(args),
    208             "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
    209             dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
    210             dec_ctx->time_base.num, dec_ctx->time_base.den,
    211             dec_ctx->sample_aspect_ratio.num,
    212             dec_ctx->sample_aspect_ratio.den);
    213         ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
    214             args, NULL, filter_graph);
    215         if (ret < 0) {
    216             av_log(NULL, AV_LOG_ERROR, "Cannotcreate buffer source
    ");
    217             goto end;
    218         }
    219         ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
    220             NULL, NULL, filter_graph);
    221         if (ret < 0) {
    222             av_log(NULL, AV_LOG_ERROR, "Cannotcreate buffer sink
    ");
    223             goto end;
    224         }
    225         ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
    226             (uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
    227             AV_OPT_SEARCH_CHILDREN);
    228         if (ret < 0) {
    229             av_log(NULL, AV_LOG_ERROR, "Cannot setoutput pixel format
    ");
    230             goto end;
    231         }
    232     }
    233     else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
    234         buffersrc = avfilter_get_by_name("abuffer");
    235         buffersink = avfilter_get_by_name("abuffersink");
    236         if (!buffersrc || !buffersink) {
    237             av_log(NULL, AV_LOG_ERROR, "filteringsource or sink element not found
    ");
    238             ret = AVERROR_UNKNOWN;
    239             goto end;
    240         }
    241         if (!dec_ctx->channel_layout)
    242             dec_ctx->channel_layout =
    243             av_get_default_channel_layout(dec_ctx->channels);
    244         _snprintf(args, sizeof(args),
    245             "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%I64x",
    246             dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
    247             av_get_sample_fmt_name(dec_ctx->sample_fmt),
    248             dec_ctx->channel_layout);
    249         ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
    250             args, NULL, filter_graph);
    251         if (ret < 0) {
    252             av_log(NULL, AV_LOG_ERROR, "Cannotcreate audio buffer source
    ");
    253             goto end;
    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, "Cannotcreate audio buffer sink
    ");
    259             goto end;
    260         }
    261         ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
    262             (uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),
    263             AV_OPT_SEARCH_CHILDREN);
    264         if (ret < 0) {
    265             av_log(NULL, AV_LOG_ERROR, "Cannot setoutput sample format
    ");
    266             goto end;
    267         }
    268         ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
    269             (uint8_t*)&enc_ctx->channel_layout,
    270             sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
    271         if (ret < 0) {
    272             av_log(NULL, AV_LOG_ERROR, "Cannot setoutput channel layout
    ");
    273             goto end;
    274         }
    275         ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
    276             (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),
    277             AV_OPT_SEARCH_CHILDREN);
    278         if (ret < 0) {
    279             av_log(NULL, AV_LOG_ERROR, "Cannot setoutput sample rate
    ");
    280             goto end;
    281         }
    282     }
    283     else {
    284         ret = AVERROR_UNKNOWN;
    285         goto end;
    286     }
    287     /* Endpoints for the filter graph. */
    288     outputs->name = av_strdup("in");
    289     outputs->filter_ctx = buffersrc_ctx;
    290     outputs->pad_idx = 0;
    291     outputs->next = NULL;
    292     inputs->name = av_strdup("out");
    293     inputs->filter_ctx = buffersink_ctx;
    294     inputs->pad_idx = 0;
    295     inputs->next = NULL;
    296     if (!outputs->name || !inputs->name) {
    297         ret = AVERROR(ENOMEM);
    298         goto end;
    299     }
    300     if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
    301         &inputs, &outputs, NULL)) < 0)
    302         goto end;
    303     if ((ret = avfilter_graph_config(filter_graph, NULL))< 0)
    304         goto end;
    305     /* Fill FilteringContext */
    306     fctx->buffersrc_ctx = buffersrc_ctx;
    307     fctx->buffersink_ctx = buffersink_ctx;
    308     fctx->filter_graph = filter_graph;
    309 end:
    310     avfilter_inout_free(&inputs);
    311     avfilter_inout_free(&outputs);
    312     return ret;
    313 }
    314 
    315 static int init_filters(void)
    316 {
    317     const char*filter_spec;
    318     unsigned int i;
    319     int ret;
    320     filter_ctx = (FilteringContext *)av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
    321     if (!filter_ctx)
    322         return AVERROR(ENOMEM);
    323     for (i = 0; i < ifmt_ctx->nb_streams; i++) {
    324         filter_ctx[i].buffersrc_ctx = NULL;
    325         filter_ctx[i].buffersink_ctx = NULL;
    326         filter_ctx[i].filter_graph = NULL;
    327         if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
    328             || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
    329             continue;
    330         if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
    331             filter_spec = "null"; /* passthrough (dummy) filter for video */
    332         else
    333             filter_spec = "anull"; /* passthrough (dummy) filter for audio */
    334 
    335         ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,
    336             ofmt_ctx->streams[i]->codec, filter_spec);
    337         if (ret)
    338             return ret;
    339     }
    340     return 0;
    341 }
    342 
    343 static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int*got_frame) {
    344     int ret;
    345     int got_frame_local;
    346     AVPacket enc_pkt;
    347     int(*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int*) =
    348         (ifmt_ctx->streams[stream_index]->codec->codec_type ==
    349         AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
    350     if (!got_frame)
    351         got_frame = &got_frame_local;
    352     av_log(NULL, AV_LOG_INFO, "Encoding frame
    ");
    353     /* encode filtered frame */
    354     enc_pkt.data = NULL;
    355     enc_pkt.size = 0;
    356     av_init_packet(&enc_pkt);
    357     ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,
    358         filt_frame, got_frame);
    359     av_frame_free(&filt_frame);
    360     if (ret < 0)
    361         return ret;
    362     if (!(*got_frame))
    363         return 0;
    364     /* prepare packet for muxing */
    365     enc_pkt.stream_index = stream_index;
    366     enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
    367         ofmt_ctx->streams[stream_index]->codec->time_base,
    368         ofmt_ctx->streams[stream_index]->time_base,
    369         (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    370     enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
    371         ofmt_ctx->streams[stream_index]->codec->time_base,
    372         ofmt_ctx->streams[stream_index]->time_base,
    373         (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    374     enc_pkt.duration = av_rescale_q(enc_pkt.duration,
    375         ofmt_ctx->streams[stream_index]->codec->time_base,
    376         ofmt_ctx->streams[stream_index]->time_base);
    377     av_log(NULL, AV_LOG_DEBUG, "Muxing frame
    ");
    378     /* mux encoded frame */
    379     ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
    380     return ret;
    381 }
    382 
    383 static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
    384 {
    385     int ret;
    386     AVFrame*filt_frame;
    387     av_log(NULL, AV_LOG_INFO, "Pushing decoded frame tofilters
    ");
    388     /* push the decoded frame into the filtergraph */
    389     ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
    390         frame, 0);
    391     if (ret < 0) {
    392         av_log(NULL, AV_LOG_ERROR, "Error whilefeeding the filtergraph
    ");
    393         return ret;
    394     }
    395     /* pull filtered frames from the filtergraph */
    396     while (1) {
    397         filt_frame = av_frame_alloc();
    398         if (!filt_frame) {
    399             ret = AVERROR(ENOMEM);
    400             break;
    401         }
    402         av_log(NULL, AV_LOG_INFO, "Pullingfiltered frame from filters
    ");
    403         ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
    404             filt_frame);
    405         if (ret < 0) {
    406             /* if nomore frames for output - returns AVERROR(EAGAIN)
    407             * if flushed and no more frames for output - returns AVERROR_EOF
    408             * rewrite retcode to 0 to show it as normal procedure completion
    409             */
    410             if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
    411                 ret = 0;
    412             av_frame_free(&filt_frame);
    413             break;
    414         }
    415         filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
    416         ret = encode_write_frame(filt_frame, stream_index, NULL);
    417         if (ret < 0)
    418             break;
    419     }
    420     return ret;
    421 }
    422 
    423 static int flush_encoder(unsigned int stream_index)
    424 {
    425     int ret;
    426     int got_frame;
    427     if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities&
    428         CODEC_CAP_DELAY))
    429         return 0;
    430     while (1) {
    431         av_log(NULL, AV_LOG_INFO, "Flushingstream #%u encoder
    ", stream_index);
    432         ret = encode_write_frame(NULL, stream_index, &got_frame);
    433         if (ret < 0)
    434             break;
    435         if (!got_frame)
    436             return 0;
    437     }
    438     return ret;
    439 }
    440 
    441 
    442 
    443 /**
    444 输入视频的封装格式是FLV,视频编码标准是H.264,音频编码标准是AAC;输出视频的封装格式是AVI,视频编码标准是MPEG2,音频编码标准是MP3
    445 */
    446 int main(int argc, char* argv[])
    447 {
    448     int ret;
    449     AVPacket packet;
    450     AVFrame *frame = NULL;
    451     enum AVMediaType type;
    452     unsigned int stream_index;
    453     unsigned int i;
    454     int got_frame;
    455     int(*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket*);
    456     if (argc != 3) {
    457         av_log(NULL, AV_LOG_ERROR, "Usage: %s<input file> <output file>
    ", argv[0]);
    458         return 1;
    459     }
    460     av_register_all();
    461     avfilter_register_all();
    462 
    463     const char* input_filename = argv[1];
    464     const char* output_filename = argv[2];
    465 
    466     if ((ret = open_input_file(input_filename)) < 0)
    467         goto end;
    468     if ((ret = open_output_file(output_filename)) < 0)
    469         goto end;
    470     if ((ret = init_filters()) < 0)
    471         goto end;
    472     /* read all packets */
    473     while (1)
    474     {
    475         if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
    476             break;
    477         stream_index = packet.stream_index;
    478         type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
    479         av_log(NULL, AV_LOG_DEBUG, "Demuxergave frame of stream_index %u
    ",
    480             stream_index);
    481         if (filter_ctx[stream_index].filter_graph) {
    482             av_log(NULL, AV_LOG_DEBUG, "Going toreencode&filter the frame
    ");
    483             frame = av_frame_alloc();
    484             if (!frame) {
    485                 ret = AVERROR(ENOMEM);
    486                 break;
    487             }
    488             packet.dts = av_rescale_q_rnd(packet.dts,
    489                 ifmt_ctx->streams[stream_index]->time_base,
    490                 ifmt_ctx->streams[stream_index]->codec->time_base,
    491                 (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    492             packet.pts = av_rescale_q_rnd(packet.pts,
    493                 ifmt_ctx->streams[stream_index]->time_base,
    494                 ifmt_ctx->streams[stream_index]->codec->time_base,
    495                 (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    496             dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
    497                 avcodec_decode_audio4;
    498             ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
    499                 &got_frame, &packet);
    500             if (ret < 0) {
    501                 av_frame_free(&frame);
    502                 av_log(NULL, AV_LOG_ERROR, "Decodingfailed
    ");
    503                 break;
    504             }
    505             if (got_frame) {
    506                 frame->pts = av_frame_get_best_effort_timestamp(frame);
    507                 ret = filter_encode_write_frame(frame, stream_index);
    508                 av_frame_free(&frame);
    509                 if (ret < 0)
    510                     ;//goto end;
    511             }
    512             else {
    513                 av_frame_free(&frame);
    514             }
    515         }
    516         else {
    517             /* remux this frame without reencoding */
    518             packet.dts = av_rescale_q_rnd(packet.dts,
    519                 ifmt_ctx->streams[stream_index]->time_base,
    520                 ofmt_ctx->streams[stream_index]->time_base,
    521                 (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    522             packet.pts = av_rescale_q_rnd(packet.pts,
    523                 ifmt_ctx->streams[stream_index]->time_base,
    524                 ofmt_ctx->streams[stream_index]->time_base,
    525                 (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    526             ret = av_interleaved_write_frame(ofmt_ctx, &packet);
    527             if (ret < 0)
    528                 goto end;
    529         }
    530         av_free_packet(&packet);
    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, "Flushingfilter failed
    ");
    540             goto end;
    541         }
    542         /* flush encoder */
    543         ret = flush_encoder(i);
    544         if (ret < 0) {
    545             av_log(NULL, AV_LOG_ERROR, "Flushingencoder failed
    ");
    546             goto end;
    547         }
    548     }
    549     av_write_trailer(ofmt_ctx);
    550 end:
    551     av_free_packet(&packet);
    552     av_frame_free(&frame);
    553     for (i = 0; i < ifmt_ctx->nb_streams; i++) {
    554         avcodec_close(ifmt_ctx->streams[i]->codec);
    555         if (ofmt_ctx && ofmt_ctx->nb_streams >i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)
    556             avcodec_close(ofmt_ctx->streams[i]->codec);
    557         if (filter_ctx && filter_ctx[i].filter_graph)
    558             avfilter_graph_free(&filter_ctx[i].filter_graph);
    559     }
    560     av_free(filter_ctx);
    561     avformat_close_input(&ifmt_ctx);
    562     if (ofmt_ctx &&!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
    563         avio_close(ofmt_ctx->pb);
    564     avformat_free_context(ofmt_ctx);
    565     if (ret < 0)
    566         av_log(NULL, AV_LOG_ERROR, "Erroroccurred
    ");
    567     return (ret ? 1 : 0);
    568 }
    View Code
  • 相关阅读:
    Java多线程同步和异步问题
    最优二叉查找树
    岛屿的周长
    Mac 环境下 go 国内代理配置
    岛屿数量
    字符串解码
    环形链表 II
    颜色分类
    无重复字符的最长子串
    完全平方数
  • 原文地址:https://www.cnblogs.com/baigoogledu/p/9110038.html
Copyright © 2020-2023  润新知