[Libav-user] Grabbing alsa - default audio?

Jiří Novák novak.jirik at gmail.com
Fri Jun 10 21:59:59 CEST 2011


Hi, I am a newbie in using libavcodec.

What I am trying to manage is to record alsa sound from default device 
into mp2. Could somebody make me clear what I do wrong within my code?
The output file I receive this way is "unreplayable" :(

Thank you for any hint,
Jiri Novak

/* 
========================================================================================= 
*/
#include <iostream>
#include <stdio.h>
#include <assert.h>
#include <fstream>

#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096

extern "C" {
#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libavfilter/avfilter.h>
}

int main(int argc, char *argv[]) {
   // register devices, filters and codecs
   avdevice_register_all();
   avfilter_register_all();
   avcodec_init();
   avcodec_register_all();
   av_register_all();

   // file format, format context
   AVInputFormat *pInputFormat = av_find_input_format("alsa");
   AVFormatContext *pFormatCtxDec = avformat_alloc_context();
   assert(pInputFormat != NULL && "format unrecognized - pInputFormat is 
NULL!");
   assert(pFormatCtxDec != NULL && "format context could not be 
allocated - pFormatCtx pointer is NULL!");

   // format parameters
   AVFormatParameters input_audio_parameters, *iap = 
&input_audio_parameters;
   memset(iap, 0, sizeof(*iap));
   iap->prealloced_context = 1;
   iap->sample_rate = 44100;
   iap->channels = 1;

   // input_format_context, filename, input_format, buffer_size, 
format_parameters
   int ret = av_open_input_file(&pFormatCtxDec, "default", pInputFormat, 
0, iap);
   assert(ret >= 0 && "input video file could not be opened!");

   // retrieve stream information
   ret = av_find_stream_info(pFormatCtxDec);
   assert(pFormatCtxDec >= 0 && "could not retrieve input video stream 
info!");

   // dump information
   dump_format(pFormatCtxDec, 0, "default", 0);

   // find the first video stream
   int audioStream=-1;
   for(int i=0; i<pFormatCtxDec->nb_streams; i++)
     if(pFormatCtxDec->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
       audioStream=i;
       break;
     }
   if(audioStream==-1)
     return -1; // Didn't find a audio stream

   // get a pointer to the codec context for the video stream
   AVCodecContext *pCodecCtxDec = 
pFormatCtxDec->streams[audioStream]->codec;

   // find the decoder for the video stream
   AVCodec *pCodecDec = avcodec_find_decoder(pCodecCtxDec->codec_id);
   if(pCodecDec==NULL) {
     fprintf(stderr, "Unsupported codec!\n");
     return -1; // Codec not found
   }

   // open codec
   if (avcodec_open(pCodecCtxDec, pCodecDec)<0)
     return -1; // Could not open codec

   // alocate codec context
   AVCodecContext *pCodecCtxEnc = avcodec_alloc_context();
   assert(pCodecCtxEnc != NULL && "pCodecCtxEnc pointer is null!");

   // put sample parameters
   pCodecCtxEnc->bit_rate = 64000;
   pCodecCtxEnc->sample_rate = 44100;
   pCodecCtxEnc->channels = 2;

   // find MP2 encoder
   AVCodec *pCodecEnc = avcodec_find_encoder(CODEC_ID_MP2);
   assert(pCodecEnc != NULL && "pCodecEnc pointer is null!");

   // open the codec
   int retval = avcodec_open(pCodecCtxEnc, pCodecEnc);
   assert(retval == 0 && "could not open codec!");

   uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
   AVPacket avpkt;
   av_init_packet(&avpkt);
   int out_size, len, i=0;

   int frame_size = pCodecCtxEnc->frame_size;
   short *decoded  = (short*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
   uint8_t *encoded = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);

FILE *f = fopen("output.mp2", "wb");
if (!f) {
fprintf(stderr, "could not open output.mp2\n");
exit(1);
}

   while (av_read_frame(pFormatCtxDec, &avpkt)>=0 && i<100) {
       out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
       len = avcodec_decode_audio3(pCodecCtxDec, decoded, &out_size, 
&avpkt);
       if (len < 0) {
           fprintf(stderr, "Error while decoding\n");
           exit(1);
       }
       if (out_size > 0) {
     printf("decoded frame: %d, %d, %d\n", i, out_size, len);

         /* encode the samples */
     out_size = avcodec_encode_audio(pCodecCtxEnc, encoded, len, decoded);
     fwrite(encoded, 1, out_size, f);
       }
       i++;
   }

   return 0;
}


More information about the Libav-user mailing list