[FFmpeg-devel] Added HW H.264 and HEVC encoding for AMD GPUs based on AMF SDK

Marton Balint cus at passwd.hu
Tue Oct 31 03:26:24 EET 2017

On Mon, 30 Oct 2017, Mironov, Mikhail wrote:


>>>> I still think this would be much better off using the
>>>> send_frame()/receive_packet() API.  Even if your API doesn't expose
>>>> any information about the queue length, you only need to hold a
>>>> single input frame transiently to get around that (the user is not
>>>> allowed to call
>>>> send_frame() twice in a row without calling receive_packet()).
>>> So to implement this I would have to:
>>> - in the send_frame() if AMF_INPUT_FULL is returned - store input
>>> frame (or copy?)
>>> - In the next receive_frame() check if frame is stored
>>> - Wait till some output is produced
>>> - resubmit stored frame
>> Sounds about right.
>>> Issues I see:
>>> - Isn't this logic defeat the purpose of independent send()/receive()?
>>> - How can I report a error if receive() produced a compressed frame but
>> the delayed submission failed?
>> Since this is asynchronous anyway, just report it at the next available
>> opportunity.
>>> - This logic depends on the particular logic in the calling code.
>> The API requires this behaviour of the caller.  See the documentation in
>> avcodec.h.
>>> - This logic depends on the particular HW behaviour.
>> How so?
>>> - In the future, we would like to output individual slices of a compressed
>> frame.
>>> When this added receive_frame() must be called several times to clear
>> space in the HW queue.
>>> Granted, current implementation also does not cover this case but
>>> truly independent send/receive implementation would.
>> Note that the user is required to call receive_packet() repeatedly until it
>> returns EAGAIN, and only then are they allowed to call send_frame() again.
> The implementation will be cumbersome at least. Note that calling Drain()
> may also return AMF_INPUT_FULL and therefore will have to be remembered and
> called again in receive(). But I will implement as you suggests. It is not a huge change.

I see some confusion. The user can call send_frame/receive_packet in 
any order, and you can implement send_frame and receive_packet any way you 
want, the only thing you have to guarantee is that you cannot return 
EAGAIN for both send_frame and receive_packet. Not even temporarily.

If you returned EAGAIN in send_frame, you must return success or a 
normal error in receive_packet. If you returned EAGAIN in 
receive_packet, you must return success or a normal error in 

By returning EAGAIN in receive_packet you make sure that the API user 
submits as many frames as needed to fill your pipeline.

The simplest solution really seems to me what Mark proposed:


if (have_stored_frame)
   return EAGAIN;
if (amd_send_frame() == INPUT_FULL)
return 0;


if (have_stored_frame) {
   if (amd_send_frame() == OK)
   return packet
} else {
   return EAGAIN

I hope I did not mess it up, proper draining and error handling obviously 
needs some minor changes.


More information about the ffmpeg-devel mailing list