* commit '722ec3eb35bc152ce91d0a4502eca0df1c0086d0':
avconv: decouple configuring filtergraphs and setting input parameters
Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
... | ... |
@@ -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 |
|