]> git.sesse.net Git - ffmpeg/blobdiff - avconv.c
hevc: decouple calling get_format() from exporting the SPS parameters
[ffmpeg] / avconv.c
index 778de654cb0802f777eb9360e9d6a37004a49f9c..5c31332812b743b7f3907808c4b0ab06348d98d2 100644 (file)
--- a/avconv.c
+++ b/avconv.c
@@ -38,6 +38,7 @@
 #include "libavutil/parseutils.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/fifo.h"
+#include "libavutil/hwcontext.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
@@ -190,7 +191,6 @@ static void avconv_cleanup(int ret)
         for (j = 0; j < ost->nb_bitstream_filters; j++)
             av_bsf_free(&ost->bsf_ctx[j]);
         av_freep(&ost->bsf_ctx);
-        av_freep(&ost->bitstream_filters);
 
         av_frame_free(&ost->filtered_frame);
 
@@ -203,13 +203,14 @@ static void avconv_cleanup(int ret)
 
         avcodec_free_context(&ost->enc_ctx);
 
-        while (av_fifo_size(ost->muxing_queue)) {
-            AVPacket pkt;
-            av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
-            av_packet_unref(&pkt);
+        if (ost->muxing_queue) {
+            while (av_fifo_size(ost->muxing_queue)) {
+                AVPacket pkt;
+                av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
+                av_packet_unref(&pkt);
+            }
+            av_fifo_free(ost->muxing_queue);
         }
-        av_fifo_free(ost->muxing_queue);
-
         av_freep(&output_streams[i]);
     }
     for (i = 0; i < nb_input_files; i++) {
@@ -764,6 +765,15 @@ static int poll_filters(void)
         for (i = 0; i < nb_output_streams; i++) {
             int64_t pts = output_streams[i]->sync_opts;
 
+            if (output_streams[i]->filter && !output_streams[i]->filter->graph->graph &&
+                !output_streams[i]->filter->graph->nb_inputs) {
+                ret = configure_filtergraph(output_streams[i]->filter->graph);
+                if (ret < 0) {
+                    av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n");
+                    return ret;
+                }
+            }
+
             if (!output_streams[i]->filter || output_streams[i]->finished ||
                 !output_streams[i]->filter->graph->graph)
                 continue;
@@ -1242,6 +1252,34 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
     return 0;
 }
 
+static int ifilter_send_eof(InputFilter *ifilter)
+{
+    int i, j, ret;
+
+    ifilter->eof = 1;
+
+    if (ifilter->filter) {
+        ret = av_buffersrc_add_frame(ifilter->filter, NULL);
+        if (ret < 0)
+            return ret;
+    } else {
+        // the filtergraph was never configured
+        FilterGraph *fg = ifilter->graph;
+        for (i = 0; i < fg->nb_inputs; i++)
+            if (!fg->inputs[i]->eof)
+                break;
+        if (i == fg->nb_inputs) {
+            // All the input streams have finished without the filtergraph
+            // ever being configured.
+            // Mark the output streams as finished.
+            for (j = 0; j < fg->nb_outputs; j++)
+                finish_output_stream(fg->outputs[j]->ost);
+        }
+    }
+
+    return 0;
+}
+
 // This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
 // There is the following difference: if you got a frame, you must call
 // it again with pkt=NULL. pkt==NULL is treated differently from pkt.size==0
@@ -1287,7 +1325,8 @@ int guess_input_channel_layout(InputStream *ist)
     return 1;
 }
 
-static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
+static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
+                        int *decode_failed)
 {
     AVFrame *decoded_frame, *f;
     AVCodecContext *avctx = ist->dec_ctx;
@@ -1300,6 +1339,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
     decoded_frame = ist->decoded_frame;
 
     ret = decode(avctx, decoded_frame, got_output, pkt);
+    if (ret < 0)
+        *decode_failed = 1;
     if (!*got_output || ret < 0)
         return ret;
 
@@ -1309,7 +1350,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
     /* if the decoder provides a pts, use it instead of the last packet pts.
        the decoder could be delaying output by a packet or more. */
     if (decoded_frame->pts != AV_NOPTS_VALUE)
-        ist->next_dts = decoded_frame->pts;
+        ist->next_dts = av_rescale_q(decoded_frame->pts, ist->st->time_base, AV_TIME_BASE_Q);
     else if (pkt && pkt->pts != AV_NOPTS_VALUE) {
         decoded_frame->pts = pkt->pts;
     }
@@ -1338,7 +1379,8 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
     return err < 0 ? err : ret;
 }
 
-static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
+static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output,
+                        int *decode_failed)
 {
     AVFrame *decoded_frame, *f;
     int i, ret = 0, err = 0;
@@ -1350,6 +1392,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
     decoded_frame = ist->decoded_frame;
 
     ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt);
+    if (ret < 0)
+        *decode_failed = 1;
     if (!*got_output || ret < 0)
         return ret;
 
@@ -1364,6 +1408,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
 
     decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pts,
                                            decoded_frame->pkt_dts);
+    if (ist->framerate.num)
+        decoded_frame->pts = ist->cfr_next_pts++;
 
     if (ist->st->sample_aspect_ratio.num)
         decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
@@ -1388,13 +1434,16 @@ fail:
     return err < 0 ? err : ret;
 }
 
-static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
+static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output,
+                               int *decode_failed)
 {
     AVSubtitle subtitle;
     int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,
                                           &subtitle, got_output, pkt);
-    if (ret < 0)
+    if (ret < 0) {
+        *decode_failed = 1;
         return ret;
+    }
     if (!*got_output)
         return ret;
 
@@ -1415,18 +1464,11 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
 
 static int send_filter_eof(InputStream *ist)
 {
-    int i, j, ret;
+    int i, ret;
     for (i = 0; i < ist->nb_filters; i++) {
-        if (ist->filters[i]->filter) {
-            ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
-            if (ret < 0)
-                return ret;
-        } else {
-            // the filtergraph was never configured
-            FilterGraph *fg = ist->filters[i]->graph;
-            for (j = 0; j < fg->nb_outputs; j++)
-                finish_output_stream(fg->outputs[j]->ost);
-        }
+        ret = ifilter_send_eof(ist->filters[i]);
+        if (ret < 0)
+            return ret;
     }
     return 0;
 }
@@ -1457,16 +1499,19 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e
     while (ist->decoding_needed && (!pkt || avpkt.size > 0)) {
         int ret = 0;
         int got_output = 0;
+        int decode_failed = 0;
 
         if (!repeating)
             ist->last_dts = ist->next_dts;
 
         switch (ist->dec_ctx->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
-            ret = decode_audio    (ist, repeating ? NULL : &avpkt, &got_output);
+            ret = decode_audio    (ist, repeating ? NULL : &avpkt, &got_output,
+                                   &decode_failed);
             break;
         case AVMEDIA_TYPE_VIDEO:
-            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output);
+            ret = decode_video    (ist, repeating ? NULL : &avpkt, &got_output,
+                                   &decode_failed);
             if (repeating && !got_output)
                 ;
             else if (pkt && pkt->duration)
@@ -1483,16 +1528,21 @@ static void process_input_packet(InputStream *ist, const AVPacket *pkt, int no_e
         case AVMEDIA_TYPE_SUBTITLE:
             if (repeating)
                 break;
-            ret = transcode_subtitles(ist, &avpkt, &got_output);
+            ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed);
             break;
         default:
             return;
         }
 
         if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
-                   ist->file_index, ist->st->index);
-            if (exit_on_error)
+            if (decode_failed) {
+                av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
+                       ist->file_index, ist->st->index);
+            } else {
+                av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded "
+                       "data for stream #%d:%d\n", ist->file_index, ist->st->index);
+            }
+            if (!decode_failed || exit_on_error)
                 exit_program(1);
             break;
         }
@@ -1747,17 +1797,8 @@ static int init_output_bsfs(OutputStream *ost)
     if (!ost->nb_bitstream_filters)
         return 0;
 
-    ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx));
-    if (!ost->bsf_ctx)
-        return AVERROR(ENOMEM);
-
     for (i = 0; i < ost->nb_bitstream_filters; i++) {
-        ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx);
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n");
-            return ret;
-        }
-        ost->bsf_ctx[i] = ctx;
+        ctx = ost->bsf_ctx[i];
 
         ret = avcodec_parameters_copy(ctx->par_in,
                                       i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
@@ -1769,12 +1810,11 @@ static int init_output_bsfs(OutputStream *ost)
         ret = av_bsf_init(ctx);
         if (ret < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
-                   ost->bitstream_filters[i]->name);
+                   ctx->filter->name);
             return ret;
         }
     }
 
-    ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1];
     ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
     if (ret < 0)
         return ret;
@@ -1791,39 +1831,23 @@ static int init_output_stream_streamcopy(OutputStream *ost)
     AVCodecParameters *par_dst = ost->st->codecpar;
     AVCodecParameters *par_src = ist->st->codecpar;
     AVRational sar;
-    int i;
-    uint64_t extra_size;
-
-    extra_size = (uint64_t)par_src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE;
-    if (extra_size > INT_MAX) {
-        return AVERROR(EINVAL);
-    }
-
-    ost->st->disposition = ist->st->disposition;
-
-    /* if stream_copy is selected, no need to decode or encode */
-    par_dst->codec_id   = par_src->codec_id;
-    par_dst->codec_type = par_src->codec_type;
+    uint32_t codec_tag = par_dst->codec_tag;
+    int i, ret;
 
-    if (!par_dst->codec_tag) {
+    if (!codec_tag) {
         if (!of->ctx->oformat->codec_tag ||
-             av_codec_get_id (of->ctx->oformat->codec_tag, par_src->codec_tag) == par_dst->codec_id ||
+             av_codec_get_id (of->ctx->oformat->codec_tag, par_src->codec_tag) == par_src->codec_id ||
              av_codec_get_tag(of->ctx->oformat->codec_tag, par_src->codec_id) <= 0)
-            par_dst->codec_tag = par_src->codec_tag;
+            codec_tag = par_src->codec_tag;
     }
 
-    par_dst->bit_rate        = par_src->bit_rate;
-    par_dst->field_order     = par_src->field_order;
-    par_dst->chroma_location = par_src->chroma_location;
+    ret = avcodec_parameters_copy(par_dst, par_src);
+    if (ret < 0)
+        return ret;
 
-    if (par_src->extradata) {
-        par_dst->extradata       = av_mallocz(extra_size);
-        if (!par_dst->extradata) {
-            return AVERROR(ENOMEM);
-        }
-        memcpy(par_dst->extradata, par_src->extradata, par_src->extradata_size);
-        par_dst->extradata_size = par_src->extradata_size;
-    }
+    par_dst->codec_tag = codec_tag;
+
+    ost->st->disposition = ist->st->disposition;
 
     ost->st->time_base = ist->st->time_base;
 
@@ -1852,21 +1876,7 @@ static int init_output_stream_streamcopy(OutputStream *ost)
     if (!ost->parser_avctx)
         return AVERROR(ENOMEM);
 
-    switch (par_dst->codec_type) {
-    case AVMEDIA_TYPE_AUDIO:
-        if (audio_volume != 256) {
-            av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
-            exit_program(1);
-        }
-        par_dst->channel_layout     = par_src->channel_layout;
-        par_dst->sample_rate        = par_src->sample_rate;
-        par_dst->channels           = par_src->channels;
-        par_dst->block_align        = par_src->block_align;
-        break;
-    case AVMEDIA_TYPE_VIDEO:
-        par_dst->format             = par_src->format;
-        par_dst->width              = par_src->width;
-        par_dst->height             = par_src->height;
+    if (par_dst->codec_type == AVMEDIA_TYPE_VIDEO) {
         if (ost->frame_aspect_ratio)
             sar = av_d2q(ost->frame_aspect_ratio * par_dst->height / par_dst->width, 255);
         else if (ist->st->sample_aspect_ratio.num)
@@ -1874,16 +1884,6 @@ static int init_output_stream_streamcopy(OutputStream *ost)
         else
             sar = par_src->sample_aspect_ratio;
         ost->st->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar;
-        break;
-    case AVMEDIA_TYPE_SUBTITLE:
-        par_dst->width  = par_src->width;
-        par_dst->height = par_src->height;
-        break;
-    case AVMEDIA_TYPE_DATA:
-    case AVMEDIA_TYPE_ATTACHMENT:
-        break;
-    default:
-        abort();
     }
 
     return 0;
@@ -1984,6 +1984,8 @@ static int init_output_stream_encode(OutputStream *ost)
             ost->filter->filter->inputs[0]->sample_aspect_ratio;
         enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format;
 
+        enc_ctx->framerate = ost->frame_rate;
+
         ost->st->avg_frame_rate = ost->frame_rate;
 
         if (dec_ctx &&
@@ -2033,7 +2035,9 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
         if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
             av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
 
-        if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx) {
+        if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx &&
+            ((AVHWFramesContext*)ost->filter->filter->inputs[0]->hw_frames_ctx->data)->format ==
+            ost->filter->filter->inputs[0]->format) {
             ost->enc_ctx->hw_frames_ctx = av_buffer_ref(ost->filter->filter->inputs[0]->hw_frames_ctx);
             if (!ost->enc_ctx->hw_frames_ctx)
                 return AVERROR(ENOMEM);