[MPlayer-dev-eng] [PATCH] correct seeking with long audio buffer
Mikulas Patocka
mikulas at artax.karlin.mff.cuni.cz
Mon Aug 2 17:28:48 CEST 2004
Hi
When I configures my OSS sound driver so that it has 2M (12 seconds) large
buffer, mplayer hit a bug that it coudn't seek reliably in streams. When I
pressed back arrow (it should seek 10 seconds backward), it seeked 2
seconds forward.
The problem is caused by the fact, that some demuxers seek according to
current audio position in stream (which is 12 seconds forward from the
position that user sees & hears) and some demuxers seek according to video
position (they behave correctly even with large audio buffer).
The demuxers seeking according to audio position:
mpeg, asf, ogg audio, all the audio-only formats
The demuxers seeking according to video position:
avi, mov
For audio-only demuxers, there not possible to fix the demuxer, the
demuxer has no knowledge of what the user hears now, so it can't seek
according to that information. Seeking according to the position that was
last read from file is very inaccurate.
I fixed the problem by adding another parameter audio_delay to demux_seek
function. If the demuxer is the one seeking by audio offset, demux_seek
subtracts this parameter from the number of seconds to seek.
With this patch, I can reliably seek in all files I have (avi, asf, mov,
mpg, mp3, ogg, wav) with 2M audio buffer size.
Mikulas
-------------- next part --------------
diff -u -r ../MPLAYER-1.0PRE4-BAK2/LIBMPDEMUX/DEMUXER.C ./LIBMPDEMUX/DEMUXER.C
--- ../MPLAYER-1.0PRE4-BAK2/LIBMPDEMUX/DEMUXER.C 2004-04-17 17:46:40.000000000 +0100
+++ ./libmpdemux/demuxer.c 2004-08-02 04:57:27.000000000 +0100
@@ -1462,7 +1462,7 @@
extern void demux_xmms_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
extern void demux_mkv_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags,float audio_delay){
demux_stream_t *d_audio=demuxer->audio;
demux_stream_t *d_video=demuxer->video;
sh_audio_t *sh_audio=d_audio->sh;
@@ -1496,6 +1496,21 @@
#endif
switch(demuxer->file_format){
+ case DEMUXER_TYPE_H264_ES:
+ case DEMUXER_TYPE_MPEG4_ES:
+ case DEMUXER_TYPE_MPEG_ES:
+ case DEMUXER_TYPE_MPEG_PS:
+ case DEMUXER_TYPE_MPEG_TY:
+ case DEMUXER_TYPE_ASF:
+ case DEMUXER_TYPE_AUDIO:
+ case DEMUXER_TYPE_RAWAUDIO:
+#ifdef HAVE_OGGVORBIS
+ case DEMUXER_TYPE_OGG:
+#endif
+ if (!flags) rel_seek_secs -= audio_delay;
+}
+
+switch(demuxer->file_format){
#ifdef HAVE_LIBDV095
case DEMUXER_TYPE_RAWDV:
diff -u -r ../MPLAYER-1.0PRE4-BAK2/LIBMPDEMUX/DEMUXER.H ./LIBMPDEMUX/DEMUXER.H
--- ../MPLAYER-1.0PRE4-BAK2/LIBMPDEMUX/DEMUXER.H 2004-04-12 15:19:12.000000000 +0100
+++ ./libmpdemux/demuxer.h 2004-08-02 04:38:04.000000000 +0100
@@ -262,7 +262,7 @@
}
demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid,char* filename);
-int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
+int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags,float audio_delay);
demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd);
// AVI demuxer params:
diff -u -r ../MPLAYER-1.0PRE4-BAK2/LIBMPDEMUX/DEMUX_DEMUXERS.C ./LIBMPDEMUX/DEMUX_DEMUXERS.C
--- ../MPLAYER-1.0PRE4-BAK2/LIBMPDEMUX/DEMUX_DEMUXERS.C 2003-03-27 21:40:50.000000000 +0100
+++ ./libmpdemux/demux_demuxers.c 2004-08-02 04:45:31.000000000 +0100
@@ -63,13 +63,13 @@
priv->sd->stream->eof = 0;
// Seek video
- demux_seek(priv->vd,rel_seek_secs,flags);
+ demux_seek(priv->vd,rel_seek_secs,flags,0);
// Get the new pos
pos = demuxer->video->pts;
if(priv->ad != priv->vd) {
sh_audio_t* sh = (sh_audio_t*)demuxer->audio->sh;
- demux_seek(priv->ad,pos,1);
+ demux_seek(priv->ad,pos,1,0);
// In case the demuxer don't set pts
if(!demuxer->audio->pts)
demuxer->audio->pts = pos-((ds_tell_pts(demuxer->audio)-sh->a_in_buffer_len)/(float)sh->i_bps);
@@ -77,7 +77,7 @@
}
if(priv->sd != priv->vd)
- demux_seek(priv->sd,pos,1);
+ demux_seek(priv->sd,pos,1,0);
}
diff -u -r ../MPLAYER-1.0PRE4-BAK2/MENCODER.C ./MENCODER.C
--- ../MPLAYER-1.0PRE4-BAK2/MENCODER.C 2004-04-17 17:46:40.000000000 +0100
+++ ./mencoder.c 2004-08-02 04:35:32.000000000 +0100
@@ -1047,12 +1047,12 @@
else
sscanf(seek_to_sec, "%f", &d);
- demux_seek(demuxer, d, 1);
+ demux_seek(demuxer, d, 1, 0);
// there is 2 way to handle the -ss option in 3-pass mode:
// > 1. do the first pass for the whole file, and use -ss for 2nd/3rd pases only
// > 2. do all the 3 passes with the same -ss value
// this line enables behaviour 1. (and kills 2. at the same time):
-// if(demuxer2) demux_seek(demuxer2, d, 1);
+// if(demuxer2) demux_seek(demuxer2, d, 1, 0);
}
if (out_file_format == MUXER_TYPE_MPEG)
diff -u -r ../MPLAYER-1.0PRE4-BAK2/MPLAYER.C ./MPLAYER.C
--- ../MPLAYER-1.0PRE4-BAK2/MPLAYER.C 2004-08-02 04:20:46.000000000 +0100
+++ ./mplayer.c 2004-08-02 04:36:24.000000000 +0100
@@ -3385,7 +3385,7 @@
if(rel_seek_secs || abs_seek_pos){
current_module="seek";
- if(demux_seek(demuxer,rel_seek_secs,abs_seek_pos)){
+ if(demux_seek(demuxer,rel_seek_secs,abs_seek_pos,sh_audio?audio_out->get_delay()*playback_speed:0)){
// success:
/* FIXME there should be real seeking for vobsub */
if(sh_video) sh_video->pts=d_video->pts;
More information about the MPlayer-dev-eng
mailing list