【发布时间】:2020-07-14 18:11:51
【问题描述】:
我需要将音频数据从 AV_CODEC_ID_PCM_S16LE 转换为 AV_CODEC_ID_PCM_ALAW,我以 this 代码为例。示例代码基本上是这样做的(为简洁起见,省略了错误检查):
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 选择了任意一秒的数据。
【问题讨论】: