关于ffmpeg的error返回值

本文介绍了FFmpeg中av_read_frame函数的作用及返回值的意义。av_read_frame用于从码流中读取音视频帧数据,通过解析其返回值可以判断文件或流是否结束。文章还详细列举了error.h文件中定义的各种错误状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在我的实际项目中, av_read_frame获取音视频帧数据。
现在有个功能需要我根据 av_read_frame的返回值判断文件或者流是否结束。

之前对av_read_frame的返回值只做了简单的判断。
今天查看源码,发现其返回的状态信息还是比较有用的
,写此文记录一下吧。

av_read_frame简介:ffmpeg中的av_read_frame()的作用是读取码流中的音频若干帧或者视频一帧。例如,解码视频的时候,每解码一个视频帧,需要先调用 av_read_frame()获得一帧视频的压缩数据,然后才能对该数据进行解码(例如H.264中一帧压缩数据通常对应一个NAL)。


在error.h文件中有error的定义:
/* error handling */
#if EDOM > 0
#define AVERROR(e) (-(e))   ///< Returns a negative error code from a POSIX error code, to return from library functions.
#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value.
#else
/* Some platforms have E* and errno already negated. */
#define AVERROR(e) (e)
#define AVUNERROR(e) (e)
#endif


#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d))


#define AVERROR_BSF_NOT_FOUND      FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found
#define AVERROR_BUG                FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2
#define AVERROR_BUFFER_TOO_SMALL   FFERRTAG( 'B','U','F','S') ///< Buffer too small
#define AVERROR_DECODER_NOT_FOUND  FFERRTAG(0xF8,'D','E','C') ///< Decoder not found
#define AVERROR_DEMUXER_NOT_FOUND  FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found
#define AVERROR_ENCODER_NOT_FOUND  FFERRTAG(0xF8,'E','N','C') ///< Encoder not found
#define  AVERROR_EOF                 FFERRTAG( 'E','O','F',' ') ///< End of file
#define AVERROR_EXIT               FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted
#define AVERROR_EXTERNAL           FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library
#define AVERROR_FILTER_NOT_FOUND   FFERRTAG(0xF8,'F','I','L') ///< Filter not found
#define AVERROR_INVALIDDATA        FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input
#define AVERROR_MUXER_NOT_FOUND    FFERRTAG(0xF8,'M','U','X') ///< Muxer not found
#define AVERROR_OPTION_NOT_FOUND   FFERRTAG(0xF8,'O','P','T') ///< Option not found
#define AVERROR_PATCHWELCOME       FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome
#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found


#define AVERROR_STREAM_NOT_FOUND   FFERRTAG(0xF8,'S','T','R') ///< Stream not found



AVERROR_EOF  就是我要找的。

转载于:https://my.oschina.net/zhangxu0512/blog/175207

<think>我们正在处理FFmpeg中`avcodec_receive_frame`返回负值(错误码)的情况。根据引用[3],我们知道`avcodec_send_packet`和`avcodec_receive_frame`是成对使用的解码接口。当`avcodec_receive_frame`返回负数时,通常表示出现了某种错误或者需要特殊处理的情况。 常见的错误码(负数)包括: - `AVERROR(EAGAIN)`:当前没有可用的帧,需要先发送更多的packet(数据包)才能获取帧。 - `AVERROR_EOF`:解码器已经被刷新,没有更多的帧可以输出。 - 其他错误:如解码错误等。 根据引用[3]的示例,当`avcodec_send_packet`返回`AVERROR(EAGAIN)`时,表示当前解码器无法接受新的packet,因为还有帧没有取出。类似地,`avcodec_receive_frame`返回负数时,我们也需要根据具体的错误码进行处理。 处理步骤: 1. 检查返回的错误码。 2. 如果是`AVERROR(EAGAIN)`,表示需要继续发送packet(即再次调用`avcodec_send_packet`)然后再次尝试接收帧。 3. 如果是`AVERROR_EOF`,表示解码器已经刷新,没有更多帧了,可以结束解码。 4. 如果是其他错误,可能需要记录错误并停止解码。 另外,在引用[1]中提到,有时候即使发送了一个packet,也不能立刻得到一帧,因为解码器内部有缓存。因此,在追求低延时的场景下,需要尽量减少缓存。但这里我们关注的是错误处理。 下面是一个处理`avcodec_receive_frame`返回错误的示例代码片段: ```c AVPacket *pkt; // 假设已经分配并初始化的packet AVFrame *frame = av_frame_alloc(); // 分配帧 int ret; // 发送packet到解码器 ret = avcodec_send_packet(avctx, pkt); if (ret < 0) { // 处理发送packet的错误 // 可能是AVERROR(EAGAIN)或AVERROR(ENOMEM)等 // 如果是EAGAIN,需要先接收帧 } // 接收帧 while (1) { ret = avcodec_receive_frame(avctx, frame); if (ret == 0) { // 成功接收到一帧,进行后续处理 // ... av_frame_unref(frame); // 处理完后取消引用 } else if (ret == AVERROR(EAGAIN)) { // 需要发送新的packet才能继续解码 break; // 退出循环,继续发送下一个packet } else if (ret == AVERROR_EOF) { // 解码器已经刷新,没有更多帧了 break; } else { // 其他错误 fprintf(stderr, "Error during decoding: %s\n", av_err2str(ret)); break; } } ``` 注意:在实际使用中,我们通常在一个循环中不断发送packet并接收帧,直到没有packet可发送,然后发送一个NULL packet来刷新解码器(表示结束)。 关于刷新解码器:在发送完所有packet后,需要发送一个NULL packet来告诉解码器刷新内部缓存(即刷新帧)。此时,即使返回`AVERROR_EOF`也是正常的。 另外,错误码可以用`av_err2str`函数转换为可读的字符串,方便调试。 总结: - 当`avcodec_receive_frame`返回负数时,首先判断是否是`EAGAIN`或`EOF`,这两种情况通常不需要视为错误,而是正常流程。 - 其他错误码则表明解码过程中出现了问题,需要根据具体情况进行处理。 希望以上信息能帮助你解决问题。</think>### FFmpeg `avcodec_receive_frame` 返回值小于0的错误处理 `avcodec_receive_frame` 是 FFmpeg 解码流程的核心函数,当返回值 `< 0` 时表示解码异常。以下是常见错误码及处理方法: #### 1. **`AVERROR(EAGAIN)`(错误码 -11)** - **含义**:解码器需要更多输入数据才能输出帧 - **处理**: ```c if (ret == AVERROR(EAGAIN)) { // 需要发送新的packet avcodec_send_packet(dec_ctx, next_packet); } ``` - **原因**:解码器内部有帧缓存,需多次调用`avcodec_send_packet`才能输出帧[^1][^3] #### 2. **`AVERROR_EOF`(错误码 -541478725)** - **含义**:解码器已刷新,无更多输出 - **处理**: ```c if (ret == AVERROR_EOF) { // 终止解码循环 break; } ``` - **触发条件**:调用`avcodec_send_packet(NULL)`刷新解码器后 #### 3. **`AVERROR(EINVAL)`(错误码 -22)** - **含义**:解码器未初始化或已关闭 - **处理**: 1. 检查`AVCodecContext`是否已初始化 2. 确认未重复释放资源 ```c if (!dec_ctx || !dec_ctx->internal) { avcodec_open2(dec_ctx, decoder, NULL); } ``` #### 4. **其他错误(如 -1094995529)** - **处理流程**: ```c char err_buf[256]; av_strerror(ret, err_buf, sizeof(err_buf)); fprintf(stderr, "Decoding error: %s\n", err_buf); // 重置解码器 avcodec_flush_buffers(dec_ctx); ``` #### ⚠️ 低延时场景优化 对于需要极低延时的场景(如自动驾驶流媒体): 1. 设置解码器参数: ```c AVDictionary *opts = NULL; av_dict_set(&opts, "tune", "zerolatency", 0); av_dict_set(&opts, "fflags", "nobuffer", 0); avcodec_open2(dec_ctx, decoder, &opts); ``` 2. 使用 **无B帧的H.264流** 减少依赖[^1] 3. 启用硬件加速: ```c dec_ctx->get_format = get_hw_format; // 设置硬件解码回调 ``` > **关键点**:当遇到`EAGAIN`时,需持续发送packet直至解码器输出帧,这是由编解码器内部缓冲机制决定的[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值