changeset 8208:ae5a2ae1c349

demuxer_control(), percent position and time length query implemented in asf, avi, mpeg demuxers. patch by Balatoni Denes <pnis@coder.hu>
author arpi
date Sat, 16 Nov 2002 03:42:14 +0000
parents 467ffae428b0
children 51ed4c00f15b
files libmpdemux/asfheader.c libmpdemux/aviheader.h libmpdemux/demux_asf.c libmpdemux/demux_avi.c libmpdemux/demux_mpg.c libmpdemux/demuxer.c libmpdemux/demuxer.h mplayer.c
diffstat 8 files changed, 146 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/asfheader.c	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/asfheader.c	Sat Nov 16 03:42:14 2002 +0000
@@ -48,6 +48,8 @@
 int asf_scrambling_w=1;
 int asf_scrambling_b=1;
 int asf_packetsize=0;
+double asf_packetrate=0;
+int asf_movielength=0;
 
 //int i;
 
@@ -214,6 +216,8 @@
       mp_msg(MSGT_HEADER,MSGL_V,"ASF: packets: %d  flags: %d  max_packet_size: %d  min_packet_size: %d  max_bitrate: %d  preroll: %d\n",(int)fileh.num_packets,(int)fileh.flags,(int)fileh.min_packet_size,(int)fileh.max_packet_size,(int)fileh.max_bitrate,(int)fileh.preroll);
       asf_packetsize=fileh.max_packet_size;
       asf_packet=malloc(asf_packetsize); // !!!
+      asf_packetrate=fileh.max_bitrate/8.0/(double)asf_packetsize;
+      asf_movielength=fileh.send_duration/10000000LL;
       break;
     case ASF_GUID_PREFIX_data_chunk: // guid_data_chunk
       demuxer->movi_start=stream_tell(demuxer->stream)+26;
--- a/libmpdemux/aviheader.h	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/aviheader.h	Sat Nov 16 03:42:14 2002 +0000
@@ -106,6 +106,7 @@
   unsigned int pts_corr_bytes;
   unsigned char pts_corrected;
   unsigned char pts_has_video;
+  unsigned int numberofframes;
 } avi_priv_t;
 
 #define AVI_PRIV ((avi_priv_t*)(demuxer->priv))
--- a/libmpdemux/demux_asf.c	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/demux_asf.c	Sat Nov 16 03:42:14 2002 +0000
@@ -35,7 +35,8 @@
 extern int asf_scrambling_w;
 extern int asf_scrambling_b;
 extern int asf_packetsize;
-
+extern double asf_packetrate;
+extern int asf_movielength;
 
 // based on asf file-format doc by Eugene [http://divx.euro.ru]
 
@@ -357,7 +358,7 @@
   //FIXME: reports good or bad to steve@daviesfam.org please
 
   //================= seek in ASF ==========================
-    float p_rate=10; // packets / sec
+    float p_rate=asf_packetrate; // packets / sec
     off_t rel_seek_packs=(flags&2)?	 // FIXME: int may be enough?
 	(rel_seek_secs*(demuxer->movi_end-demuxer->movi_start)/asf_packetsize):
 	(rel_seek_secs*p_rate);
@@ -395,3 +396,25 @@
 
 }
 
+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;
+
+    switch(cmd) {
+	case DEMUXER_CTRL_GET_TIME_LENGTH:
+	    *((unsigned long *)arg)=(unsigned long)(asf_movielength);
+	    return DEMUXER_CTRL_OK;
+
+	case DEMUXER_CTRL_GET_PERCENT_POS:
+	    if (demuxer->movi_end==demuxer->movi_start) {
+		return DEMUXER_CTRL_DONTKNOW;
+	    }
+    	    *((int *)arg)=(int)((demuxer->filepos-demuxer->movi_start)/((demuxer->movi_end-demuxer->movi_start)/100));
+	    return DEMUXER_CTRL_OK;
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
+}
--- a/libmpdemux/demux_avi.c	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/demux_avi.c	Sat Nov 16 03:42:14 2002 +0000
@@ -552,6 +552,15 @@
   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;
+  
+  if((priv->numberofframes=sh_video->video.dwLength)<=1)
+    // bad video header, try to get number of frames from audio
+    if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->wf->nAvgBytesPerSec;
+  if(priv->numberofframes<=1){
+    mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo);
+    priv->numberofframes=0;
+  }          
+ 
   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,
@@ -588,17 +597,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*priv->numberofframes;
       }
     
       priv->skip_video_frames=0;
@@ -785,3 +784,35 @@
     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_TIME_LENGTH:
+    	    if (!priv->numberofframes) return DEMUXER_CTRL_DONTKNOW;
+	    *((unsigned long *)arg)=priv->numberofframes/sh_video->fps;
+	    if (sh_video->video.dwLength<=1) return DEMUXER_CTRL_GUESS;
+	    return DEMUXER_CTRL_OK;
+
+	case DEMUXER_CTRL_GET_PERCENT_POS:
+    	    if (!priv->numberofframes) {
+		if (demuxer->movi_end==demuxer->movi_start) return DEMUXER_CTRL_DONTKNOW;
+		*((int *)arg)=(int)((demuxer->filepos-demuxer->movi_start)/((demuxer->movi_end-demuxer->movi_start)/100));
+		return DEMUXER_CTRL_OK; 
+	    }
+	    *((int *)arg)=(int)(priv->video_pack_no*100/priv->numberofframes);
+	    if (sh_video->video.dwLength<=1) return DEMUXER_CTRL_GUESS;
+	    return DEMUXER_CTRL_OK;
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
+}
--- a/libmpdemux/demux_mpg.c	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/demux_mpg.c	Sat Nov 16 03:42:14 2002 +0000
@@ -403,7 +403,28 @@
           if(i==0x1B3 || i==0x1B8) break; // found it!
           if(!i || !skip_video_packet(d_video)) break; // EOF?
         }
-
-
 }
 
+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_TIME_LENGTH:
+	    if(!sh_video->i_bps)  // unspecified or VBR 
+    		return DEMUXER_CTRL_DONTKNOW;
+	    *((unsigned long *)arg)=(demuxer->movi_end-demuxer->movi_start)/sh_video->i_bps;
+	    return DEMUXER_CTRL_GUESS;
+
+	case DEMUXER_CTRL_GET_PERCENT_POS:
+	    if (demuxer->movi_end==demuxer->movi_start) 
+    		return DEMUXER_CTRL_DONTKNOW;
+    	    *((int *)arg)=(int)((demuxer->filepos-demuxer->movi_start)/((demuxer->movi_end-demuxer->movi_start)/100));
+	    return DEMUXER_CTRL_OK;
+
+	default:
+	    return DEMUXER_CTRL_NOTIMPL;
+    }
+}
--- a/libmpdemux/demuxer.c	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/demuxer.c	Sat Nov 16 03:42:14 2002 +0000
@@ -1245,3 +1245,41 @@
   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;
+    }
+}
+
+
+
+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)<=0)  {
+        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;
+}
+
--- a/libmpdemux/demuxer.h	Sat Nov 16 03:25:37 2002 +0000
+++ b/libmpdemux/demuxer.h	Sat Nov 16 03:42:14 2002 +0000
@@ -50,6 +50,14 @@
 #define DEMUXER_TIME_BPS 3
 
 
+// DEMUXER control commands/answers
+#define DEMUXER_CTRL_NOTIMPL -1
+#define DEMUXER_CTRL_DONTKNOW 0
+#define DEMUXER_CTRL_OK 1
+#define DEMUXER_CTRL_GUESS 2
+#define DEMUXER_CTRL_GET_TIME_LENGTH 10
+#define DEMUXER_CTRL_GET_PERCENT_POS 11
+
 // Holds one packet/frame/whatever
 typedef struct demux_packet_st {
   int len;
@@ -234,5 +242,9 @@
 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
+
+extern unsigned long demuxer_get_time_length(demuxer_t *demuxer);
+extern int demuxer_get_percent_pos(demuxer_t *demuxer);
--- a/mplayer.c	Sat Nov 16 03:25:37 2002 +0000
+++ b/mplayer.c	Sat Nov 16 03:42:14 2002 +0000
@@ -1239,6 +1239,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;
 }