关于FFmpeg错误码的几个小常识

FFmpeg编程有两个最常见的问题:

1. timebase如何理解?

2. av_xxx接口返回-11怎么办?

第一个问题有FFmpeg自身设计带来的复杂性。关于第二个问题,我本来以为简单到无需专门解释,RTFM即可,最近却发现一个新的场景,值得说一说。

一、FFmpeg错误码的构成

FFmpeg错误码有两部分组成:

  1. 自定义部分。自定义部分是用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里定义的错误码,并将其负数化:

  1. 如果errno.h里的错误码是正数,FFmpeg加一个负号来用
  2. 假如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 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论