[MPlayer-dev-eng] [PATCH] seekbar support for mp4 files

Reimar =?UTF8?Q?D=F6ffinger?= Reimar.Doeffinger at stud.uni-karlsruhe.de
Tue Dec 21 12:22:09 CET 2004


Hi,
[...]
> Please have a look at the attached patch. This is how I think it should be done.

With some more extra code to avoid breaking some demuxers that don't implement GET_PERCENT_POS but have movi_start and movi_end to something useful (seem to be quite a few).

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 11:19:10 -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 11:19:10 -0000
@@ -1693,6 +1693,18 @@
     return 1;
 }
 
+/**
+ * \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;
+}
+
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
@@ -1703,8 +1715,8 @@
     int x;
     off_t pos;
     
-    if(ds->id<0 || ds->id>=priv->track_db) return 0;
-    trak=priv->tracks[ds->id];
+    trak = stream_track(priv, ds);
+    if (!trak) return 0;
 
 if(trak->samplesize){
     // read chunk:
@@ -1832,12 +1844,13 @@
 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 11:19:10 -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;
@@ -1695,10 +1698,11 @@
 }
 
 int demuxer_get_percent_pos(demuxer_t *demuxer){     
-    int ans;     
-    if (demux_control(demuxer, DEMUXER_CTRL_GET_PERCENT_POS, &ans)<=0)  {
-        ans=0;     
-    }
+    int ans = 0;
+    int res = demux_control(demuxer, DEMUXER_CTRL_GET_PERCENT_POS, &ans);
+    int len = (demuxer->movi_end - demuxer->movi_start) / 100;
+    if (res == DEMUXER_CTRL_NOTIMPL && len > 0)
+      ans = (demuxer->filepos - demuxer->movi_start) / len;
     if (ans>100 || ans<0) ans=0;
     return ans;
 }


More information about the MPlayer-dev-eng mailing list