[FFmpeg-devel] [Hack/rfc] Fix seeking with timestamps wrapping

Etienne Buira etienne.buira.lists at free.fr
Sun Jul 3 10:38:36 CEST 2011


Hi all.

Currently, with a file that has timestamps wrapped, it is not possible
to seek with lavf.

On the user side, that means that ffmpeg -ss -i wrapfile will error out,
and that mplayer -demuxer lavf will exit (eof reported) at every seek
request.

This is due to the if (ts_min>ts_max) in
libavformat/utils.c:av_gen_search().

The attached patch permits to seek in such files.
However, it is breaking seek-lavf_nut in a way I don't understand
(tests/data/fate/seek-lavf_nut.err exists but is empty, and
seek-lavf_nut is empty). I'd really like if someone could look at that.
I also don't know how bad it is to ignore AVSEEK_FLAG_BACKWARD.

BTW, it seems reporting ts_max (@ end of av_gen_search) is based on
wrong value (pos_MIN).

BTW2, does someone knows how to run a particular fate test? I tried make
fate-seek-lavf_nut but it does all fate.

Regards.
-------------- next part --------------
diff --git a/libavformat/utils.c b/libavformat/utils.c
index cfc70ec..3a7ac79 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1578,6 +1578,8 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
 
     av_dlog(s, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
 
+    pos = avio_tell(s->pb);
+
     if(ts_min == AV_NOPTS_VALUE){
         pos_min = s->data_offset;
         ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
@@ -1611,7 +1613,15 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
     }
 
     if(ts_min > ts_max){
+        if (s->bit_rate) {
+            int64_t offset = target_ts - read_timestamp(s, stream_index, &pos, INT64_MAX);
+            pos += av_rescale(offset*s->bit_rate/8,
+                              s->streams[stream_index]->time_base.num,
+                              s->streams[stream_index]->time_base.den);
+            pos_min = pos_max = pos_limit = pos;
+        } else {
         return -1;
+        }
     }else if(ts_min == ts_max){
         pos_limit= pos_min;
     }
diff --git a/tests/ref/seek/lavf_asf b/tests/ref/seek/lavf_asf
index 757fd0e..81f32b2 100644
--- a/tests/ref/seek/lavf_asf
+++ b/tests/ref/seek/lavf_asf
@@ -7,7 +7,8 @@ ret: 0         st: 0 flags:0  ts: 0.788000
 ret: 0         st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:   209
 ret: 0         st: 0 flags:1  ts:-0.317000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    575 size: 28487
-ret:-1         st: 1 flags:0  ts: 2.577000
+ret: 0         st: 1 flags:0  ts: 2.577000
+ret:-EOF
 ret:-1         st: 1 flags:1  ts: 1.471000
 ret: 0         st:-1 flags:0  ts: 0.365002
 ret: 0         st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147775 size:   209
@@ -19,7 +20,8 @@ ret: 0         st: 0 flags:1  ts: 1.048000
 ret: 0         st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:   209
 ret: 0         st: 1 flags:0  ts:-0.058000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:  29375 size:   208
-ret:-1         st: 1 flags:1  ts: 2.836000
+ret: 0         st: 1 flags:1  ts: 2.836000
+ret:-EOF
 ret: 0         st:-1 flags:0  ts: 1.730004
 ret: 0         st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:   209
 ret: 0         st:-1 flags:1  ts: 0.624171
@@ -28,7 +30,8 @@ ret: 0         st: 0 flags:0  ts:-0.482000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    575 size: 28487
 ret: 0         st: 0 flags:1  ts: 2.413000
 ret: 0         st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:   209
-ret:-1         st: 1 flags:0  ts: 1.307000
+ret: 0         st: 1 flags:0  ts: 1.307000
+ret:-EOF
 ret: 0         st: 1 flags:1  ts: 0.201000
 ret: 0         st: 1 flags:1 dts: 0.183000 pts: 0.183000 pos:  70975 size:   209
 ret: 0         st:-1 flags:0  ts:-0.904994
@@ -39,7 +42,8 @@ ret: 0         st: 0 flags:0  ts: 0.883000
 ret: 0         st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:   209
 ret: 0         st: 0 flags:1  ts:-0.222000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    575 size: 28487
-ret:-1         st: 1 flags:0  ts: 2.672000
+ret: 0         st: 1 flags:0  ts: 2.672000
+ret:-EOF
 ret:-1         st: 1 flags:1  ts: 1.566000
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147775 size:   209


More information about the ffmpeg-devel mailing list