Настройте структуру AVCodecContext для кодирования из необработанного PCM в u-law

Я пытаюсь кодировать необработанные аудиоданные PCM в u-law, и это звучит очень странно (когда это звучит …). Я не очень понимаю, как инициализировать мой AVCodecContext структура (и мой вклад AVFrame).

Вот мои параметры:

  • Вход: PCM (16 бит со знаком), MONO, 44,1 кГц (частота дискретизации) (с микрофона моего устройства Android)

  • Требуемый выход: u-закон G.711, MONO, 8 кГц (частота дискретизации), 64 кбит / с (битрейт) (из документации моего выходного целевого устройства)

Я также знаю свои входные образцы 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. Но сейчас я почти уверен, что не правильно кодирую. Любой совет, пожалуйста? Спасибо!

1

Решение

G.711 требует, чтобы ваш вход был моно 8 кГц (например, sample_rate of 8000). Итак, перед передачей ваших необработанных аудиосэмплов pcm в libavcodec вы должны преобразовать их в 8 кГц с помощью swresample или любой другой библиотеки, которая может это сделать. Если вы обычно снимаете свой необработанный pcm, вы можете запросить частоту дискретизации 8 кГц из os sound api.

Я уверен, что на устройствах с Android вы можете запрашивать звук 8 кГц. G.711 такой простой кодек, для этого вам не нужен libavcodec. Вы можете использовать любой доступный g711.c и просто позвони linear2alaw или же linear2ulaw для каждого образца. В принципе linear2alaw или же linear2ulaw преобразуйте каждый 16-битный аудиосэмпл в байт потока битов g711.

Вы также должны убедиться, что вы инициируете AVCodecContext должным образом:

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

Другие решения

Других решений пока нет …