Hi,
I'm developing a mobile music player and I'm planning to use ffmpeg for
some of the audio decoding. The decoder has been written some time ago, but it
seems to work ok (music plays without issues). Except for APE files. The result
is as if the decoder was seeking ~0.8 second forward after reading each packet,
so that a 4 minute track plays in a couple of seconds. Decoding of one stereo
96kHz APE file results in frames with 18432 bytes of data each (4608 samples,
or 48 ms), but the consecutive timestamps are as follows:
49.152000
49.919998
50.688000
51.456001
52.223999
I've created an ugly workaround by manually counting the total number of
samples read and seeking to the correct time just after decoding a packet. The
music sounds ok on APE files (but has occassional glitches on ALAC M4As- which
is unnacceptable, in addition to the overall ugliness of the solution). I've
downloaded a windows build of the library and converted the APE files to MP3s
using CLI ffmpeg. Files converted just fine, so they are not broken and I
assume it is not a bug of ffmpeg itself. My android code is built against
ffmpeg 2.7.2, the same version that I've downloaded pre-built for Windows.
Excerpts from my code (with some logging and non-ffmpeg related stuff removed
for readibility):
//OPENING THE FILE
ret = avformat_open_input(&(af->mFormatCtx), native_name, NULL, NULL);
if (ret < 0)
{
return 0;
}
ret = avformat_find_stream_info(af->mFormatCtx, NULL);
if (ret < 0)
{
return 0;
}
ret = av_find_best_stream(af->mFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1,
&(af->mCodec), 0);
if (ret < 0) {
return 0;
}
af->mAudioStream = ret;
af->mCodecCtx = af->mFormatCtx->streams[af->mAudioStream]->codec;
af->mDuration = -1.0f;
af->mDTimebase =
av_q2d(af->mFormatCtx->streams[af->mAudioStream]->time_base);
double duration =
(double)af->mFormatCtx->streams[af->mAudioStream]->duration;
if (af->mDTimebase > 0.0 && duration > 0.0)
{
af->mDuration = (float)(duration*af->mDTimebase);
}
av_opt_set_int(af->mCodecCtx, "refcounted_frames", 1, 0);
if ((ret = avcodec_open2(af->mCodecCtx, af->mCodec, NULL)) < 0)
{
return 0;
}
//READING A FRAME
int got_frame;
int ret;
for (;;)
{
ret = av_read_frame(af->mFormatCtx, &(af->mPacket));
if (ret < 0)
{
return ret;
}
if (af->mPacket.stream_index == af->mAudioStream)
{
avcodec_get_frame_defaults(frame);
got_frame = 0;
ret = avcodec_decode_audio4(af->mCodecCtx, frame, &got_frame,
&(af->mPacket));
if (ret < 0)
{
continue;
}
if (got_frame)
{
af->mTimestamp = (float)(af->mPacket.pts *
af->mDTimebase);
return 0;
}
}
av_free_packet(&(af->mPacket));
}
What am I doing wrong? Should I pass some additional parameters to the codec?
Best regards,
Michał Kurowski
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user