编辑:我一开始可能写得不清楚,所以我重写了它们。抱歉,如果您发现我的问题令人困惑。
我是 FFmpeg api 编程的新手(我使用的是 5.1 版本),正在从文档和官方示例中学习。
在有关发送/接收编码和解码 API 概述的文档页面中,简要讨论了流结束情况:
流结束的情况。这些需要“刷新”(也称为排空)编解码器,因为编解码器可能为了性能或出于必要而在内部缓冲多个帧或数据包(考虑 B 帧)。处理如下:
将
发送到NULL
(解码)或avcodec_send_packet()
(编码)功能,而不是有效输入。这将进入排水模式。 拨打avcodec_send_frame()
(解码) 或avcodec_receive_frame()
(编码)循环,直到返回avcodec_receive_packet()
。这些函数不会返回AVERROR_EOF
,除非您忘记进入排水模式。 在再次恢复解码之前,必须使用AVERROR(EAGAIN)
重置编解码器。avcodec_flush_buffers()
据我了解,当我得到
AVERROR_EOF
时,我已经达到了一个特殊的点,我需要从编解码器中排出缓冲数据,最后用avcodec_flush_buffers()
重置编解码器。如果不这样做,我就无法继续解码/编码。
我的理解正确吗?
如果是这样,那么我有一些问题:
av_read_frame()
返回EOF之后),我应该如何判断它是否真的完成了?这里没有返回码,只是为了表示接收是否完成。receive_...
函数返回的数据,我应该将它们视为有效吗?我可能已经在官方示例中找到了答案,但我不确定答案是否普遍正确。我注意到在一些官方示例中,例如transcode_aac.c中,仅在到达第一个EOF时才进行排水,然后在收到第二个EOF后,就认为真的没有剩下了。排空期间接收到的任何数据也会写入最终输出。
我对这个例子的解释正确吗?如果是的话,我是否可以说问题1的答案是一次,问题3的答案是是?
感谢您的回复和提前的时间。 :)
我现在发现我的困惑是我自己对文档的误解造成的。
我误将“End of Stream issues”当成接收端返回的EOF,这给了我无尽的惊奇。应该是解复用中
av_read_frame
返回的EOF。
对于您在我自己的错误上花费的注意力和时间,我深表歉意。