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

Reply via email to