使用FFmpeg afir滤镜时av_buffersink_get_frame()持续返回AVERROR(EAGAIN)求助
av_buffersink_get_frame()始终返回AVERROR(EAGAIN)的排查与解决 问题背景
使用FFmpeg的afir滤镜处理两个音频输入(input.mp3和signal.wav),解码后将帧推入abuffersrc,但调用av_buffersink_get_frame()始终返回AVERROR(EAGAIN),即使推完所有输入帧也无法获取输出。
核心原因与解决步骤
1. afir滤镜需要明确的EOF标记(关键)
afir滤镜的第二个输入(in1)是脉冲响应(IR),它需要先完整接收IR的所有数据,才能开始处理第一个输入(in0)的音频流。如果未给in1发送结束信号,滤镜会一直等待更多IR数据,导致无法输出,返回EAGAIN。
解决方法:
推送完in1的所有帧后,必须调用av_buffersrc_add_frame_flags标记输入结束:
// 推送完in1的所有帧后执行 av_buffersrc_add_frame_flags(ctx->input_files[1]->buffersrc, NULL, AV_BUFFERSRC_FLAG_END_OF_STREAM);
同样,推送完in0的所有帧后也需要发送EOF:
av_buffersrc_add_frame_flags(ctx->input_files[0]->buffersrc, NULL, AV_BUFFERSRC_FLAG_END_OF_STREAM);
发送EOF后,循环调用av_buffersink_get_frame()直到返回AVERROR_EOF,中间的EAGAIN属于正常情况,只需继续调用即可。
2. 检查两个输入的音频参数一致性
afir滤镜要求两个输入的采样率、采样格式、通道布局完全一致。如果输入参数不匹配,滤镜内部无法处理数据,导致无输出。
检查方法:
在解码后打印两个输入帧的参数:
AVFrame *frame = ...; // 解码后的帧 printf("Sample rate: %d, Format: %s, Channel layout: 0x%"PRIx64"\n", frame->sample_rate, av_get_sample_fmt_name(frame->format), frame->channel_layout);
如果参数不一致,需要在滤镜链中加入aresample滤镜统一参数,修改滤镜描述为:
[in0]aresample=sample_rate=44100:sample_fmt=fltp:channel_layout=stereo[in0_resampled]; [in1]aresample=sample_rate=44100:sample_fmt=fltp:channel_layout=stereo[in1_resampled]; [in0_resampled][in1_resampled]afir[out]
(替换为实际需要统一的参数)
3. 确保滤镜图配置成功
检查avfilter_graph_config(filter_graph, NULL)的返回值,确认没有错误。如果配置失败,滤镜链可能未正确建立,导致无法处理输入。
4. 帧时间戳有效性
确保解码后的AVFrame的pts字段正确设置(使用解码器的time_base转换)。无效的时间戳可能导致滤镜无法正确调度处理,进而无输出。
验证流程
- 推送in1的所有帧 → 发送in1的EOF
- 推送in0的所有帧 → 发送in0的EOF
- 循环调用
av_buffersink_get_frame(),直到返回AVERROR_EOF
内容的提问来源于stack exchange,提问作者Evgenii

