aviad rozenhek <[email protected]> added the comment:

tested with some more .mov files, all had same problems.
attached more test cases which show the problem.

----------
title: seek to 0 is broken in specific file -> seek to 0 is broken in mov 
demuxer
topic: +avformat

________________________________________________
FFmpeg issue tracker <[email protected]>
<https://roundup.ffmpeg.org/issue2046>
________________________________________________
// 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>
}

static void read_all_streams_after_seek(AVFormatContext* fmt)
{
        int read_packets;
        int streams_with_read_packet;
        int all_streams_with_read_packet;
        int64_t first_timestamp, last_timestamp;
        AVPacket packet;
        AVRational avtimebaseq = {1, AV_TIME_BASE};

        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, 100);

        // 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, 5 * AV_TIME_BASE);
}

TEST(AVFormat, seek_test1) 
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\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_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

TEST(AVFormat, seek_test2) 
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

        /// seek to end
        ASSERT_LE(0, result = avformat_seek_file(fmt, -1, INT64_MIN, 
fmt->duration, INT64_MAX, 0));
        read_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

TEST(AVFormat, seek_test3) 
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

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

                /// seek to 0
        ASSERT_LE(0, result = av_seek_frame(fmt, -1, 0, 0));
        read_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

TEST(AVFormat, seek_test4)
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

        /// seek to end
        ASSERT_LE(0, result = av_seek_frame(fmt, -1, fmt->duration, 
AVSEEK_FLAG_BACKWARD));
        read_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

TEST(AVFormat, seek_test_end)
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

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

        /// seek to end
        ASSERT_LE(0, result = avformat_seek_file(fmt, -1, 0, 0, fmt->duration, 
0));
        read_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

TEST(AVFormat, seek_test_begin)
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

        /// seek to end
        ASSERT_LE(0, result = avformat_seek_file(fmt, -1, 0, fmt->duration, 
fmt->duration, 0));
        read_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}


TEST(AVFormat, seek_test_fails1) 
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

        /// seek to end
        /// XXX: this fails
        ASSERT_LE(0, result = av_seek_frame(fmt, -1, fmt->duration, 0));
        read_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

TEST(AVFormat, seek_test_fails2) 
{
        int result;
        AVFormatContext* fmt;
        ASSERT_EQ(0, result = av_open_input_file(&fmt, 
"\\\\mediafiles\\public\\support\\demo\\PlanetEarth.Jungles.1080i.DivX.AC3.mkv.mp4",
 NULL, 0, NULL));
        ASSERT_LE(0, result = av_find_stream_info(fmt));

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

        // 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_all_streams_after_seek(fmt);

        av_close_input_stream(fmt);
}

Reply via email to