# HG changeset patch # User arpi # Date 1037418134 0 # Node ID ae5a2ae1c3498f17511d9bf24abc5966e94145b0 # Parent 467ffae428b04beb9d575502dbcb4498b6374508 demuxer_control(), percent position and time length query implemented in asf, avi, mpeg demuxers. patch by Balatoni Denes diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/asfheader.c --- 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; diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/aviheader.h --- 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)) diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/demux_asf.c --- 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; + } +} diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/demux_avi.c --- 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; + } +} diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/demux_mpg.c --- 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; + } +} diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/demuxer.c --- 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; +} + diff -r 467ffae428b0 -r ae5a2ae1c349 libmpdemux/demuxer.h --- 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); diff -r 467ffae428b0 -r ae5a2ae1c349 mplayer.c --- 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; }