配置 AVCodecContext 结构以从原始 PCM 编码为 u-law
Configure AVCodecContext structure to encode from raw PCM to u-law
我正在尝试将原始 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 以某种方式进行编码,然后 "resample"。但就目前而言,我很确定我没有正确编码。有什么建议吗?谢谢!
G.711 要求您的输入为 8kHz 单声道(例如 sample_rate of 8000)。因此,在将原始 pcm 音频样本传递给 libavcodec 之前,您必须使用 swresample 或任何其他可以做到这一点的库将它们转换为 8kHz。如果您自己捕获原始 pcm,通常您可以从 os 声音 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;
...
我正在尝试将原始 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 以某种方式进行编码,然后 "resample"。但就目前而言,我很确定我没有正确编码。有什么建议吗?谢谢!
G.711 要求您的输入为 8kHz 单声道(例如 sample_rate of 8000)。因此,在将原始 pcm 音频样本传递给 libavcodec 之前,您必须使用 swresample 或任何其他可以做到这一点的库将它们转换为 8kHz。如果您自己捕获原始 pcm,通常您可以从 os 声音 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;
...