[MPlayer-dev-eng] [rff:patch] streamposition & length with demuxer_control

Balatoni Denes pnis at coder.hu
Thu Nov 7 00:18:15 CET 2002


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

So this is a first attempt. 3 demuxer_control commands (length,stream 
position), demux_avi, asf and mpg has this.  

What doesn't work, and I don't know how it should be done:
- - length of mpg without bitrate is just guessed
- - length of asf wma/video - the packet rate is different, but how should it 
be found automatically?

Also in demux_avi the number of frames is needed at 4 different places,
so I made a macro for that.

And I added "S:  x"to the display for streamposition feedback.
Please tell me what you think should be changed, or any ideas.

Denes

- -- 
"Use the source Luke !"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9yaM3aQToeq3jgogRAmyyAJ43CxHxB+yinFQzFKTelAUGDXaCMgCeKRNH
KDV0mjtpRUIWVxN383TykOE=
=XrA8
-----END PGP SIGNATURE-----
-------------- next part --------------
diff -Naur main.original/libmpdemux/Makefile main/libmpdemux/Makefile
--- main.original/libmpdemux/Makefile	Wed Oct 23 20:20:13 2002
+++ main/libmpdemux/Makefile	Thu Nov  7 00:07:15 2002
@@ -3,7 +3,7 @@
 
 include ../config.mak
 
-SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_pva.c demux_viv.c demuxer.c dvdauth.c dvdnav_stream.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c demux_bmp.c cdda.c demux_rawaudio.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_oss.c audio_in.c demux_smjpeg.c
+SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_pva.c demux_viv.c demuxer.c demuxer_convenience.c dvdauth.c dvdnav_stream.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c demux_bmp.c cdda.c demux_rawaudio.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_oss.c audio_in.c demux_smjpeg.c
 ifeq ($(STREAMING),yes)
 SRCS += asf_streaming.c url.c http.c network.c asf_mmst_streaming.c
 ifeq ($(STREAMING_LIVE_DOT_COM),yes)
diff -Naur main.original/libmpdemux/demux_asf.c main/libmpdemux/demux_asf.c
--- main.original/libmpdemux/demux_asf.c	Sun Sep 22 04:33:26 2002
+++ main/libmpdemux/demux_asf.c	Thu Nov  7 00:07:15 2002
@@ -392,3 +392,28 @@
 
 }
 
+int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){
+    demux_stream_t *d_audio=demuxer->audio;
+    demux_stream_t *d_video=demuxer->video;
+    sh_audio_t *sh_audio=d_audio->sh;
+    sh_video_t *sh_video=d_video->sh;
+    float p_rate=(sh_video) ? 10:4.5 ; // packets / sec
+
+    switch(cmd) {
+	case DEMUXER_CTRL_GET_PERCENT_LENGTH:
+	    *((unsigned long *)arg)=100;
+	    return DEMUXER_CTRL_OK;
+	    
+	case DEMUXER_CTRL_GET_TIME_LENGTH:
+	    *((unsigned long *)arg)=(demuxer->movi_end-demuxer->movi_start)/asf_packetsize/p_rate;
+	    return DEMUXER_CTRL_OK;
+
+	case DEMUXER_CTRL_GET_PERCENT_POS:
+	    if (demuxer->movi_end==demuxer->movi_start) *((unsigned long *)arg)=0; 
+    	    else *((int *)arg)=(int)(demuxer->filepos/((demuxer->movi_end-demuxer->movi_start)/100));
+	    return DEMUXER_CTRL_OK;
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
+}
diff -Naur main.original/libmpdemux/demux_avi.c main/libmpdemux/demux_avi.c
--- main.original/libmpdemux/demux_avi.c	Sat Nov  2 22:52:48 2002
+++ main/libmpdemux/demux_avi.c	Thu Nov  7 00:08:03 2002
@@ -14,6 +14,12 @@
 
 #include "aviheader.h"
 
+#define NUMBEROFFRAMES   (int)(((demuxer->movi_end-demuxer->movi_start- \
+				priv->idx_size*8-sh_audio->audio.dwLength)/ \
+				(float)sh_video->i_bps)*(float)sh_video->fps) 
+
+
+
 // PTS:  0=interleaved  1=BPS-based
 int pts_from_bps=1;
 
@@ -435,6 +441,7 @@
     sh_audio_t *sh_audio=NULL;
     sh_video_t *sh_video=NULL;
     avi_priv_t* priv=malloc(sizeof(avi_priv_t));
+    long total;
 
   // priv struct:
   priv->avi_audio_pts=priv->avi_video_pts=0.0f;
@@ -548,10 +555,19 @@
   sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
   sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
   // calculating video bitrate:
+  
+  if((total=sh_video->video.dwLength)<=1){
+    // bad video header, try to get it from audio
+    if(sh_audio) total=sh_video->fps*sh_audio->audio.dwLength/sh_audio->wf->nAvgBytesPerSec;
+        if(total<=1){
+		mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo);
+        	total=1;
+        }
+  }  
   sh_video->i_bps=demuxer->movi_end-demuxer->movi_start-priv->idx_size*8;
   if(sh_audio) sh_video->i_bps-=sh_audio->audio.dwLength;
   mp_msg(MSGT_DEMUX,MSGL_V,"AVI video length=%lu\n",(unsigned long)sh_video->i_bps);
-  sh_video->i_bps=((float)sh_video->i_bps/(float)sh_video->video.dwLength)*sh_video->fps;
+  sh_video->i_bps=((float)sh_video->i_bps/(float)total)*sh_video->fps;
   mp_msg(MSGT_DEMUX,MSGL_INFO,"VIDEO:  [%.4s]  %ldx%ld  %dbpp  %4.2f fps  %5.1f kbps (%4.1f kbyte/s)\n",
     (char *)&sh_video->bih->biCompression,
     sh_video->bih->biWidth,
@@ -587,17 +603,7 @@
       }
       
       if(flags&2){
-        // float 0..1
-	int total=sh_video->video.dwLength;
-	if(total<=1){
-	    // bad video header, try to get it from audio
-	    if(sh_audio) total=sh_video->fps*sh_audio->audio.dwLength/sh_audio->wf->nAvgBytesPerSec;
-	    if(total<=1){
-              mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo);
-	      total=0;
-	    }
-	}
-	rel_seek_frames=rel_seek_secs*total;
+	rel_seek_frames=rel_seek_secs*NUMBEROFFRAMES;
       }
     
       priv->skip_video_frames=0;
@@ -783,4 +789,33 @@
   if(priv->idx_size > 0)
     free(priv->idx);
   free(priv);
+}
+
+
+int demux_avi_control(demuxer_t *demuxer,int cmd, void *arg){
+    avi_priv_t *priv=demuxer->priv;
+    demux_stream_t *d_audio=demuxer->audio;
+    demux_stream_t *d_video=demuxer->video;
+    sh_audio_t *sh_audio=d_audio->sh;
+    sh_video_t *sh_video=d_video->sh;
+
+
+
+    switch(cmd) {
+	case DEMUXER_CTRL_GET_PERCENT_LENGTH:
+	    *((unsigned long *)arg)=100;
+	    return DEMUXER_CTRL_OK;
+	    
+	case DEMUXER_CTRL_GET_TIME_LENGTH:
+
+    	    *((unsigned long *)arg)=NUMBEROFFRAMES/sh_video->fps;
+	    return DEMUXER_CTRL_OK;
+
+	case DEMUXER_CTRL_GET_PERCENT_POS:
+	    *((int *)arg)=(int)(d_video->pack_no*100/NUMBEROFFRAMES);
+	    return DEMUXER_CTRL_OK;
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
 }
diff -Naur main.original/libmpdemux/demux_mpg.c main/libmpdemux/demux_mpg.c
--- main.original/libmpdemux/demux_mpg.c	Wed Oct  9 00:57:39 2002
+++ main/libmpdemux/demux_mpg.c	Thu Nov  7 00:07:15 2002
@@ -404,3 +404,31 @@
 
 }
 
+int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
+    demux_stream_t *d_audio=demuxer->audio;
+    demux_stream_t *d_video=demuxer->video;
+    sh_audio_t *sh_audio=d_audio->sh;
+    sh_video_t *sh_video=d_video->sh;
+
+    switch(cmd) {
+	case DEMUXER_CTRL_GET_PERCENT_LENGTH:
+	    *((unsigned long *)arg)=100;
+	    return DEMUXER_CTRL_OK;
+	    
+	case DEMUXER_CTRL_GET_TIME_LENGTH:
+	    if(!sh_video->i_bps) // unspecified or VBR {
+		*((unsigned long *)arg)=(demuxer->movi_end-demuxer->movi_start)/174300; // 174.3 kbyte/sec
+	    else
+        	*((unsigned long *)arg)=(demuxer->movi_end-demuxer->movi_start)/sh_video->i_bps;
+	    return DEMUXER_CTRL_OK;
+
+	case DEMUXER_CTRL_GET_PERCENT_POS:
+	    if (demuxer->movi_end==demuxer->movi_start) *((int *)arg)=0;
+    	    else *((int *)arg)=(int)(demuxer->filepos/((demuxer->movi_end-demuxer->movi_start)/100));
+	    
+	    return DEMUXER_CTRL_OK;
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
+}
diff -Naur main.original/libmpdemux/demuxer.c main/libmpdemux/demuxer.c
--- main.original/libmpdemux/demuxer.c	Sat Nov  2 20:52:59 2002
+++ main/libmpdemux/demuxer.c	Thu Nov  7 00:07:15 2002
@@ -1243,3 +1243,22 @@
   return NULL;
 }
 
+extern int demux_mpg_control(demuxer_t *demuxer, int cmd, void *arg);
+extern int demux_asf_control(demuxer_t *demuxer, int cmd, void *arg);
+extern int demux_avi_control(demuxer_t *demuxer, int cmd, void *arg);
+
+int demux_control(demuxer_t *demuxer, int cmd, void *arg) {
+    switch(demuxer->type) {
+	case DEMUXER_TYPE_MPEG_ES:
+	case DEMUXER_TYPE_MPEG_PS:
+	    return demux_mpg_control(demuxer,cmd,arg);
+	case DEMUXER_TYPE_ASF:
+	    return demux_asf_control(demuxer,cmd,arg);
+	case DEMUXER_TYPE_AVI:
+	    return demux_avi_control(demuxer,cmd,arg);
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
+}
+
diff -Naur main.original/libmpdemux/demuxer.h main/libmpdemux/demuxer.h
--- main.original/libmpdemux/demuxer.h	Sat Nov  2 01:45:12 2002
+++ main/libmpdemux/demuxer.h	Thu Nov  7 00:07:15 2002
@@ -8,6 +8,7 @@
 #define MAX_PACK_BYTES 0x800000
 #endif
 
+
 #define DEMUXER_TYPE_UNKNOWN 0
 #define DEMUXER_TYPE_MPEG_ES 1
 #define DEMUXER_TYPE_MPEG_PS 2
@@ -50,6 +51,13 @@
 #define DEMUXER_TIME_BPS 3
 
 
+// DEMUXER control commands/answers
+#define DEMUXER_CTRL_OK 0
+#define DEMUXER_CTRL_NOTIMPL 666
+#define DEMUXER_CTRL_GET_TIME_LENGTH 1
+#define DEMUXER_CTRL_GET_PERCENT_LENGTH 2
+#define DEMUXER_CTRL_GET_PERCENT_POS 3
+
 // Holds one packet/frame/whatever
 typedef struct demux_packet_st {
   int len;
@@ -234,5 +242,6 @@
 int demux_info_add(demuxer_t *demuxer, char *opt, char *param);
 char* demux_info_get(demuxer_t *demuxer, char *opt);
 int demux_info_print(demuxer_t *demuxer);
+int demux_control(demuxer_t *demuxer, int cmd, void *arg);
 
 #endif
diff -Naur main.original/libmpdemux/demuxer_convenience.c main/libmpdemux/demuxer_convenience.c
--- main.original/libmpdemux/demuxer_convenience.c	Thu Jan  1 01:00:00 1970
+++ main/libmpdemux/demuxer_convenience.c	Thu Nov  7 00:07:15 2002
@@ -0,0 +1,23 @@
+#include "stream.h"
+#include "demuxer.h"
+#include "stheader.h"
+#include "mf.h"
+
+
+unsigned long demuxer_get_time_length(demuxer_t *demuxer){     
+    unsigned long get_time_ans;     
+    if (demux_control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH,(void *)&get_time_ans)!=DEMUXER_CTRL_OK)  {
+        get_time_ans=0;     
+    }
+    return get_time_ans;
+}
+
+int demuxer_get_percent_pos(demuxer_t *demuxer){     
+    int ans;     
+    if (demux_control(demuxer, DEMUXER_CTRL_GET_PERCENT_POS, &ans)!=DEMUXER_CTRL_OK)  {
+        ans=0;     
+    }
+    if (ans>100 || ans<0) ans=0;
+    return ans;
+}
+
diff -Naur main.original/libmpdemux/demuxer_convenience.h main/libmpdemux/demuxer_convenience.h
--- main.original/libmpdemux/demuxer_convenience.h	Thu Jan  1 01:00:00 1970
+++ main/libmpdemux/demuxer_convenience.h	Thu Nov  7 00:07:15 2002
@@ -0,0 +1,11 @@
+#ifndef _DEMUXER_CONVENIENCE
+#define _DEMUXER_CONVENIENCE
+#include "demuxer.h"
+
+extern unsigned long demuxer_get_time_length(demuxer_t *demuxer);
+extern int demuxer_get_percent_pos(demuxer_t *demuxer);
+
+
+
+#endif
+
diff -Naur main.original/mplayer.c main/mplayer.c
--- main.original/mplayer.c	Sun Nov  3 03:02:08 2002
+++ main/mplayer.c	Thu Nov  7 00:07:15 2002
@@ -123,6 +123,7 @@
 #include "libmpdemux/stream.h"
 #include "libmpdemux/demuxer.h"
 #include "libmpdemux/stheader.h"
+#include "libmpdemux/demuxer_convenience.h"
 //#include "parse_es.h"
 
 #include "libmpcodecs/dec_audio.h"
@@ -1178,6 +1179,7 @@
     mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_AUDIO_RATE=%d\n", sh_audio->samplerate);
     mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_AUDIO_NCH=%d\n", sh_audio->channels);
   }
+  mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_LENGTH=%ld\n", demuxer_get_time_length(demuxer));
   goto goto_next_file;
 }
 
@@ -1454,7 +1456,8 @@
 
 if(!sh_video) {
   // handle audio-only case:
-  if(!quiet) mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%6.1f %4.1f%% %d%%   \r"
+  if(!quiet) mp_msg(MSGT_AVSYNC,MSGL_STATUS,"S:%3d A:%6.1f %4.1f%% %d%%   \r"
+		    ,demuxer_get_percent_pos(demuxer)
 		    ,sh_audio->delay-audio_out->get_delay()
 		    ,(sh_audio->delay>0.5)?100.0*audio_time_usage/(double)sh_audio->delay:0
 		    ,cache_fill_status
@@ -1745,7 +1748,8 @@
         else
           max_pts_correction=sh_video->frametime*0.10; // +-10% of time
 	if(!frame_time_remaining){ sh_audio->delay+=x; c_total+=x;} // correction
-        if(!quiet) mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%6.1f V:%6.1f A-V:%7.3f ct:%7.3f  %3d/%3d  %2d%% %2d%% %4.1f%% %d %d %d%%\r",
+        if(!quiet) mp_msg(MSGT_AVSYNC,MSGL_STATUS,"S:%3d A:%6.1f V:%6.1f A-V:%7.3f ct:%7.3f  %3d/%3d  %2d%% %2d%% %4.1f%% %d %d %d%%\r",
+	  demuxer_get_percent_pos(demuxer),    
 	  a_pts-audio_delay-delay,v_pts,AV_delay,c_total,
           (int)sh_video->num_frames,(int)sh_video->num_frames_decoded,
           (sh_video->timer>0.5)?(int)(100.0*video_time_usage*playback_speed/(double)sh_video->timer):0,
@@ -1762,7 +1766,9 @@
     // No audio:
     
     if(!quiet)
-      mp_msg(MSGT_AVSYNC,MSGL_STATUS,"V:%6.1f  %3d  %2d%% %2d%% %4.1f%% %d %d %d%%\r",d_video->pts,
+      mp_msg(MSGT_AVSYNC,MSGL_STATUS,"S:%3d V:%6.1f  %3d  %2d%% %2d%% %4.1f%% %d %d %d%%\r",
+        demuxer_get_percent_pos(demuxer),
+	d_video->pts,
         (int)sh_video->num_frames,
         (sh_video->timer>0.5)?(int)(100.0*video_time_usage/(double)sh_video->timer):0,
         (sh_video->timer>0.5)?(int)(100.0*vout_time_usage/(double)sh_video->timer):0,


More information about the MPlayer-dev-eng mailing list