[MPlayer-dev-eng] [PATCH] seekbar support for mp4 files
Reimar =?UTF8?Q?D=F6ffinger?=
Reimar.Doeffinger at stud.uni-karlsruhe.de
Tue Dec 21 11:36:49 CET 2004
Hi,
> >YOu should not set movi_start and especially movi_end if you don't know
> >the values, as far as I know MPlayer might stop playing when it gets
> >beyond movi_end.
> >
> Oh, as a matter of fact this problem shows up the other way around -
> with my patch (and without it as well), when you reach the end of a MP4
> file, mplayer will stop playing (and quit correctly), but if you seek
> past the end of the file, it will wrap to the beginning. I will check if
> there is an easy way to get correct values for movi_start and movi_end,
> but IMVHO the MOV/MP4 demuxer was very quickly hacked and lacks easy
> access to those features. Providing dummy values for movi_start and
> movi_end is yet better than providing no values at all, still (at least
> it allows the seekbar to work in the GUI, and also shows the total
> running time of the movie...)
Providing dummy values is not acceptable IMHO as they are used outside of the demuxer and can thus break any code outside of it.
If they aren't known they should be set to the same value or 0.
> >Instead to OSD should be fixed to use demuxer_get_percent_pos instead of
> >these values I think.
> >
> I did not understand at all why there was :
> - a "get_percent_pos" function to display the %age in the OSD
> - a "get total time" function to display the total time in the OSD
> - things like movi_start, movi_end and pos to display the seek bar in
> the OSD
That last one was probably a left-over from earlier implementations. That happens often in MPlayer...
> I suppose there are very good reasons for that :-)
> But actually, with "current time" and "total time" all those things can
> be calculated without extra parameters. OTOH, if the running time of a
> file can't be calculated easily, but we know its length (in bytes) and
> the current position, we can calculate a rough percentage and display
> the OSD seek bar ... I suppose that this reason is the rationale behind
> those discrepancies. But I would quite appreciate if the authors of the
> original code would enlighten me ?
I am not the original author, certainly not, but that guessing fallback can be done by the demuxer, there even is a special return value for that. So
no reason to do it in mplayer.c, not to mention that this will cause a inconsistency between the OSD seekbar and that of some Guis.
Please have a look at the attached patch. This is how I think it should be done.
Greetings,
Reimar Döffinger
-------------- next part --------------
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.818
diff -u -r1.818 mplayer.c
--- mplayer.c 10 Dec 2004 23:04:54 -0000 1.818
+++ mplayer.c 21 Dec 2004 10:27:27 -0000
@@ -3747,11 +3747,10 @@
#else
if( 1 ) { // Let the compiler optimize this out
#endif
- int len=((demuxer->movi_end-demuxer->movi_start)>>8);
- if (len>0 && sh_video){
+ if (sh_video){
osd_visible=sh_video->fps; // 1 sec
vo_osd_progbar_type=0;
- vo_osd_progbar_value=(demuxer->filepos-demuxer->movi_start)/len;
+ vo_osd_progbar_value=demuxer_get_percent_pos(demuxer)*256/100;
vo_osd_changed(OSDTYPE_PROGBAR);
}
}
Index: libmpdemux/demux_mov.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_mov.c,v
retrieving revision 1.109
diff -u -r1.109 demux_mov.c
--- libmpdemux/demux_mov.c 15 Nov 2004 15:04:57 -0000 1.109
+++ libmpdemux/demux_mov.c 21 Dec 2004 10:27:28 -0000
@@ -1829,15 +1829,28 @@
return pts;
}
+/**
+ * \brief return the mov track that belongs to a demuxer stream
+ * \param ds the demuxer stream, may be NULL
+ * \return the mov track info structure belonging to the stream,
+ * NULL if not found
+ */
+static mov_track_t *stream_track(mov_priv_t *priv, demux_stream_t *ds) {
+ if (ds && ds->id>=0 && ds->id < priv->track_db)
+ return priv->tracks[ds->id];
+ return NULL;
+}
+
void demux_seek_mov(demuxer_t *demuxer,float pts,int flags){
mov_priv_t* priv=demuxer->priv;
demux_stream_t* ds;
+ mov_track_t* trak;
// printf("MOV seek called %5.3f flag=%d \n",pts,flags);
ds=demuxer->video;
- if(ds && ds->id>=0 && ds->id<priv->track_db){
- mov_track_t* trak=priv->tracks[ds->id];
+ trak = stream_track(priv, ds);
+ if(trak){
//if(flags&2) pts*=(float)trak->length/(float)trak->timescale;
//if(!(flags&1)) pts+=ds->pts;
pts=ds->pts=mov_seek_track(trak,pts,flags);
@@ -1845,8 +1858,8 @@
}
ds=demuxer->audio;
- if(ds && ds->id>=0 && ds->id<priv->track_db){
- mov_track_t* trak=priv->tracks[ds->id];
+ trak = stream_track(priv, ds);
+ if(trak){
//if(flags&2) pts*=(float)trak->length/(float)trak->timescale;
//if(!(flags&1)) pts+=ds->pts;
ds->pts=mov_seek_track(trak,pts,flags);
@@ -1854,3 +1867,32 @@
}
+int demux_mov_control(demuxer_t *demuxer, int cmd, void *arg){
+ mov_track_t* track;
+
+ // try the video track
+ track = stream_track(demuxer->priv, demuxer->video);
+ if (!track || !track->length)
+ // otherwise try to get the info from the audio track
+ track = stream_track(demuxer->priv, demuxer->audio);
+ if (!track || !track->length)
+ return DEMUXER_CTRL_DONTKNOW;
+
+ switch(cmd) {
+ case DEMUXER_CTRL_GET_TIME_LENGTH:
+ if (!track->timescale)
+ return DEMUXER_CTRL_DONTKNOW;
+ *((unsigned long *)arg) = track->length / track->timescale;
+ return DEMUXER_CTRL_OK;
+ case DEMUXER_CTRL_GET_PERCENT_POS:
+ {
+ long pos = track->pos;
+ if (track->durmap_size>=1)
+ pos *= track->durmap[0].dur;
+ *((int *)arg)=(int)(100 * pos / track->length);
+ return DEMUXER_CTRL_OK;
+ }
+ }
+ return DEMUXER_CTRL_NOTIMPL;
+}
+
Index: libmpdemux/demuxer.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.c,v
retrieving revision 1.177
diff -u -r1.177 demuxer.c
--- libmpdemux/demuxer.c 15 Dec 2004 18:39:51 -0000 1.177
+++ libmpdemux/demuxer.c 21 Dec 2004 10:27:28 -0000
@@ -1642,6 +1642,7 @@
extern int demux_ogg_control(demuxer_t *demuxer, int cmd, void *arg);
extern int demux_real_control(demuxer_t *demuxer, int cmd, void *arg);
extern int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg);
+extern int demux_mov_control(demuxer_t *demuxer, int cmd, void *arg);
int demux_control(demuxer_t *demuxer, int cmd, void *arg) {
switch(demuxer->type) {
@@ -1678,6 +1679,8 @@
case DEMUXER_TYPE_LAVF:
return demux_lavf_control(demuxer, cmd, arg);
#endif
+ case DEMUXER_TYPE_MOV:
+ return demux_mov_control(demuxer, cmd, arg);
default:
return DEMUXER_CTRL_NOTIMPL;
More information about the MPlayer-dev-eng
mailing list