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;
};