我需要将音频数据从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_context3
或 avcodec_open2
进行设置。这是正确的吗?帧大小的设置是否取决于所使用的编解码器?如果必须显式设置帧大小,是否有建议的大小?编辑:
根据 @the-kamilz 的答案,似乎示例代码不够稳健。该示例假设
c->frame_size
将被设置,但这似乎取决于编解码器。在我的情况下,实际上将 codec->capabilities
设置为 AV_CODEC_CAP_VARIABLE_FRAME_SIZE
。因此,我修改了我的代码以检查c->frame_size
,并仅在其值不为零时使用它。如果为零,则仅选择一秒钟的数据作为frame->nb_samples
的样本数。
av_samples_get_buffer_size()
的nb_samples
参数传递什么值? - Jim Rhodes