[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