[FFmpeg-devel] [PATCH] avfilter/setparams: add FF_FILTER_FLAG_HWFRAME_AWARE

Pavel Koshevoy pkoshevoy at gmail.com
Sun Mar 14 21:59:40 EET 2021


On Thu, Oct 1, 2020 at 4:24 PM Mark Thompson <sw at jkqxz.net> wrote:

> On 29/09/2020 19:49, Pavel Koshevoy wrote:
> > On Tue, Sep 29, 2020 at 12:14 PM Mark Thompson <sw at jkqxz.net> wrote:
> >
> >> On 29/09/2020 18:14, Pavel Koshevoy wrote:
> >>> On Tue, Sep 29, 2020 at 10:09 AM Mark Thompson <sw at jkqxz.net> wrote:
> >>>
> >>
> >> <snip>
> >>
> >>>> - Mark
> >>>>
> >>>>
> >>> It's pretty much this use case, except I'm not using ffmpeg cli but the
> >>> avfilter api to configure the filter chain, and I'm working with
> >>> AV_PIX_FMT_CUDA frames.
> >>> Perhaps I am mis-using the api, but my patch was sufficient for my
> needs:
> >>>
> >>> ```
> >>>       bool
> >>>       VideoFilterChain::setup_filter_links(int num_threads)
> >>>       {
> >>>           graph_ = avfilter_graph_alloc();
> >>>           graph_->nb_threads = num_threads;
> >>>           int err = avfilter_graph_parse2(graph_, filters_.c_str(),
> &in_,
> >>> &out_);
> >>>           UL_FAIL_IF_AVERROR(err);
> >>>
> >>>           if (hw_frames_.ref_)
> >>>           {
> >>>               AVHWFramesContext * hw_frames_ctx =
> >>> hw_frames_.get<AVHWFramesContext>();
> >>>               AVBufferRef * device_ref = hw_frames_ctx->device_ref;
> >>>
> >>>               for (int i = 0; i < graph_->nb_filters; i++)
> >>>               {
> >>>                   AVFilterContext * filter_ctx = graph_->filters[i];
> >>>                   UL_ASSERT(!filter_ctx->hw_device_ctx);
> >>>                   filter_ctx->hw_device_ctx =
> av_buffer_ref(device_ref);
> >>>
> >>>                   bool found_hwdownload =
> strcmp(filter_ctx->filter->name,
> >>> "hwdownload") == 0;
> >>>                   if (found_hwdownload)
> >>>                   {
> >>>                       break;
> >>>                   }
> >>>
> >>>                   for (int j = 0; j < filter_ctx->nb_outputs; j++)
> >>>                   {
> >>>                       AVFilterLink * link = filter_ctx->outputs[j];
> >>>                       UL_ASSERT(!link->hw_frames_ctx);
> >>>                       link->hw_frames_ctx =
> >> av_buffer_ref(hw_frames_.ref_);
> >>
> >>
> >> <
> >>
> http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavfilter/avfilter.h;h=99297ae798aa325ac37836a3a90d9a3f8e1e7a95;hb=HEAD#l497
> >>>
> >>
> >> Don't write to internal fields.
> >>
> >> I'm not sure exactly what you're trying to do by writing the internal
> >> context fields in this section, but I suspect that if you just remove it
> >> entirely then the expected context propagation will happen and it will
> work.
> >>
> >>
> > Okay, if I fix my API mis-use and context propagation happens
> > automagically  (idk where it would get the context in the 1st place,
> > yet)...
>
> If you are putting hardware frames into a filter graph then it comes from
> buffersrc.  If you are using hwupload inside the filter graph then it gets
> made there from the device you provide as AVFilterContext.hw_device_ctx.
>
> >         won't that still leave me with setparams that is not
> > FF_FILTER_FLAG_HWFRAME_AWARE and avfilter_config_links would still fail?
>
> Why would it fail?
>
>

I guess I no longer know how to use avfilter api:

I've been doing this:
```
    graph_ = avfilter_graph_alloc();

    if (nb_threads_ > 0)
    {
      graph_->nb_threads = nb_threads_;
    }

    int err = avfilter_graph_parse2(graph_, filters_.c_str(), &in_, &out_);
```

where filters_ is something like this:
"buffer=width=1920:height=800:pix_fmt=cuda:frame_rate=60/1:time_base=1/90000:sar=1/1,hwdownload,format=pix_fmts=yuv420p,scale=w=128:h=47,setsar=sar=0.888889,buffersink"
I don't see where to pass in the hwframes context. AVFilterGraph makes no
mention of it, and avfilter_graph_parse2 has no parameter for it.


More information about the ffmpeg-devel mailing list