mirror of
https://github.com/librempeg/librempeg
synced 2024-11-22 18:49:58 +00:00
fftools/ffmpeg: supply hw_device_ctx to filters before initializing them
This is more correct, but was not possible before the recently-added filtergraph parsing API. Also, only pass hw devices to filters that are flagged as capable of using them. Tested-by: Niklas Haas
This commit is contained in:
parent
632c349931
commit
3f63685c35
@ -802,7 +802,12 @@ void hw_device_free_all(void);
|
|||||||
|
|
||||||
int hw_device_setup_for_decode(InputStream *ist);
|
int hw_device_setup_for_decode(InputStream *ist);
|
||||||
int hw_device_setup_for_encode(OutputStream *ost);
|
int hw_device_setup_for_encode(OutputStream *ost);
|
||||||
int hw_device_setup_for_filter(FilterGraph *fg);
|
/**
|
||||||
|
* Get a hardware device to be used with this filtergraph.
|
||||||
|
* The returned reference is owned by the callee, the caller
|
||||||
|
* must ref it explicitly for long-term use.
|
||||||
|
*/
|
||||||
|
AVBufferRef *hw_device_for_filter(void);
|
||||||
|
|
||||||
int hwaccel_decode_init(AVCodecContext *avctx);
|
int hwaccel_decode_init(AVCodecContext *avctx);
|
||||||
|
|
||||||
|
@ -440,7 +440,8 @@ static int graph_opts_apply(AVFilterGraphSegment *seg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int graph_parse(AVFilterGraph *graph, const char *desc,
|
static int graph_parse(AVFilterGraph *graph, const char *desc,
|
||||||
AVFilterInOut **inputs, AVFilterInOut **outputs)
|
AVFilterInOut **inputs, AVFilterInOut **outputs,
|
||||||
|
AVBufferRef *hw_device)
|
||||||
{
|
{
|
||||||
AVFilterGraphSegment *seg;
|
AVFilterGraphSegment *seg;
|
||||||
int ret;
|
int ret;
|
||||||
@ -456,6 +457,20 @@ static int graph_parse(AVFilterGraph *graph, const char *desc,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (hw_device) {
|
||||||
|
for (int i = 0; i < graph->nb_filters; i++) {
|
||||||
|
AVFilterContext *f = graph->filters[i];
|
||||||
|
|
||||||
|
if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE))
|
||||||
|
continue;
|
||||||
|
f->hw_device_ctx = av_buffer_ref(hw_device);
|
||||||
|
if (!f->hw_device_ctx) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = graph_opts_apply(seg);
|
ret = graph_opts_apply(seg);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -480,7 +495,7 @@ int init_complex_filtergraph(FilterGraph *fg)
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
graph->nb_threads = 1;
|
graph->nb_threads = 1;
|
||||||
|
|
||||||
ret = graph_parse(graph, fg->graph_desc, &inputs, &outputs);
|
ret = graph_parse(graph, fg->graph_desc, &inputs, &outputs, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -1114,6 +1129,7 @@ static int graph_is_meta(AVFilterGraph *graph)
|
|||||||
|
|
||||||
int configure_filtergraph(FilterGraph *fg)
|
int configure_filtergraph(FilterGraph *fg)
|
||||||
{
|
{
|
||||||
|
AVBufferRef *hw_device;
|
||||||
AVFilterInOut *inputs, *outputs, *cur;
|
AVFilterInOut *inputs, *outputs, *cur;
|
||||||
int ret, i, simple = filtergraph_is_simple(fg);
|
int ret, i, simple = filtergraph_is_simple(fg);
|
||||||
const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
|
const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
|
||||||
@ -1157,11 +1173,9 @@ int configure_filtergraph(FilterGraph *fg)
|
|||||||
fg->graph->nb_threads = filter_complex_nbthreads;
|
fg->graph->nb_threads = filter_complex_nbthreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = graph_parse(fg->graph, graph_desc, &inputs, &outputs)) < 0)
|
hw_device = hw_device_for_filter();
|
||||||
goto fail;
|
|
||||||
|
|
||||||
ret = hw_device_setup_for_filter(fg);
|
if ((ret = graph_parse(fg->graph, graph_desc, &inputs, &outputs, hw_device)) < 0)
|
||||||
if (ret < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
|
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
|
||||||
|
@ -548,17 +548,14 @@ int hwaccel_decode_init(AVCodecContext *avctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hw_device_setup_for_filter(FilterGraph *fg)
|
AVBufferRef *hw_device_for_filter(void)
|
||||||
{
|
{
|
||||||
HWDevice *dev;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Pick the last hardware device if the user doesn't pick the device for
|
// Pick the last hardware device if the user doesn't pick the device for
|
||||||
// filters explicitly with the filter_hw_device option.
|
// filters explicitly with the filter_hw_device option.
|
||||||
if (filter_hw_device)
|
if (filter_hw_device)
|
||||||
dev = filter_hw_device;
|
return filter_hw_device->device_ref;
|
||||||
else if (nb_hw_devices > 0) {
|
else if (nb_hw_devices > 0) {
|
||||||
dev = hw_devices[nb_hw_devices - 1];
|
HWDevice *dev = hw_devices[nb_hw_devices - 1];
|
||||||
|
|
||||||
if (nb_hw_devices > 1)
|
if (nb_hw_devices > 1)
|
||||||
av_log(NULL, AV_LOG_WARNING, "There are %d hardware devices. device "
|
av_log(NULL, AV_LOG_WARNING, "There are %d hardware devices. device "
|
||||||
@ -567,17 +564,9 @@ int hw_device_setup_for_filter(FilterGraph *fg)
|
|||||||
"%s is not usable for filters.\n",
|
"%s is not usable for filters.\n",
|
||||||
nb_hw_devices, dev->name,
|
nb_hw_devices, dev->name,
|
||||||
av_hwdevice_get_type_name(dev->type), dev->name);
|
av_hwdevice_get_type_name(dev->type), dev->name);
|
||||||
} else
|
|
||||||
dev = NULL;
|
|
||||||
|
|
||||||
if (dev) {
|
return dev->device_ref;
|
||||||
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user