2017-05-15 2 views
1

J'essaie d'encoder des données audio PCM brutes vers la loi et c'est très étrange (quand ça sonne ...). Je ne comprends pas à peu près comment initialiser ma structure AVCodecContext (et mon entrée AVFrame).Configurer la structure AVCodecContext pour coder du PCM brut à la loi

Voici mes paramètres:

  • Entrée: PCM (16bits signé), MONO, 44,1kHz (fréquence d'échantillonnage) (à partir de mon appareil Android MIC)

  • Résultat requis: G. 711 u règlement, MONO, 8kHz (fréquence d'échantillonnage), 64 kbits/s (bitrate) (de ma documentation du périphérique cible de sortie)

Je sais aussi mes entrées échantillons nb et c'est des informations que j'ai.

J'initialize mes AVCodecContext comme ça:

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; 

Et mon AVFrame s comme:

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); 

Ensuite, j'Encode avec avcodec_send_frame() et avcodec_receive_packet(). Donc, mon problème est que je ne suis pas sûr si je dois mettre en entrée ou en sortie les valeurs souhaitées dans différents paramètres. Probablement je dois encoder sur un chemin puis "rééchantillonner" en utilisant swresample lib. Mais pour l'instant, je suis à peu près sûr que je ne code pas correctement. Tout conseil s'il vous plaît? Merci!

Répondre

1

G.711 nécessite que votre entrée soit 8 kHz mono (par exemple sample_rate de 8000). Donc, avant de passer vos échantillons audio pcm bruts à libavcodec vous devez les convertir en 8kHz avec swresample ou tout autre lib qui peut le faire. Si vous capturez votre pcm brut vous-même, vous pouvez généralement demander un taux d'échantillonnage de 8 kHz à partir de l'api du son. Je suis assez sûr que sur les appareils Android, vous pouvez demander l'audio 8kHz. G.711 est un codec si simple, vous n'avez pas besoin de libavcodec pour cela. Vous pouvez utiliser n'importe quel g711.c disponible et simplement appeler linear2alaw ou linear2ulaw pour chaque échantillon. Fondamentalement linear2alaw ou linear2ulaw convertir chaque échantillon audio de 16 bits en un octet de g711 bitstream.

Vous devez également vous assurer que vous Initialiser votre AVCodecContext correctement:

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

Merci de votre réponse, je comprends mon problème et peut travailler avec cette connaissance. Je pensais libavcodec capable de "encoder" dans un taux d'échantillonnage différent! J'ai besoin de libavcodec parce que je pourrais avoir d'autres périphériques de sortie avec d'autres formats supportés. – N0un

+0

Est-il normal que je ne puisse pas ouvrir un codec en U (codeur 'AVCodec') avec une fréquence d'échantillonnage de 8 kHz? – N0un

+0

@ N0un fait 'avcodec_find_encoder (AV_CODEC_ID_PCM_MULAW);' return NULL? – Pavel