Search code examples
cffmpegcodec

FFmpeg 5 C api codec: how many times will EOF be returned by the receiving end?


Edit: I may have written my questions unclearly at first, so I rewrote them. Sorry if you had found my questions confusing.

I'm new to FFmpeg api programming (I'm using version 5.1) and am learning from the documentation and official examples.

In the documentation page about send/receive encoding and decoding API overview, end of stream situation is discussed briefly:

End of stream situations. These require "flushing" (aka draining) the codec, as the codec might buffer multiple frames or packets internally for performance or out of necessity (consider B-frames). This is handled as follows:

Instead of valid input, send NULL to the avcodec_send_packet() (decoding) or avcodec_send_frame() (encoding) functions. This will enter draining mode. Call avcodec_receive_frame() (decoding) or avcodec_receive_packet() (encoding) in a loop until AVERROR_EOF is returned. The functions will not return AVERROR(EAGAIN), unless you forgot to enter draining mode. Before decoding can be resumed again, the codec has to be reset with avcodec_flush_buffers().

As I understand it, when I get AVERROR_EOF, I have reached a special point where I need to drain buffered data from the codec and finally reset the codec with avcodec_flush_buffers(). Without doing it, I cannot continue decoding/encoding.

Is my understanding correct?

If so, then I have some questions:

  1. How many times at most can EOF be returned by the receiving end during one complete process, for example, decoding?
  2. If the answer to the first question is infinity, then: If I received an EOF from the receiving end when I already finished sending data (e.g. when after EOF is returned by av_read_frame()), how should I tell if it's really finished? Here there is no return code only for indicating if the receiving is finished.
  3. The data returned from the receive_... functions during draining, should I take them as valid?

I might have found answers to those in the official examples, but I'm not sure if the answer is universally true. I noticed that in some official examples, like in transcode_aac.c, draining is only done for the first EOF reached, and then after the second one is received, it is regarded that there are really nothing left. Any data received during draining is also written to the final output.

Am I correct on interpreting the example? If so, can I say that the answer to question 1 is once, and the answer to question 3 is yes?

I appreciate your response and time in advance. :)


Solution

  • I now find out my confusion is a consequence of my own misunderstanding of the documentation.

    I mistook "End of stream situations" for the receiving end's returning EOF, which gave me endless wonders. It should be the EOF returned by av_read_frame in demuxing.

    I apologize for your attention and time used on my own mistake.