【问题标题】:ffmpeg avcodec_open2 returns -22 if I change my speaker configuration如果我更改扬声器配置,ffmpeg avcodec_open2 返回 -22
【发布时间】:2014-11-30 01:13:15
【问题描述】:

我最近总是遇到一个奇怪的问题。 根据我在 Windows (stereo/quad/5.1) 中设置音频配置的方式,对 avcodec_open2() 的 ffmpeg 调用失败并出现错误 -22 或正常工作。 无法找到有关该错误的太多信息,我想我应该在这里问一下。 主要流程是这样的:

c = st->codec;
avformat_alloc_output_context2(&oc, NULL, NULL, "video.mpeg");
oc->fmt->audio_codec = AV_CODEC_ID_MP2;
AVDictionary* dict = NULL;
ret = av_dict_set(&dict, "ac", "2", 0);
c->request_channels = 2;

ret = avcodec_open2(c, codec, &dict); //HERE IT FAILS WITH -22 if speaker configuration  is not stereo

编解码器上下文“c”在流中设置如下:

st = avformat_new_stream(oc, *codec);
c = st->codec;
c->channels     = 2;
c->channel_layout = AV_CH_LAYOUT_STEREO;
c->sample_fmt   = AV_SAMPLE_FMT_S16;
c->codec_id     = codec_id;

其中大部分内容是从他们在文档中找到的复用示例之一复制而来的。 如果在 Windows 中我将输出设置为立体声,一切都会按预期工作。

如果我将扬声器配置设置为 5.1(6 个通道),avcodec_open2 会失败并出现错误 -22。

所以我很难理解我做错了什么。通常,我的扬声器配置和 avcodec_open2 的结果之间应该没有任何关系。

还有其他需要设置的参数吗?

【问题讨论】:

  • 为了更加清楚,如果 Windows 扬声器配置设置为立体声,一切都按预期工作。
  • 我用谷歌搜索,我发现你应该尝试类似av_log_set_level(AV_LOG_VERBOSE); 来更详细地了解错误。然后void my_log_callback(void *ptr, int level, const char *fmt, va_list vargs) { printf ("\n%s",fmt);} 然后av_log_set_callback(my_log_callback);
  • 但是错误 -22 确实是错误 22 因为任何可能的数字都意味着它应该返回多少字节所以.. 错误 22 是 #define EINVAL 22 /* Invalid argument */ 这意味着参数无效。
  • 我明白了,我会看看这里传入的参数的差异(立体声与 5.1):avcodec_open2。也许我错过了什么。我记得他们是一样的。我会仔细检查:)
  • 我想你想要AV_CH_LAYOUT_5POINT1 而不是AV_CH_LAYOUT_STEREO 我猜有 6 个频道。

标签: c ffmpeg


【解决方案1】:

这是文件 libavcodec\avcodec.h 的标题,取自 How can I find out what this ffmpeg error code means?

#if EINVAL > 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 AVERROR_UNKNOWN     AVERROR(EINVAL)  /**< unknown error */
#define AVERROR_IO          AVERROR(EIO)     /**< I/O error */
#define AVERROR_NUMEXPECTED AVERROR(EDOM)    /**< Number syntax expected in filename. */
#define AVERROR_INVALIDDATA AVERROR(EINVAL)  /**< invalid data found */
#define AVERROR_NOMEM       AVERROR(ENOMEM)  /**< not enough memory */
#define AVERROR_NOFMT       AVERROR(EILSEQ)  /**< unknown format */
#define AVERROR_NOTSUPP     AVERROR(ENOSYS)  /**< Operation not supported. */
#define AVERROR_NOENT       AVERROR(ENOENT)  /**< No such file or directory. */
#define AVERROR_EOF         AVERROR(EPIPE)   /**< End of file. */
#define AVERROR_PATCHWELCOME    -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */

那么 errno.h EINVAL 的头文件

#define EINVAL          22      /* Invalid argument */

附: AVERROR 表示(-(-22)) = 22

频道头channel_layout.h头文件的布局

/**
 * @file
 * audio conversion routines
 */

/* Audio channel masks */
#define AV_CH_FRONT_LEFT             0x00000001
#define AV_CH_FRONT_RIGHT            0x00000002
#define AV_CH_FRONT_CENTER           0x00000004
#define AV_CH_LOW_FREQUENCY          0x00000008
#define AV_CH_BACK_LEFT              0x00000010
#define AV_CH_BACK_RIGHT             0x00000020
#define AV_CH_FRONT_LEFT_OF_CENTER   0x00000040
#define AV_CH_FRONT_RIGHT_OF_CENTER  0x00000080
#define AV_CH_BACK_CENTER            0x00000100
#define AV_CH_SIDE_LEFT              0x00000200
#define AV_CH_SIDE_RIGHT             0x00000400
#define AV_CH_TOP_CENTER             0x00000800
#define AV_CH_TOP_FRONT_LEFT         0x00001000
#define AV_CH_TOP_FRONT_CENTER       0x00002000
#define AV_CH_TOP_FRONT_RIGHT        0x00004000
#define AV_CH_TOP_BACK_LEFT          0x00008000
#define AV_CH_TOP_BACK_CENTER        0x00010000
#define AV_CH_TOP_BACK_RIGHT         0x00020000
#define AV_CH_STEREO_LEFT            0x20000000  ///< Stereo downmix.
#define AV_CH_STEREO_RIGHT           0x40000000  ///< See AV_CH_STEREO_LEFT.

/** Channel mask value used for AVCodecContext.request_channel_layout
    to indicate that the user requests the channel order of the decoder output
    to be the native codec channel order. */
#define AV_CH_LAYOUT_NATIVE          0x8000000000000000LL

/* Audio channel convenience macros */
#define AV_CH_LAYOUT_MONO              (AV_CH_FRONT_CENTER)
#define AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
#define AV_CH_LAYOUT_2_1               (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER)
#define AV_CH_LAYOUT_SURROUND          (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)
#define AV_CH_LAYOUT_4POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER)
#define AV_CH_LAYOUT_2_2               (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
#define AV_CH_LAYOUT_QUAD              (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_5POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
#define AV_CH_LAYOUT_5POINT1           (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_5POINT0_BACK      (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_5POINT1_BACK      (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_7POINT0           (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_7POINT1           (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_7POINT1_WIDE      (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
#define AV_CH_LAYOUT_STEREO_DOWNMIX    (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT)

【讨论】:

  • 我投了这个作为答案。事实证明,我犯了一个意外错误,并为 5.1 扬声器配置设置了不同的比特率。 (实际系统比上面的示例代码要复杂一些)。这对我理解这个问题有很大帮助,所以我投票给它作为答案。谢谢
猜你喜欢
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多