Advertisement
Guest User

WebM transcode w/ incorrect frame rate

a guest
Apr 15th, 2014
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.08 KB | None | 0 0
  1. /*
  2.  * Copyright (c) 2010 Nicolas George
  3.  * Copyright (c) 2011 Stefano Sabatini
  4.  * Copyright (c) 2014 Andrey Utkin
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7.  * of this software and associated documentation files (the "Software"), to deal
  8.  * in the Software without restriction, including without limitation the rights
  9.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10.  * copies of the Software, and to permit persons to whom the Software is
  11.  * furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in
  14.  * all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22.  * THE SOFTWARE.
  23.  */
  24.  
  25. /**
  26.  * @file
  27.  * API example for demuxing, decoding, filtering, encoding and muxing
  28.  * @example doc/examples/transcoding.c
  29.  */
  30.  
  31. #include <libavcodec/avcodec.h>
  32. #include <libavformat/avformat.h>
  33. #include <libavfilter/avfiltergraph.h>
  34. #include <libavfilter/avcodec.h>
  35. #include <libavfilter/buffersink.h>
  36. #include <libavfilter/buffersrc.h>
  37. #include <libavutil/opt.h>
  38. #include <libavutil/pixdesc.h>
  39.  
  40. #define STATS_LOG "stats.log"
  41.  
  42. static AVFormatContext *ifmt_ctx;
  43. static AVFormatContext *ofmt_ctx;
  44. typedef struct FilteringContext {
  45.   AVFilterContext *buffersink_ctx;
  46.   AVFilterContext *buffersrc_ctx;
  47.   AVFilterGraph *filter_graph;
  48. } FilteringContext;
  49. static FilteringContext *filter_ctx;
  50.  
  51. static int open_input_file(const char *filename) {
  52.   int ret;
  53.   unsigned int i;
  54.  
  55.   ifmt_ctx = NULL;
  56.   if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
  57.     av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
  58.     return ret;
  59.   }
  60.  
  61.   if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
  62.     av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
  63.     return ret;
  64.   }
  65.  
  66.   for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  67.     AVStream *stream;
  68.     AVCodecContext *codec_ctx;
  69.     stream = ifmt_ctx->streams[i];
  70.     codec_ctx = stream->codec;
  71.     /* Reencode video & audio and remux subtitles etc. */
  72.     if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
  73.     || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
  74.       /* Open decoder */
  75.       ret = avcodec_open2(codec_ctx,
  76.               avcodec_find_decoder(codec_ctx->codec_id), NULL);
  77.       if (ret < 0) {
  78.     av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
  79.     return ret;
  80.       }
  81.     }
  82.   }
  83.  
  84.   av_dump_format(ifmt_ctx, 0, filename, 0);
  85.   return 0;
  86. }
  87.  
  88. static int init_output_context(char* filename) {
  89.   int ret;
  90.   ofmt_ctx = NULL;
  91.  
  92.   avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
  93.   if (!ofmt_ctx) {
  94.     av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
  95.     return AVERROR_UNKNOWN;
  96.   }
  97.  
  98.   return 0;
  99. }
  100.  
  101. static int init_webm_encoders(int audioBitRate, int crf, int videoMaxBitRate, int threads,
  102.                   char* quality, int speed, int pass, char* stats) {
  103.   AVStream *out_stream;
  104.   AVStream *in_stream;
  105.   AVCodecContext *dec_ctx, *enc_ctx;
  106.   AVCodec *encoder;
  107.   int ret;
  108.   unsigned int i;
  109.  
  110.   for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  111.     in_stream = ifmt_ctx->streams[i];
  112.     dec_ctx = in_stream->codec;
  113.     if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
  114.  
  115.       AVDictionary *opts = NULL;
  116.       if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
  117.     encoder = avcodec_find_encoder(AV_CODEC_ID_VP8);
  118.     out_stream = avformat_new_stream(ofmt_ctx, encoder);
  119.     if (!out_stream) {
  120.       av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
  121.       return AVERROR_UNKNOWN;
  122.     }
  123.  
  124.     enc_ctx = out_stream->codec;
  125.     enc_ctx->height = dec_ctx->height;
  126.     enc_ctx->width = dec_ctx->width;
  127.     enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
  128.     /* take first format from list of supported formats */
  129.     enc_ctx->pix_fmt = encoder->pix_fmts[0];
  130.     /* video time_base can be set to whatever is handy and supported by encoder */
  131.     /* enc_ctx->time_base = dec_ctx->time_base; */
  132.     enc_ctx->time_base.num = 1;
  133.     enc_ctx->time_base.den = 24;
  134.  
  135.     enc_ctx->bit_rate = videoMaxBitRate;
  136.     enc_ctx->thread_count = threads;
  137.     switch (pass) {
  138.     case 1:
  139.       enc_ctx->flags |= CODEC_FLAG_PASS1;
  140.       break;
  141.     case 2:
  142.       enc_ctx->flags |= CODEC_FLAG_PASS2;
  143.       if (stats) {
  144.         enc_ctx->stats_in = stats;
  145.       }
  146.       break;
  147.     }
  148.  
  149.     char crfString[3];
  150.     snprintf(crfString, 3, "%d", crf);
  151.     av_dict_set(&opts, "crf", crfString, 0);
  152.     av_dict_set(&opts, "quality", quality, 0);
  153.     char speedString[3];
  154.     snprintf(speedString, 3, "%d", speed);
  155.     av_dict_set(&opts, "speed", speedString, 0);
  156.       } else {
  157.     encoder = avcodec_find_encoder(AV_CODEC_ID_VORBIS);
  158.     out_stream = avformat_new_stream(ofmt_ctx, encoder);
  159.     if (!out_stream) {
  160.       av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
  161.       return AVERROR_UNKNOWN;
  162.     }
  163.  
  164.     /* in_stream = ifmt_ctx->streams[i]; */
  165.     /* dec_ctx = in_stream->codec; */
  166.     enc_ctx = out_stream->codec;
  167.     /* encoder = out_stream->codec->codec; */
  168.  
  169.     enc_ctx->sample_rate = dec_ctx->sample_rate;
  170.     enc_ctx->channel_layout = dec_ctx->channel_layout;
  171.     enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
  172.     /* take first format from list of supported formats */
  173.     enc_ctx->sample_fmt = encoder->sample_fmts[0];
  174.     enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
  175.     enc_ctx->bit_rate = audioBitRate;
  176.       }
  177.  
  178.       /* Open codec with the set options */
  179.       ret = avcodec_open2(enc_ctx, encoder, &opts);
  180.       if (ret < 0) {
  181.     av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
  182.     return ret;
  183.       }
  184.       int unused = av_dict_count(opts);
  185.       if (unused > 0) {
  186.     av_log(NULL, AV_LOG_WARNING, "%d unused options\n", unused);
  187.       }
  188.     /* } else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) { */
  189.     } else {
  190.       av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
  191.       return AVERROR_INVALIDDATA;
  192.     } /* else { */
  193.     /*   /\* if this stream must be remuxed *\/ */
  194.     /*   ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec, */
  195.     /*               ifmt_ctx->streams[i]->codec); */
  196.     /*   if (ret < 0) { */
  197.     /*  av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n"); */
  198.     /*  return ret; */
  199.     /*   } */
  200.     /* } */
  201.  
  202.     if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
  203.       enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
  204.   }
  205.  
  206.   return 0;
  207. }
  208.  
  209. static int open_output_file(const char *filename) {
  210.   int ret;
  211.  
  212.   av_dump_format(ofmt_ctx, 0, filename, 1);
  213.  
  214.   if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
  215.     ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
  216.     if (ret < 0) {
  217.       av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename);
  218.       return ret;
  219.     }
  220.   }
  221.  
  222.   /* init muxer, write output file header */
  223.   ret = avformat_write_header(ofmt_ctx, NULL);
  224.   if (ret < 0) {
  225.     av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
  226.     return ret;
  227.   }
  228.  
  229.   return 0;
  230. }
  231.  
  232. static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
  233.                AVCodecContext *enc_ctx, const char *filter_spec) {
  234.   char args[512];
  235.   int ret = 0;
  236.   AVFilter *buffersrc = NULL;
  237.   AVFilter *buffersink = NULL;
  238.   AVFilterContext *buffersrc_ctx = NULL;
  239.   AVFilterContext *buffersink_ctx = NULL;
  240.   AVFilterInOut *outputs = avfilter_inout_alloc();
  241.   AVFilterInOut *inputs  = avfilter_inout_alloc();
  242.   AVFilterGraph *filter_graph = avfilter_graph_alloc();
  243.  
  244.   if (!outputs || !inputs || !filter_graph) {
  245.     ret = AVERROR(ENOMEM);
  246.     goto end;
  247.   }
  248.  
  249.   if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
  250.     buffersrc = avfilter_get_by_name("buffer");
  251.     buffersink = avfilter_get_by_name("buffersink");
  252.     if (!buffersrc || !buffersink) {
  253.       av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
  254.       ret = AVERROR_UNKNOWN;
  255.       goto end;
  256.     }
  257.  
  258.     snprintf(args, sizeof(args),
  259.          "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
  260.          dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
  261.          dec_ctx->time_base.num, dec_ctx->time_base.den,
  262.          dec_ctx->sample_aspect_ratio.num,
  263.          dec_ctx->sample_aspect_ratio.den);
  264.  
  265.     ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
  266.                        args, NULL, filter_graph);
  267.     if (ret < 0) {
  268.       av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
  269.       goto end;
  270.     }
  271.  
  272.     ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
  273.                        NULL, NULL, filter_graph);
  274.     if (ret < 0) {
  275.       av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
  276.       goto end;
  277.     }
  278.  
  279.     ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
  280.              (uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
  281.              AV_OPT_SEARCH_CHILDREN);
  282.     if (ret < 0) {
  283.       av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
  284.       goto end;
  285.     }
  286.   } else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
  287.     buffersrc = avfilter_get_by_name("abuffer");
  288.     buffersink = avfilter_get_by_name("abuffersink");
  289.     if (!buffersrc || !buffersink) {
  290.       av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
  291.       ret = AVERROR_UNKNOWN;
  292.       goto end;
  293.     }
  294.  
  295.     if (!dec_ctx->channel_layout)
  296.       dec_ctx->channel_layout =
  297.     av_get_default_channel_layout(dec_ctx->channels);
  298.     snprintf(args, sizeof(args),
  299.          "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
  300.          dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
  301.          av_get_sample_fmt_name(dec_ctx->sample_fmt),
  302.          dec_ctx->channel_layout);
  303.     ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
  304.                        args, NULL, filter_graph);
  305.     if (ret < 0) {
  306.       av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
  307.       goto end;
  308.     }
  309.  
  310.     ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
  311.                        NULL, NULL, filter_graph);
  312.     if (ret < 0) {
  313.       av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
  314.       goto end;
  315.     }
  316.  
  317.     ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
  318.              (uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),
  319.              AV_OPT_SEARCH_CHILDREN);
  320.     if (ret < 0) {
  321.       av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
  322.       goto end;
  323.     }
  324.  
  325.     ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
  326.              (uint8_t*)&enc_ctx->channel_layout,
  327.              sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
  328.     if (ret < 0) {
  329.       av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
  330.       goto end;
  331.     }
  332.  
  333.     ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
  334.              (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),
  335.              AV_OPT_SEARCH_CHILDREN);
  336.     if (ret < 0) {
  337.       av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
  338.       goto end;
  339.     }
  340.   } else {
  341.     ret = AVERROR_UNKNOWN;
  342.     goto end;
  343.   }
  344.  
  345.   /* Endpoints for the filter graph. */
  346.   outputs->name       = av_strdup("in");
  347.   outputs->filter_ctx = buffersrc_ctx;
  348.   outputs->pad_idx    = 0;
  349.   outputs->next       = NULL;
  350.  
  351.   inputs->name       = av_strdup("out");
  352.   inputs->filter_ctx = buffersink_ctx;
  353.   inputs->pad_idx    = 0;
  354.   inputs->next       = NULL;
  355.  
  356.   if (!outputs->name || !inputs->name) {
  357.     ret = AVERROR(ENOMEM);
  358.     goto end;
  359.   }
  360.  
  361.   if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
  362.                       &inputs, &outputs, NULL)) < 0)
  363.     goto end;
  364.  
  365.   if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
  366.     goto end;
  367.  
  368.   /* Fill FilteringContext */
  369.   fctx->buffersrc_ctx = buffersrc_ctx;
  370.   fctx->buffersink_ctx = buffersink_ctx;
  371.   fctx->filter_graph = filter_graph;
  372.  
  373.  end:
  374.   avfilter_inout_free(&inputs);
  375.   avfilter_inout_free(&outputs);
  376.  
  377.   return ret;
  378. }
  379.  
  380. static int init_filters(enum AVCodecID audioCodec) {
  381.   const char *filter_spec;
  382.   unsigned int i;
  383.   int ret;
  384.   filter_ctx = av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
  385.   if (!filter_ctx)
  386.     return AVERROR(ENOMEM);
  387.  
  388.   for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  389.     filter_ctx[i].buffersrc_ctx  = NULL;
  390.     filter_ctx[i].buffersink_ctx = NULL;
  391.     filter_ctx[i].filter_graph   = NULL;
  392.     /* Skip streams that are neither audio nor video */
  393.     if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
  394.       || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
  395.       continue;
  396.  
  397.  
  398.     if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
  399.       filter_spec = "null"; /* passthrough (dummy) filter for video */
  400.     else
  401.       /* TODO: make this more general */
  402.       if (audioCodec == AV_CODEC_ID_VORBIS) {
  403.     filter_spec = "asetnsamples=n=64";
  404.       } else {
  405.     filter_spec = "null"; /* passthrough (dummy) filter for audio */
  406.     /* filter_spec = "fps=24"; */
  407.     /* filter_spec = "settb=expr=1/24"; */
  408.       }
  409.     ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,
  410.               ofmt_ctx->streams[i]->codec, filter_spec);
  411.     if (ret)
  412.       return ret;
  413.   }
  414.   return 0;
  415. }
  416.  
  417. static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
  418.   int ret;
  419.   int got_frame_local;
  420.   AVPacket enc_pkt;
  421.   int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
  422.     (ifmt_ctx->streams[stream_index]->codec->codec_type ==
  423.      AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
  424.  
  425.   if (!got_frame)
  426.     got_frame = &got_frame_local;
  427.  
  428.   /* av_log(NULL, AV_LOG_INFO, "Encoding frame\n"); */
  429.   /* encode filtered frame */
  430.   enc_pkt.data = NULL;
  431.   enc_pkt.size = 0;
  432.   av_init_packet(&enc_pkt);
  433.   ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,
  434.          filt_frame, got_frame);
  435.   av_frame_free(&filt_frame);
  436.   if (ret < 0)
  437.     return ret;
  438.   if (!(*got_frame))
  439.     return 0;
  440.  
  441.   /* prepare packet for muxing */
  442.   enc_pkt.stream_index = stream_index;
  443.   enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
  444.                  ofmt_ctx->streams[stream_index]->codec->time_base,
  445.                  ofmt_ctx->streams[stream_index]->time_base,
  446.                  AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  447.   enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
  448.                  ofmt_ctx->streams[stream_index]->codec->time_base,
  449.                  ofmt_ctx->streams[stream_index]->time_base,
  450.                  AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  451.   enc_pkt.duration = av_rescale_q(enc_pkt.duration,
  452.                   ofmt_ctx->streams[stream_index]->codec->time_base,
  453.                   ofmt_ctx->streams[stream_index]->time_base);
  454.  
  455.   /* av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); */
  456.   /* mux encoded frame */
  457.   ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
  458.   return ret;
  459. }
  460.  
  461. static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) {
  462.   int ret;
  463.   AVFrame *filt_frame;
  464.  
  465.   /* av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n"); */
  466.   /* push the decoded frame into the filtergraph */
  467.   ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
  468.                      frame, 0);
  469.   if (ret < 0) {
  470.     av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
  471.     return ret;
  472.   }
  473.  
  474.   /* pull filtered frames from the filtergraph */
  475.   while (1) {
  476.     filt_frame = av_frame_alloc();
  477.     if (!filt_frame) {
  478.       ret = AVERROR(ENOMEM);
  479.       break;
  480.     }
  481.     /* av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n"); */
  482.     ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
  483.                   filt_frame);
  484.     if (ret < 0) {
  485.       /* if no more frames for output - returns AVERROR(EAGAIN)
  486.        * if flushed and no more frames for output - returns AVERROR_EOF
  487.        * rewrite retcode to 0 to show it as normal procedure completion
  488.        */
  489.       if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  490.     ret = 0;
  491.       av_frame_free(&filt_frame);
  492.       break;
  493.     }
  494.  
  495.     filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
  496.     ret = encode_write_frame(filt_frame, stream_index, NULL);
  497.     if (ret < 0)
  498.       break;
  499.   }
  500.  
  501.   return ret;
  502. }
  503.  
  504. static int flush_encoder(unsigned int stream_index) {
  505.   int ret;
  506.   int got_frame;
  507.  
  508.   if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
  509.     CODEC_CAP_DELAY))
  510.     return 0;
  511.  
  512.   while (1) {
  513.     av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
  514.     ret = encode_write_frame(NULL, stream_index, &got_frame);
  515.     if (ret < 0)
  516.       break;
  517.     if (!got_frame)
  518.       return 0;
  519.   }
  520.   return ret;
  521. }
  522.  
  523. static int transcode() {
  524.   int ret;
  525.   AVPacket packet = { .data = NULL, .size = 0 };
  526.   AVFrame *frame = NULL;
  527.   enum AVMediaType type;
  528.   unsigned int stream_index;
  529.   unsigned int i;
  530.   int got_frame;
  531.   int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
  532.  
  533.   /* read all packets */
  534.   while (1) {
  535.     if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
  536.       break;
  537.     stream_index = packet.stream_index;
  538.     type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
  539.     av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
  540.        stream_index);
  541.  
  542.     if (filter_ctx[stream_index].filter_graph) {
  543.       av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
  544.       frame = av_frame_alloc();
  545.       if (!frame) {
  546.     ret = AVERROR(ENOMEM);
  547.     break;
  548.       }
  549.       packet.dts = av_rescale_q_rnd(packet.dts,
  550.                     ifmt_ctx->streams[stream_index]->time_base,
  551.                     ifmt_ctx->streams[stream_index]->codec->time_base,
  552.                     AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  553.       packet.pts = av_rescale_q_rnd(packet.pts,
  554.                     ifmt_ctx->streams[stream_index]->time_base,
  555.                     ifmt_ctx->streams[stream_index]->codec->time_base,
  556.                     AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  557.       dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
  558.     avcodec_decode_audio4;
  559.       ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
  560.              &got_frame, &packet);
  561.       if (ret < 0) {
  562.     av_frame_free(&frame);
  563.     av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
  564.     break;
  565.       }
  566.  
  567.       if (got_frame) {
  568.     frame->pts = av_frame_get_best_effort_timestamp(frame);
  569.     ret = filter_encode_write_frame(frame, stream_index);
  570.     av_frame_free(&frame);
  571.     if (ret < 0)
  572.       goto end;
  573.       } else {
  574.     av_frame_free(&frame);
  575.       }
  576.     } else {
  577.       /* remux this frame without reencoding */
  578.       packet.dts = av_rescale_q_rnd(packet.dts,
  579.                     ifmt_ctx->streams[stream_index]->time_base,
  580.                     ofmt_ctx->streams[stream_index]->time_base,
  581.                     AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  582.       packet.pts = av_rescale_q_rnd(packet.pts,
  583.                     ifmt_ctx->streams[stream_index]->time_base,
  584.                     ofmt_ctx->streams[stream_index]->time_base,
  585.                     AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  586.  
  587.       ret = av_interleaved_write_frame(ofmt_ctx, &packet);
  588.       if (ret < 0)
  589.     goto end;
  590.     }
  591.     av_free_packet(&packet);
  592.   }
  593.  
  594.   /* flush filters and encoders */
  595.   for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  596.     /* flush filter */
  597.     if (!filter_ctx[i].filter_graph)
  598.       continue;
  599.     ret = filter_encode_write_frame(NULL, i);
  600.     if (ret < 0) {
  601.       av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n");
  602.       goto end;
  603.     }
  604.  
  605.     /* flush encoder */
  606.     ret = flush_encoder(i);
  607.     if (ret < 0) {
  608.       av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
  609.       goto end;
  610.     }
  611.   }
  612.  
  613.   av_write_trailer(ofmt_ctx);
  614.  
  615.   // Retrieve and store the first instance of codec statistics
  616.   // TODO: less naive, deal with multiple instances of statistics
  617.   for (i = 0; i < ofmt_ctx->nb_streams; i++) {
  618.     AVCodecContext* codec = ofmt_ctx->streams[i]->codec;
  619.     if ((codec->flags & CODEC_FLAG_PASS1) && (codec->stats_out)){
  620.     FILE* logfile = fopen(STATS_LOG, "wb");
  621.     fprintf(logfile, "%s", codec->stats_out);
  622.     if (fclose(logfile) < 0) {
  623.       av_log(NULL, AV_LOG_ERROR, "Error closing log file.\n");
  624.     }
  625.     break;
  626.       }
  627.   }
  628.  
  629.   av_log(NULL, AV_LOG_INFO, "output duration = %" PRId64 "\n", ofmt_ctx->duration);
  630.  
  631.  end:
  632.   av_free_packet(&packet);
  633.   av_frame_free(&frame);
  634.   for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  635.     avcodec_close(ifmt_ctx->streams[i]->codec);
  636.     if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)
  637.       avcodec_close(ofmt_ctx->streams[i]->codec);
  638.     if (filter_ctx && filter_ctx[i].filter_graph)
  639.       avfilter_graph_free(&filter_ctx[i].filter_graph);
  640.   }
  641.   av_free(filter_ctx);
  642.   avformat_close_input(&ifmt_ctx);
  643.   if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
  644.     avio_close(ofmt_ctx->pb);
  645.   avformat_free_context(ofmt_ctx);
  646.  
  647.   if (ret < 0)
  648.     av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
  649.  
  650.   return ret ? 1 : 0;
  651. }
  652.  
  653. int TranscodeToWebM(char* inputPath, char* outputPath, int audioBitRate, int crf, int videoMaxBitRate, int threads,
  654.             char* quality, int speed) {
  655.   int ret;
  656.   unsigned int pass;
  657.   char* stats = NULL;
  658.  
  659.   av_register_all();
  660.   avfilter_register_all();
  661.  
  662.   for (pass = 1; pass <= 2; pass++) {
  663.     if ((ret = open_input_file(inputPath)) < 0)
  664.       goto end;
  665.  
  666.     if ((ret = init_output_context(outputPath)) < 0)
  667.       goto end;
  668.  
  669.     if (pass == 2) {
  670.       size_t stats_length;
  671.       if (cmdutils_read_file(STATS_LOG, &stats, &stats_length) < 0) {
  672.     av_log(NULL, AV_LOG_ERROR, "Error reading stats file.\n");
  673.     break;
  674.       }
  675.     }
  676.  
  677.     if ((ret = init_webm_encoders(audioBitRate, crf, videoMaxBitRate, threads, quality, speed, pass, stats)) < 0)
  678.       goto end;
  679.  
  680.     if ((ret = open_output_file(outputPath)) < 0)
  681.       goto end;
  682.  
  683.     if ((ret = init_filters(AV_CODEC_ID_VORBIS)) < 0)
  684.       goto end;
  685.  
  686.     if ((ret = transcode()) < 0)
  687.       goto end;
  688.   }
  689.  
  690.   if (remove(STATS_LOG) != 0) {
  691.     av_log(NULL, AV_LOG_ERROR, "Failed to remove %s\n", STATS_LOG);
  692.   }
  693.  
  694.  end:
  695.   if (ret < 0) {
  696.     av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
  697.     return ret;
  698.   }
  699.  
  700.   return 0;
  701. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement