Browse code

Merge commit '722ec3eb35bc152ce91d0a4502eca0df1c0086d0'

* commit '722ec3eb35bc152ce91d0a4502eca0df1c0086d0':
avconv: decouple configuring filtergraphs and setting input parameters

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>

Hendrik Leppkes authored on 2016/11/03 22:53:58
Showing 4 changed files
... ...
@@ -471,6 +471,7 @@ static void ffmpeg_cleanup(int ret)
471 471
         FilterGraph *fg = filtergraphs[i];
472 472
         avfilter_graph_free(&fg->graph);
473 473
         for (j = 0; j < fg->nb_inputs; j++) {
474
+            av_buffer_unref(&fg->inputs[j]->hw_frames_ctx);
474 475
             av_freep(&fg->inputs[j]->name);
475 476
             av_freep(&fg->inputs[j]);
476 477
         }
... ...
@@ -2128,6 +2129,16 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
2128 2128
         ist->resample_channel_layout = decoded_frame->channel_layout;
2129 2129
         ist->resample_channels       = avctx->channels;
2130 2130
 
2131
+        for (i = 0; i < ist->nb_filters; i++) {
2132
+            err = ifilter_parameters_from_frame(ist->filters[i], decoded_frame);
2133
+            if (err < 0) {
2134
+                av_log(NULL, AV_LOG_ERROR,
2135
+                       "Error reconfiguring input stream %d:%d filter %d\n",
2136
+                       ist->file_index, ist->st->index, i);
2137
+                goto fail;
2138
+            }
2139
+        }
2140
+
2131 2141
         for (i = 0; i < nb_filtergraphs; i++)
2132 2142
             if (ist_in_filtergraph(filtergraphs[i], ist)) {
2133 2143
                 FilterGraph *fg = filtergraphs[i];
... ...
@@ -2169,6 +2180,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
2169 2169
     }
2170 2170
     decoded_frame->pts = AV_NOPTS_VALUE;
2171 2171
 
2172
+fail:
2172 2173
     av_frame_unref(ist->filter_frame);
2173 2174
     av_frame_unref(decoded_frame);
2174 2175
     return err < 0 ? err : ret;
... ...
@@ -2307,6 +2319,16 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int eo
2307 2307
         ist->resample_height  = decoded_frame->height;
2308 2308
         ist->resample_pix_fmt = decoded_frame->format;
2309 2309
 
2310
+        for (i = 0; i < ist->nb_filters; i++) {
2311
+            err = ifilter_parameters_from_frame(ist->filters[i], decoded_frame);
2312
+            if (err < 0) {
2313
+                av_log(NULL, AV_LOG_ERROR,
2314
+                       "Error reconfiguring input stream %d:%d filter %d\n",
2315
+                       ist->file_index, ist->st->index, i);
2316
+                goto fail;
2317
+            }
2318
+        }
2319
+
2310 2320
         for (i = 0; i < nb_filtergraphs; i++) {
2311 2321
             if (ist_in_filtergraph(filtergraphs[i], ist) && ist->reinit_filters &&
2312 2322
                 configure_filtergraph(filtergraphs[i]) < 0) {
... ...
@@ -3305,6 +3327,16 @@ static int transcode_init(void)
3305 3305
                  enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
3306 3306
                  filtergraph_is_simple(ost->filter->graph)) {
3307 3307
                     FilterGraph *fg = ost->filter->graph;
3308
+
3309
+                    if (dec_ctx) {
3310
+                        ret = ifilter_parameters_from_decoder(fg->inputs[0],
3311
+                                                              dec_ctx);
3312
+                        if (ret < 0) {
3313
+                            av_log(NULL, AV_LOG_FATAL, "Error initializing filter input\n");
3314
+                            exit_program(1);
3315
+                        }
3316
+                    }
3317
+
3308 3318
                     if (configure_filtergraph(fg)) {
3309 3319
                         av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
3310 3320
                         exit_program(1);
... ...
@@ -231,6 +231,18 @@ typedef struct InputFilter {
231 231
     struct InputStream *ist;
232 232
     struct FilterGraph *graph;
233 233
     uint8_t            *name;
234
+
235
+    // parameters configured for this input
236
+    int format;
237
+
238
+    int width, height;
239
+    AVRational sample_aspect_ratio;
240
+
241
+    int sample_rate;
242
+    int channels;
243
+    uint64_t channel_layout;
244
+
245
+    AVBufferRef *hw_frames_ctx;
234 246
 } InputFilter;
235 247
 
236 248
 typedef struct OutputFilter {
... ...
@@ -600,6 +612,9 @@ int filtergraph_is_simple(FilterGraph *fg);
600 600
 int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
601 601
 int init_complex_filtergraph(FilterGraph *fg);
602 602
 
603
+int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
604
+int ifilter_parameters_from_decoder(InputFilter *ifilter, const AVCodecContext *avctx);
605
+
603 606
 int ffmpeg_parse_options(int argc, char **argv);
604 607
 
605 608
 int vdpau_init(AVCodecContext *s);
... ...
@@ -214,6 +214,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
214 214
         exit_program(1);
215 215
     fg->inputs[0]->ist   = ist;
216 216
     fg->inputs[0]->graph = fg;
217
+    fg->inputs[0]->format = -1;
217 218
 
218 219
     GROW_ARRAY(ist->filters, ist->nb_filters);
219 220
     ist->filters[ist->nb_filters - 1] = fg->inputs[0];
... ...
@@ -292,6 +293,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
292 292
         exit_program(1);
293 293
     fg->inputs[fg->nb_inputs - 1]->ist   = ist;
294 294
     fg->inputs[fg->nb_inputs - 1]->graph = fg;
295
+    fg->inputs[fg->nb_inputs - 1]->format = -1;
295 296
 
296 297
     GROW_ARRAY(ist->filters, ist->nb_filters);
297 298
     ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
... ...
@@ -667,7 +669,7 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
667 667
     }
668 668
 }
669 669
 
670
-static int sub2video_prepare(InputStream *ist)
670
+static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
671 671
 {
672 672
     AVFormatContext *avf = input_files[ist->file_index]->ctx;
673 673
     int i, w, h;
... ...
@@ -675,8 +677,8 @@ static int sub2video_prepare(InputStream *ist)
675 675
     /* Compute the size of the canvas for the subtitles stream.
676 676
        If the subtitles codecpar has set a size, use it. Otherwise use the
677 677
        maximum dimensions of the video streams in the same file. */
678
-    w = ist->dec_ctx->width;
679
-    h = ist->dec_ctx->height;
678
+    w = ifilter->width;
679
+    h = ifilter->height;
680 680
     if (!(w && h)) {
681 681
         for (i = 0; i < avf->nb_streams; i++) {
682 682
             if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
... ...
@@ -695,7 +697,7 @@ static int sub2video_prepare(InputStream *ist)
695 695
 
696 696
     /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
697 697
        palettes for all rectangles are identical or compatible */
698
-    ist->resample_pix_fmt = ist->dec_ctx->pix_fmt = AV_PIX_FMT_RGB32;
698
+    ist->resample_pix_fmt = ifilter->format = AV_PIX_FMT_RGB32;
699 699
 
700 700
     ist->sub2video.frame = av_frame_alloc();
701 701
     if (!ist->sub2video.frame)
... ...
@@ -736,22 +738,19 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
736 736
         fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
737 737
 
738 738
     if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
739
-        ret = sub2video_prepare(ist);
739
+        ret = sub2video_prepare(ist, ifilter);
740 740
         if (ret < 0)
741 741
             goto fail;
742 742
     }
743 743
 
744
-    sar = ist->st->sample_aspect_ratio.num ?
745
-          ist->st->sample_aspect_ratio :
746
-          ist->dec_ctx->sample_aspect_ratio;
744
+    sar = ifilter->sample_aspect_ratio;
747 745
     if(!sar.den)
748 746
         sar = (AVRational){0,1};
749 747
     av_bprint_init(&args, 0, 1);
750 748
     av_bprintf(&args,
751 749
              "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
752
-             "pixel_aspect=%d/%d:sws_param=flags=%d", ist->resample_width,
753
-             ist->resample_height,
754
-             ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->resample_pix_fmt,
750
+             "pixel_aspect=%d/%d:sws_param=flags=%d",
751
+             ifilter->width, ifilter->height, ifilter->format,
755 752
              tb.num, tb.den, sar.num, sar.den,
756 753
              SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
757 754
     if (fr.num && fr.den)
... ...
@@ -763,7 +762,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
763 763
     if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
764 764
                                             args.str, NULL, fg->graph)) < 0)
765 765
         goto fail;
766
-    par->hw_frames_ctx = ist->hw_frames_ctx;
766
+    par->hw_frames_ctx = ifilter->hw_frames_ctx;
767 767
     ret = av_buffersrc_parameters_set(ifilter->filter, par);
768 768
     if (ret < 0)
769 769
         goto fail;
... ...
@@ -866,14 +865,14 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
866 866
 
867 867
     av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
868 868
     av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
869
-             1, ist->dec_ctx->sample_rate,
870
-             ist->dec_ctx->sample_rate,
871
-             av_get_sample_fmt_name(ist->dec_ctx->sample_fmt));
872
-    if (ist->dec_ctx->channel_layout)
869
+             1, ifilter->sample_rate,
870
+             ifilter->sample_rate,
871
+             av_get_sample_fmt_name(ifilter->format));
872
+    if (ifilter->channel_layout)
873 873
         av_bprintf(&args, ":channel_layout=0x%"PRIx64,
874
-                   ist->dec_ctx->channel_layout);
874
+                   ifilter->channel_layout);
875 875
     else
876
-        av_bprintf(&args, ":channels=%d", ist->dec_ctx->channels);
876
+        av_bprintf(&args, ":channels=%d", ifilter->channels);
877 877
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
878 878
              ist->file_index, ist->st->index);
879 879
 
... ...
@@ -1093,6 +1092,58 @@ int configure_filtergraph(FilterGraph *fg)
1093 1093
     return 0;
1094 1094
 }
1095 1095
 
1096
+int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
1097
+{
1098
+    av_buffer_unref(&ifilter->hw_frames_ctx);
1099
+
1100
+    ifilter->format = frame->format;
1101
+
1102
+    ifilter->width               = frame->width;
1103
+    ifilter->height              = frame->height;
1104
+    ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
1105
+
1106
+    ifilter->sample_rate         = frame->sample_rate;
1107
+    ifilter->channels            = av_frame_get_channels(frame);
1108
+    ifilter->channel_layout      = frame->channel_layout;
1109
+
1110
+    if (frame->hw_frames_ctx) {
1111
+        ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
1112
+        if (!ifilter->hw_frames_ctx)
1113
+            return AVERROR(ENOMEM);
1114
+    }
1115
+
1116
+    return 0;
1117
+}
1118
+
1119
+int ifilter_parameters_from_decoder(InputFilter *ifilter, const AVCodecContext *avctx)
1120
+{
1121
+    av_buffer_unref(&ifilter->hw_frames_ctx);
1122
+
1123
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
1124
+        ifilter->format = avctx->pix_fmt;
1125
+    else
1126
+        ifilter->format = avctx->sample_fmt;
1127
+
1128
+    ifilter->width               = avctx->width;
1129
+    ifilter->height              = avctx->height;
1130
+    if (ifilter->ist && ifilter->ist->st && ifilter->ist->st->sample_aspect_ratio.num)
1131
+        ifilter->sample_aspect_ratio = ifilter->ist->st->sample_aspect_ratio;
1132
+    else
1133
+        ifilter->sample_aspect_ratio = avctx->sample_aspect_ratio;
1134
+
1135
+    ifilter->sample_rate         = avctx->sample_rate;
1136
+    ifilter->channels            = avctx->channels;
1137
+    ifilter->channel_layout      = avctx->channel_layout;
1138
+
1139
+    if (avctx->hw_frames_ctx) {
1140
+        ifilter->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
1141
+        if (!ifilter->hw_frames_ctx)
1142
+            return AVERROR(ENOMEM);
1143
+    }
1144
+
1145
+    return 0;
1146
+}
1147
+
1096 1148
 int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
1097 1149
 {
1098 1150
     int i;
... ...
@@ -2008,12 +2008,28 @@ static int init_complex_filters(void)
2008 2008
 
2009 2009
 static int configure_complex_filters(void)
2010 2010
 {
2011
-    int i, ret = 0;
2011
+    int i, j, ret = 0;
2012
+
2013
+    for (i = 0; i < nb_filtergraphs; i++) {
2014
+        FilterGraph *fg = filtergraphs[i];
2015
+
2016
+        if (filtergraph_is_simple(fg))
2017
+            continue;
2012 2018
 
2013
-    for (i = 0; i < nb_filtergraphs; i++)
2014
-        if (!filtergraph_is_simple(filtergraphs[i]) &&
2015
-            (ret = configure_filtergraph(filtergraphs[i])) < 0)
2019
+        for (j = 0; j < fg->nb_inputs; j++) {
2020
+            ret = ifilter_parameters_from_decoder(fg->inputs[j],
2021
+                                                  fg->inputs[j]->ist->dec_ctx);
2022
+            if (ret < 0) {
2023
+                av_log(NULL, AV_LOG_ERROR,
2024
+                       "Error initializing filtergraph %d input %d\n", i, j);
2025
+                return ret;
2026
+            }
2027
+        }
2028
+
2029
+        ret = configure_filtergraph(filtergraphs[i]);
2030
+        if (ret < 0)
2016 2031
             return ret;
2032
+    }
2017 2033
     return 0;
2018 2034
 }
2019 2035