mirror of
https://github.com/mpv-player/mpv
synced 2024-11-18 21:16:10 +01:00
demuxer_control(), percent position and time length query implemented in
asf, avi, mpeg demuxers. patch by Balatoni Denes <pnis@coder.hu> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8209 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
4bda81ad16
commit
422b0d2a4c
@ -48,6 +48,8 @@ int asf_scrambling_h=1;
|
||||
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 @@ while(!stream_eof(demuxer->stream)){
|
||||
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;
|
||||
|
@ -106,6 +106,7 @@ typedef struct {
|
||||
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))
|
||||
|
@ -35,7 +35,8 @@ extern int asf_scrambling_h;
|
||||
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 @@ void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
||||
//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 @@ void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -552,6 +552,15 @@ demuxer_t* demux_open_avi(demuxer_t* demuxer){
|
||||
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 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
||||
}
|
||||
|
||||
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 @@ void demux_close_avi(demuxer_t *demuxer) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +403,28 @@ void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1245,3 +1245,41 @@ char* demux_info_get(demuxer_t *demuxer, char *opt) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ extern int pts_from_bps;
|
||||
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);
|
||||
|
@ -1239,6 +1239,7 @@ if(identify) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user