[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
avcodec_encode_audio.
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
noise.
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);
while(1)
{
if(av_read_frame(ic, &avpkt) < 0)
{
break;
}
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int count;
count = avcodec_decode_audio3(audio_stream->codec, (short
*)decodedBuffer, &out_size, &avpkt);
if(count < 0)
{
break;
}
if((audio_resample(reSampleContext, (short *)resampledBuffer,
(short *)decodedBuffer, out_size / 4)) < 0)
{
fprintf(stderr, "Error\n");
exit(1);
}
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
pktOut.size = avcodec_encode_audio(c, outbuf, out_size, (short
*)resampledBuffer);
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);
//av_res
}
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");
exit(1);
}
}
--
_______________________________
Sebastian Ludwig, Dipl.-Inform. (FH)
Lyncker& Theis GmbH
Wilhelmstr. 16
65185 Wiesbaden
Germany
Fon +49 611/89038960
Fax +49 611/9406125
Handelsregister: HRB 23156 Amtsgericht Wiesbaden
Steuernummer: 4023897051
USt-IdNr.: DE255806399
Geschäftsführer:
Filip Lyncker,
Armin Theis,
Patrick Schmidt
More information about the Libav-user
mailing list