配置 AVCodecContext 结构以从原始 PCM 编码为 u-law

Configure AVCodecContext structure to encode from raw PCM to u-law

我正在尝试将原始 PCM 音频数据编码为 u-law,这听起来很奇怪(当它听起来...)。我不太了解如何初始化我的 AVCodecContext 结构(以及我的输入 AVFrame)。

这是我的参数:

我也知道我的输入 nb 样本,这是我所有的信息。

所以我这样初始化我的 AVCodecContext

AVCodec* pCodec = avcodec_find_encoder(AV_CODEC_ID_PCM_MULAW);
// ...
AVCodecContext* pCodecContext = avcodec_alloc_context3(pCodec);
// ...
// Do I need input or output params in following lines?
pCodecContext->channels = 1:
pCodecContext->channel_layout = AV_CH_LAYOUT_MONO;
pCodecContext->sample_rate = 8000;
pCodecContext->bit_rate = 64000
pCodecContext->sample_fmt = AV_SAMPLE_FMT_S16;

我的 AVFrame 喜欢:

AVFrame* pFrame = av_frame_alloc();
pFrame->channels = 1;
pFrame->channel_layout = AV_CH_LAYOUT_MONO;
pFrame->sample_rate = 44100;
pFrame->format = AV_SAMPLE_FMT_S16;
pFrame->nb_samples = /*my audio data samples count*/;
avcodec_fill_audio_frame(pFrame, 1, AV_SAMPLE_FMT_S16, /*my audio data*/, /*my audio data size*/, 0);

然后,我用 avcodec_send_frame()avcodec_receive_packet() 编码。

所以我的问题是我不确定是否必须在不同的参数中输入或输出所需的值。可能我必须使用 swresample lib 以某种方式进行编码,然后 "resample"。但就目前而言,我很确定我没有正确编码。有什么建议吗?谢谢!

G.711 要求您的输入为 8kHz 单声道(例如 sample_rate of 8000)。因此,在将原始 pcm 音频样本传递给 libavcodec 之前,您必须使用 swresample 或任何其他可以做到这一点的库将它们转换为 8kHz。如果您自己捕获原始 pcm,通常您可以从 os 声音 api.

请求 8kHz 采样率

我很确定您可以在 android 设备上请求 8kHz 音频。 G.711 是如此简单的编解码器,您不需要 libavcodec。您可以使用任何可用的 g711.c 并简单地为每个样本调用 linear2alawlinear2ulaw。基本上 linear2alawlinear2ulaw 将每个 16 位音频样本转换为一个字节的 g711 比特流。

您还应确保正确初始化 AVCodecContext

pCodecContext->channels = 1;
pCodecContext->channel_layout = AV_CH_LAYOUT_MONO; 
...