New submission from aviad rozenhek <avia...@gmail.com>:

with this file (sample "seek_forward_then_to_0_not_working.mp4" uploaded 
to mplayer/incoming) when seeking to 0, seeking fails in the sense that 
stream #1 (audio) doesnt seek at all, while stream #0 (video) does 
indeed seek to 0.

the file seek_forward_then_to_0_not_working.mp4.txt (also uploaded by 
ftp) contains a test case which shows the problem.

----------
files: seek_forward_then_to_0_not_working.mp4.txt
messages: 10976
priority: normal
status: new
substatus: new
title: seek to 0 is broken in specific file
type: bug

________________________________________________
FFmpeg issue tracker <iss...@roundup.ffmpeg.org>
<https://roundup.ffmpeg.org/issue2046>
________________________________________________
/*
 * Text file accompanying the sample "seek_forward_then_to_0_not_working.mp4"
 *
 * in this sample, when seeking forward, and then seeking back to 0, the audio 
stream does not actually seek to 0.
 * when reading, it will actually supply packets from before it was seeked back 
to 0.
 *
 * unfortunately I cannot reproduce using run-of-the-mill ffmpeg or ffplay, 
because I can't get them to seek to arbitrary point, and then seek exactly to 0.
 * below is a very simple test case using libav* that does the same thing, and 
shows the problem
 *
 * for completeness: here is the version information about libav* libraries I 
am using
 *
 * FFmpeg version SVN-r23391, Copyright (c) 2000-2010 the FFmpeg developers
 *   built on May 31 2010 04:07:01 with gcc 4.4.2
 *   configuration: --target-os=mingw32 --enable-runtime-cpudetect 
--enable-avisynth --enable-gpl --enable-version3 --enabl
 * e-bzlib --enable-libgsm --enable-libfaad --enable-pthreads 
--enable-libvorbis --enable-libtheora --enable-libspeex --ena
 * ble-libmp3lame --enable-libopenjpeg --enable-libxvid 
--enable-libschroedinger --enable-libx264 --extra-libs='-lx264 -lpt
 * hread' --enable-libopencore_amrwb --enable-libopencore_amrnb 
--enable-librtmp --extra-libs='-lrtmp -lssl -lcrypto -lws2_
 * 32 -lgdi32 -lwinmm -lcrypt32 -lz' --arch=x86 --cross-prefix=i686-mingw32- 
--cc='ccache i686-mingw32-gcc' --enable-memali
 * gn-hack --enable-shared --disable-static
 *   libavutil     50.16. 0 / 50.16. 0
 *   libavcodec    52.72. 0 / 52.72. 0
 *   libavformat   52.67. 0 / 52.67. 0
 *   libavdevice   52. 2. 0 / 52. 2. 0
 *   libavfilter    1.20. 0 /  1.20. 0
 *   libswscale     0.10. 0 /  0.10. 0
 * Hyper fast Audio and Video encoder
 *
 *
 *
 * Regards:
 * Aviad Rozenhek
 * avia...@gmail.com
 *
 */

// google unit test framework
#include <gtest/gtest.h>
#include <gtest/gtest-spi.h>

#include <inttypes.h>
#include <stdint.h>

#ifdef _MSC_VER
#include <intsafe.h>
#endif

extern "C" {
#       include <libavformat/avformat.h>
}

///
/// test case that tests the ability to seek forward into file,
/// and then seek to 0 timestamp.
TEST(AVFormat, seek_test) 
{
        int result;
        int read_packets;
        int streams_with_read_packet;
        int all_streams_with_read_packet;
        int64_t first_timestamp, last_timestamp;
        AVPacket packet;
        AVFormatContext* fmt;
        AVRational avtimebaseq = {1, AV_TIME_BASE};

        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4", NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

        /// seek 20 minutes forward
        ASSERT_LE(0, result = av_seek_frame(fmt, -1, 20 * 60 * AV_TIME_BASE, 
0));

        read_packets = 0;
        streams_with_read_packet = 0;
        all_streams_with_read_packet = (1 << fmt->nb_streams) - 1;
        first_timestamp = INT64_MAX;
        last_timestamp  = INT64_MIN;
        do {
                ASSERT_LE(0, av_read_frame(fmt, &packet));
                streams_with_read_packet |= (1 << packet.stream_index);
                read_packets++;

                first_timestamp = FFMIN(first_timestamp, 
av_rescale_q(packet.dts, fmt->streams[packet.stream_index]->time_base, 
avtimebaseq));
                last_timestamp  = FFMAX(last_timestamp , 
av_rescale_q(packet.dts, fmt->streams[packet.stream_index]->time_base, 
avtimebaseq));
        }
        while(streams_with_read_packet != all_streams_with_read_packet);
        
        // we expect to be able to have read a packet from all streams by going 
through less than 1000 packets
        // the actual value in this specific case is 2 packets
        EXPECT_LE(read_packets, 2);

        // we expect that there won't be much time difference between the first 
and last timestamp encountered
        // the actual value in this specific case is 19139 ( = ~19ms )
        EXPECT_LE(last_timestamp - first_timestamp, 60 * AV_TIME_BASE);

        // seek back to 0
        // XXX: this seems not to work properly for this file! see failed 
asserts below
        ASSERT_LE(0, result = av_seek_frame(fmt, -1, 0, AVSEEK_FLAG_BACKWARD));
                
        read_packets = 0;
        streams_with_read_packet = 0;
        all_streams_with_read_packet = (1 << fmt->nb_streams) - 1;
        first_timestamp = INT64_MAX;
        last_timestamp  = INT64_MIN;
        do {
                ASSERT_GE(0, av_read_frame(fmt, &packet));
                streams_with_read_packet |= (1 <<packet.stream_index);
                read_packets++;

                first_timestamp = FFMIN(first_timestamp, 
av_rescale_q(packet.dts, fmt->streams[packet.stream_index]->time_base, 
avtimebaseq));
                last_timestamp  = FFMAX(last_timestamp , 
av_rescale_q(packet.dts, fmt->streams[packet.stream_index]->time_base, 
avtimebaseq));
        }
        while(streams_with_read_packet != all_streams_with_read_packet);
        
        // again, we expect to be able to have read packets from all streams by 
reading less than 1000 packets
        // XXX: in this specific test case, it takes 36074(!) packets in order 
to get a packet from stream #1 (audio)
        EXPECT_LE(read_packets, 1000);

        // again, we expect that all timestamps will be around 0 (where we have 
been seeking to)
        // XXX: in this specific test case, the first audio sample is from 
1202398912 ( = ~20min)
        //      this means that the audio stream has not seeked properly
        EXPECT_LE(last_timestamp - first_timestamp, 60 * AV_TIME_BASE);
}

int main(int argc, char** argv) {
        testing::InitGoogleTest(&argc, argv);

        /* register all codecs, demux and protocols */
        avcodec_init();
        avcodec_register_all();
        av_register_all();

        // Runs all tests using Google Test.
        const int result = RUN_ALL_TESTS();

        puts("press enter to continue");
        getchar();

        return result;
};

Reply via email to