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