[FFmpeg-devel] [PATCH v2] avcodec/av1_vaapi: add direct film grain mode

Mark Thompson sw at jkqxz.net
Wed Nov 23 01:34:21 EET 2022


On 22/11/2022 20:59, Mark Thompson wrote:
> On 22/11/2022 20:26, Mark Thompson wrote:
>> On 22/11/2022 19:18, Dong, Ruijing wrote:
>>> [AMD Official Use Only - General]
>>>
>>> Hi Mark,
>>>
>>> Sorry for being late to reply to you.
>>>
>>> Your understanding is correct, and I have sent a new patch [v4] for addressing the current issue and to use
>>> driver quirk mechanism to specify only AMD VAAPI driver has this behavior, then this could be more specific.
>>>
>>> For AMD hardware, it allocates GPU memory internally for the DPB management, the output is always the final one with or without applied film-grain.
>>
>> I don't see why this requires you to write the output to the wrong surface.  Why not write it to the correct one instead?
> 
> Indeed, this seems to be a trivial fix in Mesa: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19938>.
> 
> It would be helpful if someone with suitable hardware could test that.

This was too naive, the Mesa driver doesn't make this easy.

It is only set up to write to a single surface, which is the one provided to vaBeginPicture().  However, VAAPI does not work that way - it wants you to write to both the pre-grain and the post-grain surfaces, where the pre-grain surface is the primary target and gets passed the vaBeginPicture() and the post-grain surface is supplied in the parameters.

So that's the first problem: the render target which is given as the pre-grain surface needs to be replaced by post-grain surface if we want to only write a single surface.

Is that enough?  Well, no.  The Mesa driver is also messing with the reference frames.

The VAAPI model is that the pre-grain surfaces are passed back into the driver on subsequent frames when they are used as reference frames.  However, the Mesa driver has hidden the pre-grain surface internally and only written the post-grain surface.

Therefore, when writing a post-grain output, it magically associates with the target surface information about the pre-grain surface which was written internally at the same time.  Then, when you later give it that surface as a reference frame it ignores the actual content of the frame and looks at the associated data to find what to use internally as the reference.

That's the second problem: if the post-grain surface were actually the render target then the magic internal reference gets associated with that, and when we pass the real reference frame (the pre-grain surface) in later then it won't recognise it because it never wrote to that surface.

How should it be fixed, then?

The best way would be to stop hiding the internal information about reference frames: if the real reference frames were visible in VAAPI then everything would just work and none of the magic internal references would be needed.

If we suppose that this can't be done (maybe it is hidden behind opaque firmware which the naughty users buying the products are not allowed to see), then Mesa needs two changes:

1.  Write the output to the post-grain surface rather than the pre-grain surface.  This is nontrivial because it isn't the surface passed to vaBeginPicture(), but given the API there isn't really any way around it.

2.  Attach the magic internal reference to the pre-grain surface, /even though it wasn't the one written to/.  This makes the reference frames work, since the pre-grain surfaces will be the ones passed back in later frames.

Alternatively: make new API in libva somehow.  Probably wants an attribute which indicates that vaBeginPicture() would want the post-grain surface and then ignore the surfaces in the picture parameters?  Unclear exactly how this should be specified, but whatever it is it needs to be very clear about how the references would work.

Hacking FFmpeg to use the API differently based on matching substrings in the vendor name does not seem like a good approach here, given that future Mesa decode implementations (which could be AMD or could be other hardware) may well be more sensible.  It would also doom other VAAPI users, since you can only really send this sort of hack to a few big projects like FFmpeg.

Thanks,

- Mark


More information about the ffmpeg-devel mailing list