FFmpeg编程有两个最常见的问题:
1. timebase如何理解?
2. av_xxx接口返回-11怎么办?
第一个问题有FFmpeg自身设计带来的复杂性。关于第二个问题,我本来以为简单到无需专门解释,RTFM即可,最近却发现一个新的场景,值得说一说。
一、FFmpeg错误码的构成
FFmpeg错误码有两部分组成:
- 自定义部分。自定义部分是用FourCC再加上负号构成的#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d))
FourCC是用四个字符构成的一个整型。因为FourCC是正数,FFmpeg错误码是负数,所以在MKTAG()前加一个负号。
一些常见的自定义错误码有:
- AVERROR_EOF:文件到头了,或者编解码、filter等处理完了最后一笔数据。EOF不算是真正的错误
- AVERROR_INVALIDDATA:数据损坏了,无法识别解析
- AVERROR_EXTERNAL:第三方库报错,没有对应的错误码,但日志一般有第三方库更具体的错误信息
- AVERROR_DECODER_NOT_FOUND、AVERROR_DEMUXER_NOT_FOUND 、AVERROR_ENCODER_NOT_FOUND ……,找不到对应的解码前、解封装、编码器等等
2. 复用系统定义的错误码
这部分是复用errno.h里定义的错误码,并将其负数化:
- 如果errno.h里的错误码是正数,FFmpeg加一个负号来用
- 假如errno.h里定义的错误码是负数,FFmpeg直接拿来用
当前多数能碰到的系统,errno都是正数。BeOS系统的errno是负数,FFmpeg代码提交记录显示是为了支持BeOS系统加上的第二条。
/* 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
二、如何查看错误码的含义
知道了错误码的来源,也就知道了如何查看错误码的含义。某个API返回了一个error,我们可以:
1. 和已知的错误码做比较。通常需要处理的是AVERROR(EAGAIN)和AVERROR_EOF
2. 打印错误信息描述,通过av_strerror、av_err2str等
三、错误码的数值是跨平台的吗?
FFmpeg错误码数值是否跨平台,取决于errno是否跨平台。注意:errno的数值是平台相关的。所以才出现了这么一幕:
A: avcodec_receive_frame return -11表示什么?
B:AVERROR(EAGAIN)
A:胡说八道,AVERROR(EAGAIN)是-35
问题出在哪里呢?A在Android上运行测试,在macOS系统头文件里查询errno的数值。Android/Linux上EAGAIN是11,macOS上EAGAIN是35,然后闹出了笑话。
作者: quink 来源:公众号——Fun With FFmpeg
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。