From e2542124059f5960ac2bbd94183012814263f20d Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 13 Apr 2020 16:33:19 +0100 Subject: [PATCH] ffmpeg: Make filter hardware device selection clearer Also move it into a dedicated function in the hardware file. --- fftools/ffmpeg.h | 1 + fftools/ffmpeg_filter.c | 14 +++----------- fftools/ffmpeg_hw.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index fbaae15377..43b5040f73 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -661,6 +661,7 @@ void hw_device_free_all(void); int hw_device_setup_for_decode(InputStream *ist); int hw_device_setup_for_encode(OutputStream *ost); +int hw_device_setup_for_filter(FilterGraph *fg); int hwaccel_decode_init(AVCodecContext *avctx); diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index b66faa50b5..8b5b157be7 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1061,17 +1061,9 @@ int configure_filtergraph(FilterGraph *fg) if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0) goto fail; - if (filter_hw_device || hw_device_ctx) { - AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref - : hw_device_ctx; - for (i = 0; i < fg->graph->nb_filters; i++) { - fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device); - if (!fg->graph->filters[i]->hw_device_ctx) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - } + ret = hw_device_setup_for_filter(fg); + if (ret < 0) + goto fail; if (simple && (!inputs || inputs->next || !outputs || outputs->next)) { const char *num_inputs; diff --git a/fftools/ffmpeg_hw.c b/fftools/ffmpeg_hw.c index 962d8f7d5a..40739fc320 100644 --- a/fftools/ffmpeg_hw.c +++ b/fftools/ffmpeg_hw.c @@ -480,3 +480,31 @@ int hwaccel_decode_init(AVCodecContext *avctx) return 0; } + +int hw_device_setup_for_filter(FilterGraph *fg) +{ + HWDevice *dev; + int i; + + // If the user has supplied exactly one hardware device then just + // give it straight to every filter for convenience. If more than + // one device is available then the user needs to pick one explcitly + // with the filter_hw_device option. + if (filter_hw_device) + dev = filter_hw_device; + else if (nb_hw_devices == 1) + dev = hw_devices[0]; + else + dev = NULL; + + if (dev) { + for (i = 0; i < fg->graph->nb_filters; i++) { + fg->graph->filters[i]->hw_device_ctx = + av_buffer_ref(dev->device_ref); + if (!fg->graph->filters[i]->hw_device_ctx) + return AVERROR(ENOMEM); + } + } + + return 0; +}