我正在尝试将原始PCM音频数据编码为u-law,这听起来很奇怪(听起来......)。我几乎不了解如何初始化我的AVCodecContext
结构(以及我的输入AVFrame
)。
以下是我的参数:
输入:PCM(16位签名),MONO,44,1kHz(采样率)(来自我的Android设备MIC)
所需输出:G.711 u-law,MONO,8kHz(采样率),64 kbits / s(比特率)(来自我的输出目标设备的文档)
我也知道我输入的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以“重新采样”的方式进行编码。但是现在,我很确定我没有正确编码。有什么建议吗?谢谢!
答案 0 :(得分:1)
G.711要求您的输入为8kHz单声道(例如,sample_rate为8000)。因此,在将原始pcm音频样本传递给libavcodec之前,您必须使用swresample或任何其他可以执行此操作的库将它们转换为8kHz。如果您自己捕获原始pcm,则可以从os sound api请求8kHz采样率。
我非常确定在Android设备上你可以请求8kHz音频。 G.711是一个如此简单的编解码器,你不需要libavcodec。您可以使用任何可用的g711.c,只需为每个样本调用linear2alaw
或linear2ulaw
即可。基本上linear2alaw
或linear2ulaw
将每个16位音频样本转换为g711比特流的字节。
您还应确保正确初始化AVCodecContext
:
pCodecContext->channels = 1;
pCodecContext->channel_layout = AV_CH_LAYOUT_MONO;
...