为什么 avcodec_fill_audio_frame return -22 只有样本计数不同?
Why does avcodec_fill_audio_frame return -22 when only sample count is different?
我的问题解释起来非常快:我必须使用 FFmpeg(原始 PCM 到 G.711 mu-law)对音频样本进行编码。这是我的代码有罪的部分(我在这个例子中把原始参数显式):
AVFrame* frame = av_frame_alloc();
frame->nb_samples = 8000;
frame->format = AV_SAMPLE_FMT_S16;
frame->channels = 1;
frame->channel_layout = AV_CH_LAYOUT_MONO;
frame->sample_rate = 8000;
frame->quality = 1;
int res = avcodec_fill_audio_frame(frame, 1, AV_SAMPLE_FMT_S16, /*my samples data*/, 16000, 0);
// If res >= 0, continue with avcodec_encode_audio2
而且有效:) ...嗯,我的意思是...
当我的输入是 8000 音频样本时(S16 格式所以 16000 字节),有用。但是当我有 6000 音频样本时(仍然是 S16 格式所以 12000 字节),它失败了-22(无效参数)。有什么想法吗?
PRECISION: 此样本数不会动态变化。我的数据会话总是由 8000 个样本组成(并且有效),而其他会话的数据总是由 6000 个样本组成(并且失败)。样本数和数据大小是这些会话之间唯一不同的参数。
编辑: 如果我设置或不设置 AVCodecContext
中的 frame_size
字段,它 returns 在 avcodec_open2
之后变为 0但所选的 mu-law 编码器具有 AV_CODEC_CAP_VARIABLE_FRAME_SIZE
功能,因此听起来很正常。
每次调用 avcodec_encode_audio2()
的输入应该恰好是 N 个样本,其中 N 是 AVCodecContext::frame_size
。在某些情况下,这取决于编解码器(例如 mp3 帧大小是恒定的),但在其他情况下,它可以是可变的。对于大多数编码器来说,它在编码中应该仍然是常量。看起来你的值就是默认值,mulaw 没有内置常量,所以你可以在调用 avcodec_open2()
之前指定一个不同的 frame_size
值,你应该没问题。
如果您的样本数量动态变化,您需要一个环形缓冲区来确保 avcodec_encode_audio2()
的输入仍然具有恒定数量的样本。
好的,我解决了我自己的问题,这是一个对齐问题。有两种解决方法:
根据 libavcodec
所需的默认对齐方式对输入缓冲区进行初始化和填充。您可以将 av_samples_get_buffer_size
与对齐值一起使用,以 0 获得正确的大小。
调用 avcodec_fill_audio_frame
并将对齐参数设置为 1 以忽略对齐。
希望这对其他人有帮助:)
我的问题解释起来非常快:我必须使用 FFmpeg(原始 PCM 到 G.711 mu-law)对音频样本进行编码。这是我的代码有罪的部分(我在这个例子中把原始参数显式):
AVFrame* frame = av_frame_alloc();
frame->nb_samples = 8000;
frame->format = AV_SAMPLE_FMT_S16;
frame->channels = 1;
frame->channel_layout = AV_CH_LAYOUT_MONO;
frame->sample_rate = 8000;
frame->quality = 1;
int res = avcodec_fill_audio_frame(frame, 1, AV_SAMPLE_FMT_S16, /*my samples data*/, 16000, 0);
// If res >= 0, continue with avcodec_encode_audio2
而且有效:) ...嗯,我的意思是...
当我的输入是 8000 音频样本时(S16 格式所以 16000 字节),有用。但是当我有 6000 音频样本时(仍然是 S16 格式所以 12000 字节),它失败了-22(无效参数)。有什么想法吗?
PRECISION: 此样本数不会动态变化。我的数据会话总是由 8000 个样本组成(并且有效),而其他会话的数据总是由 6000 个样本组成(并且失败)。样本数和数据大小是这些会话之间唯一不同的参数。
编辑: 如果我设置或不设置 AVCodecContext
中的 frame_size
字段,它 returns 在 avcodec_open2
之后变为 0但所选的 mu-law 编码器具有 AV_CODEC_CAP_VARIABLE_FRAME_SIZE
功能,因此听起来很正常。
每次调用 avcodec_encode_audio2()
的输入应该恰好是 N 个样本,其中 N 是 AVCodecContext::frame_size
。在某些情况下,这取决于编解码器(例如 mp3 帧大小是恒定的),但在其他情况下,它可以是可变的。对于大多数编码器来说,它在编码中应该仍然是常量。看起来你的值就是默认值,mulaw 没有内置常量,所以你可以在调用 avcodec_open2()
之前指定一个不同的 frame_size
值,你应该没问题。
如果您的样本数量动态变化,您需要一个环形缓冲区来确保 avcodec_encode_audio2()
的输入仍然具有恒定数量的样本。
好的,我解决了我自己的问题,这是一个对齐问题。有两种解决方法:
根据
libavcodec
所需的默认对齐方式对输入缓冲区进行初始化和填充。您可以将av_samples_get_buffer_size
与对齐值一起使用,以 0 获得正确的大小。调用
avcodec_fill_audio_frame
并将对齐参数设置为 1 以忽略对齐。
希望这对其他人有帮助:)