AVERROR(EAGAIN)表示解码器输入缓冲区满、需先消费输出帧再重试发送;非错误而是流控信号,常见于硬件解码或多线程软解,须严格按send→receive→send节奏处理,避免卡死或丢帧。

FFmpeg解码器返回AVERROR(EAGAIN)意味着什么
这表示解码器内部输入缓冲区已满,暂时无法接受新数据包(AVPacket),但输出缓冲区可能仍有待取的帧(AVFrame)。它不是错误,而是流控信号——常见于硬件解码器(如h264_qsv、h264_cuvid)或启用了多线程软解(thread_count > 1)时。
遇到avcodec_send_packet()返回AVERROR(EAGAIN)怎么办
不能直接重试或丢弃包,必须先消费输出帧,腾出解码器内部空间:
- 立即调用
avcodec_receive_frame()循环读取可用帧,直到返回AVERROR(EAGAIN)(表示输出暂空)或AVERROR_EOF - 确认收到所有可得帧后,再重试
avcodec_send_packet() - 若
avcodec_receive_frame()返回0,记得调用av_frame_unref()释放引用,避免内存泄漏 - 不要在
send失败后跳过该AVPacket——它仍需被送入解码器,只是时机未到
avcodec_receive_frame()也返回EAGAIN时的典型误操作
此时说明解码器输入不足(比如刚初始化、或上一个AVPacket还没送进去),而非输出已空。常见错误包括:
- 在未成功
send任何包前就反复receive——结果必是EAGAIN,应先确保至少一个包已成功送入 - 忽略
avcodec_send_packet()返回负值(除EAGAIN外还有AVERROR_INVALIDDATA等真错误),一律当流控处理 - 使用
AV_CODEC_CAP_DELAY解码器(如H.264)时,flush阶段需发送nullptr包,否则receive会持续EAGAIN而收不到尾帧
硬件解码器下EAGAIN更频繁,需特别注意资源同步
例如h264_qsv在Intel Quick Sync下,EAGAIN常伴随显存队列满。这时仅靠轮询receive不够:
立即学习“C++免费学习笔记(深入)”;
- 确保
AVCodecContext的hw_frames_ctx已正确初始化并绑定到解码器 - 调用
avcodec_receive_frame()后,若帧为硬件格式(frame->format == AV_PIX_FMT_QSV等),必须用对应硬件API(如MFXVideoCORE_SyncOperation)同步帧数据,否则后续send可能因GPU未就绪而持续EAGAIN - 避免在单线程中密集
send→receive→send,建议用双缓冲队列解耦输入/输出节奏
EAGAIN当成可忽略的“小问题”,而没意识到它背后是解码器状态机与外部调度节奏的耦合——一旦输入/输出节奏失配,就会卡死或丢帧。


















