diff options
Diffstat (limited to 'video/filter/vf_lavfi.c')
-rw-r--r-- | video/filter/vf_lavfi.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c index 291ddd315b..2f4bc92ecc 100644 --- a/video/filter/vf_lavfi.c +++ b/video/filter/vf_lavfi.c @@ -26,6 +26,7 @@ #include <assert.h> #include <libavutil/avstring.h> +#include <libavutil/hwcontext.h> #include <libavutil/mem.h> #include <libavutil/mathematics.h> #include <libavutil/rational.h> @@ -44,6 +45,7 @@ #include "options/m_option.h" #include "common/tags.h" +#include "video/hwdec.h" #include "video/img_format.h" #include "video/mp_image.h" #include "video/sws_utils.h" @@ -148,6 +150,8 @@ static bool recreate_graph(struct vf_instance *vf, struct mp_image_params *fmt) in_params->height = fmt->h; in_params->sample_aspect_ratio.num = fmt->p_w; in_params->sample_aspect_ratio.den = fmt->p_h; + // Assume it's ignored for non-hwaccel formats. + in_params->hw_frames_ctx = vf->in_hwframes_ref; ret = av_buffersrc_parameters_set(in, in_params); av_free(in_params); @@ -170,6 +174,13 @@ static bool recreate_graph(struct vf_instance *vf, struct mp_image_params *fmt) if (graph_parse(graph, p->cfg_graph, inputs, outputs, NULL) < 0) goto error; + struct mp_hwdec_ctx *hwdec = hwdec_devices_get_first(vf->hwdec_devs); + for (int n = 0; n < graph->nb_filters; n++) { + AVFilterContext *filter = graph->filters[n]; + if (hwdec && hwdec->av_device_ref) + filter->hw_device_ctx = av_buffer_ref(hwdec->av_device_ref); + } + if (avfilter_graph_config(graph, NULL) < 0) goto error; @@ -226,17 +237,25 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in, out->p_w = l_out->sample_aspect_ratio.num; out->p_h = l_out->sample_aspect_ratio.den; out->imgfmt = pixfmt2imgfmt(l_out->format); + av_buffer_unref(&vf->out_hwframes_ref); +#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(6, 69, 100) && \ + LIBAVFILTER_VERSION_MICRO >= 100 + AVBufferRef *hw_frames_ctx = av_buffersink_get_hw_frames_ctx(p->out); +#else + AVBufferRef *hw_frames_ctx = l_out->hw_frames_ctx; +#endif + if (hw_frames_ctx) { + AVHWFramesContext *fctx = (void *)hw_frames_ctx->data; + out->hw_subfmt = pixfmt2imgfmt(fctx->sw_format); + vf->out_hwframes_ref = av_buffer_ref(hw_frames_ctx); + } return 0; } static int query_format(struct vf_instance *vf, unsigned int fmt) { - // We accept all sws-convertable formats as inputs. Output formats are - // handled in config(). The current public libavfilter API doesn't really - // allow us to do anything more sophisticated. - // This breaks with filters which accept input pixel formats not - // supported by libswscale. - return !!mp_sws_supported_format(fmt); + // Format negotiation is not possible with libavfilter. + return 1; } static AVFrame *mp_to_av(struct vf_instance *vf, struct mp_image *img) |