FFmpeg音频编码器帧大小

3

我需要将音频数据从AV_CODEC_ID_PCM_S16LE转换为AV_CODEC_ID_PCM_ALAW,我正在使用这个代码示例。示例代码基本上执行以下操作(出于简洁起见省略错误检查):

const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
AVCodecContext* c = avcodec_alloc_context3(codec);
c->bit_rate       = 64000;
c->sample_fmt     = AV_SAMPLE_FMT_S16;
c->sample_rate    = select_sample_rate(codec);
c->channel_layout = select_channel_layout(codec);
c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
avcodec_open2(c, codec, NULL);
AVFrame* frame = av_frame_alloc();
frame->nb_samples     = c->frame_size;
frame->format         = c->sample_fmt;
frame->channel_layout = c->channel_layout;

下面的示例代码在for循环中使用了c->frame_size

我的代码与上述代码类似,但有以下区别:

const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_PCM_ALAW);
c->sample_rate    = 8000;
c->channel_layout = AV_CH_LAYOUT_MONO;
c->channels       = 1;

在调用 avcodec_open2 后,c->frame_size 的值为零。示例代码从未设置帧大小,因此我假设它期望 avcodec_alloc_context3avcodec_open2 进行设置。这是正确的吗?帧大小的设置是否取决于所使用的编解码器?如果必须显式设置帧大小,是否有建议的大小?
编辑:
根据 @the-kamilz 的答案,似乎示例代码不够稳健。该示例假设 c->frame_size 将被设置,但这似乎取决于编解码器。在我的情况下,实际上将 codec->capabilities 设置为 AV_CODEC_CAP_VARIABLE_FRAME_SIZE。因此,我修改了我的代码以检查c->frame_size,并仅在其值不为零时使用它。如果为零,则仅选择一秒钟的数据作为frame->nb_samples的样本数。
2个回答

1
在FFmpeg文档中提到:

int AVCodecContext :: frame_size

每个音频帧中每个通道的样本数。

编码:由libavcodec在avcodec_open2()中设置。除最后一个提交的帧外,每个提交的帧必须恰好包含frame_size个每个通道的样本。
当编解码器设置了AV_CODEC_CAP_VARIABLE_FRAME_SIZE时,可以为0,然后 帧大小不受限制。
解码:某些解码器可能设置以指示常量帧大小。

希望这有所帮助。

0

你无法显式地控制帧大小,它是由编码器根据初始化(打开)时提供的编解码器设置的。

一旦 avcodec_open2() 成功,你可以使用 av_samples_get_buffer_size() 检索帧缓冲区的大小。


我应该向 av_samples_get_buffer_size()nb_samples 参数传递什么值? - Jim Rhodes
:) OK sorry my bad - oli21270

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接