[Libav-user] Converting 3gp (amr) to mp3 using ffmpeg api calls (low quality)

Sebastian Ludwig ludwig at lyth.de
Tue Mar 13 14:02:26 CET 2012

Converting 3gp (amr) to mp3 using ffmpeg api calls

I try to use libavformat (ffmpeg) to build my own function that converts 
3gp audio files (recorded with an android mobile device) into mp3 files.

I use av_read_frame() to read a frame from the input file and use 
avcodec_decode_audio3() to decode the data
into a buffer and use this buffer to encode the data into mp3 with 
This seems to give me a correct result for converting wav to mp3 and mp3 
to wav (Or decode one mp3 and encode to another mp3) but not for amr to mp3.
My resulting mp3 file seems to has the right length but only consists of 

In another post I read that amr-decoder does not use the same sample 
format than mp3 does.
AMR uses FLT and mp3 S16 or S32 und that I have to do resampling.
So I call av_audio_resample_init() and audio_resample for each frame 
that has been decoded.
But that does not solve my problem completely. Now I can hear my 
recorded voice and unsterstand what I was saying, but the quality is 
very low and there is still a lot of noise.
I am not sure if I set the parameters of av_audio_resample correctly, 
especially the last 4 parameters (I think not) or if I miss something else.

     ReSampleContext* reSampleContext = av_audio_resample_init(1, 1, 
44100, 8000, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT, 0, 0, 0, 0.0);

         if(av_read_frame(ic, &avpkt) < 0)

         out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
         int count;

         count = avcodec_decode_audio3(audio_stream->codec, (short 
*)decodedBuffer, &out_size, &avpkt);

         if(count < 0)

         if((audio_resample(reSampleContext, (short *)resampledBuffer, 
(short *)decodedBuffer, out_size / 4)) < 0)
             fprintf(stderr, "Error\n");

         out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;

         pktOut.size = avcodec_encode_audio(c, outbuf, out_size, (short 

         if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
             pktOut.pts = av_rescale_q(c->coded_frame->pts, 
c->time_base, outStream->time_base);

         pktOut.pts = AV_NOPTS_VALUE;
         pktOut.dts = AV_NOPTS_VALUE;

         pktOut.flags |= AV_PKT_FLAG_KEY;
         pktOut.stream_index = audio_stream->index;
         pktOut.data = outbuf;

         if(av_write_frame(oc, &pktOut) != 0)
             fprintf(stderr, "Error while writing audio frame\n");

Sebastian Ludwig, Dipl.-Inform. (FH)

Lyncker&   Theis GmbH
Wilhelmstr. 16
65185 Wiesbaden

Fon +49 611/89038960
Fax +49 611/9406125

Handelsregister: HRB 23156 Amtsgericht Wiesbaden
Steuernummer: 4023897051
USt-IdNr.: DE255806399

Filip Lyncker,
Armin Theis,
Patrick Schmidt

More information about the Libav-user mailing list