# HG changeset patch # User arpi # Date 1042935714 0 # Node ID d00997f12257645ed30a0ab45aade263b142cddf # Parent ebc368360ea22ebf07f1a685db9ce996ba0efa6e extension-based filetype detection for headerless files (mp3 vs mpeg, etc) inspired by patch by Fabian Franz diff -r ebc368360ea2 -r d00997f12257 DOCS/mplayer.1 --- a/DOCS/mplayer.1 Sat Jan 18 21:09:22 2003 +0000 +++ b/DOCS/mplayer.1 Sun Jan 19 00:21:54 2003 +0000 @@ -596,6 +596,13 @@ Do not use average byte/\:sec value for A\-V sync (AVI). Helps with some AVI files with broken header. .TP +.B \-noextbased +Disables filename-extension based demuxer selection. +By default, when file type (demuxer) cannot be detected reliably +(the file has no header or it is not reliable enough), the filename +extension is used to select demuxer. It always falls back to content-based +demuxer selection. +.TP .B \-passwd (see \-user option too) Specify password for http authentication. .TP diff -r ebc368360ea2 -r d00997f12257 cfg-common.h --- a/cfg-common.h Sat Jan 18 21:09:22 2003 +0000 +++ b/cfg-common.h Sun Jan 19 00:21:54 2003 +0000 @@ -83,6 +83,8 @@ { "demuxer", &demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, NULL }, { "audio-demuxer", &audio_demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, NULL }, { "sub-demuxer", &sub_demuxer_type, CONF_TYPE_INT, CONF_RANGE, 1, DEMUXER_TYPE_MAX, NULL }, + { "extbased", &extension_parsing, CONF_TYPE_FLAG, 0, 0, 1, NULL }, + { "noextbased", &extension_parsing, CONF_TYPE_FLAG, 0, 1, 0, NULL }, {"mf", mfopts_conf, CONF_TYPE_SUBCONFIG, 0,0,0, NULL}, #ifdef USE_TV diff -r ebc368360ea2 -r d00997f12257 libmpdemux/Makefile --- a/libmpdemux/Makefile Sat Jan 18 21:09:22 2003 +0000 +++ b/libmpdemux/Makefile Sun Jan 19 00:21:54 2003 +0000 @@ -3,7 +3,7 @@ include ../config.mak -SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.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 cue_read.c +SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.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 cue_read.c extension.c ifeq ($(XMMS_PLUGINS),yes) SRCS += demux_xmms.c endif diff -r ebc368360ea2 -r d00997f12257 libmpdemux/demuxer.c --- a/libmpdemux/demuxer.c Sat Jan 18 21:09:22 2003 +0000 +++ b/libmpdemux/demuxer.c Sun Jan 19 00:21:54 2003 +0000 @@ -549,8 +549,9 @@ extern int use_rawaudio; +int extension_parsing=1; // 0=off 1=mixed (used only for unstable formats) -static demuxer_t* demux_open_stream(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id){ +static demuxer_t* demux_open_stream(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id,char* filename){ //int file_format=(*file_format_ptr); @@ -645,6 +646,43 @@ demuxer = NULL; } } +//=============== Try to open as REAL file: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_REAL){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_REAL,audio_id,video_id,dvdsub_id); + if(real_check_file(demuxer)){ + mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"REAL"); + file_format=DEMUXER_TYPE_REAL; + } else { + free_demuxer(demuxer); + demuxer = NULL; + } +} +//=============== Try to open as SMJPEG file: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_SMJPEG){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_SMJPEG,audio_id,video_id,dvdsub_id); + if(smjpeg_check_file(demuxer)){ + mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"SMJPEG"); + file_format=DEMUXER_TYPE_SMJPEG; + } else { + free_demuxer(demuxer); + demuxer = NULL; + } +} + +//=============== Try based on filename EXTENSION: ================= +// Ok. We're over the stable detectable fileformats, the next ones are a bit +// fuzzy. So by default (extension_parsing==1) try extension-based detection +// first: +if(file_format==DEMUXER_TYPE_UNKNOWN && filename && extension_parsing==1){ + file_format=demuxer_type_by_filename(filename); + if(file_format!=DEMUXER_TYPE_UNKNOWN){ + // we like recursion :) + demuxer=demux_open_stream(stream,file_format,audio_id,video_id,dvdsub_id,NULL); + if(demuxer) return demuxer; // done! + file_format=DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing... + } +} + //=============== Try to open as MOV file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){ demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id); @@ -667,17 +705,6 @@ demuxer = NULL; } } -//=============== Try to open as REAL file: ================= -if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_REAL){ - demuxer=new_demuxer(stream,DEMUXER_TYPE_REAL,audio_id,video_id,dvdsub_id); - if(real_check_file(demuxer)){ - mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"REAL"); - file_format=DEMUXER_TYPE_REAL; - } else { - free_demuxer(demuxer); - demuxer = NULL; - } -} //=============== Try to open as FLI file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_FLI){ demuxer=new_demuxer(stream,DEMUXER_TYPE_FLI,audio_id,video_id,dvdsub_id); @@ -732,17 +759,6 @@ demuxer = NULL; } } -//=============== Try to open as SMJPEG file: ================= -if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_SMJPEG){ - demuxer=new_demuxer(stream,DEMUXER_TYPE_SMJPEG,audio_id,video_id,dvdsub_id); - if(smjpeg_check_file(demuxer)){ - mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"SMJPEG"); - file_format=DEMUXER_TYPE_SMJPEG; - } else { - free_demuxer(demuxer); - demuxer = NULL; - } -} #ifdef HAVE_OGGVORBIS //=============== Try to open as Ogg file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_OGG){ @@ -1065,7 +1081,7 @@ extern int hr_mp3_seek; -demuxer_t* demux_open(stream_t *vs,int file_format,int audio_id,int video_id,int dvdsub_id){ +demuxer_t* demux_open(stream_t *vs,int file_format,int audio_id,int video_id,int dvdsub_id,char* filename){ stream_t *as = NULL,*ss = NULL; demuxer_t *vd,*ad = NULL,*sd = NULL; int afmt = 0,sfmt = 0; @@ -1085,18 +1101,18 @@ } } - vd = demux_open_stream(vs,demuxer_type ? demuxer_type : file_format,audio_stream ? -2 : audio_id,video_id, sub_stream ? -2 : dvdsub_id); + vd = demux_open_stream(vs,demuxer_type ? demuxer_type : file_format,audio_stream ? -2 : audio_id,video_id, sub_stream ? -2 : dvdsub_id, filename); if(!vd) return NULL; if(as) { - ad = demux_open_stream(as,audio_demuxer_type ? audio_demuxer_type : afmt,audio_id,-2,-2); + ad = demux_open_stream(as,audio_demuxer_type ? audio_demuxer_type : afmt,audio_id,-2,-2, audio_stream); if(!ad) mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_OpeningAudioDemuxerFailed,audio_stream); else if(ad->audio->sh && ((sh_audio_t*)ad->audio->sh)->format == 0x55) // MP3 hr_mp3_seek=1; // Enable high res seeking } if(ss) { - sd = demux_open_stream(ss,sub_demuxer_type ? sub_demuxer_type : sfmt,-2,-2,dvdsub_id); + sd = demux_open_stream(ss,sub_demuxer_type ? sub_demuxer_type : sfmt,-2,-2,dvdsub_id, sub_stream); if(!sd) mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_OpeningSubtitlesDemuxerFailed,sub_stream); } diff -r ebc368360ea2 -r d00997f12257 libmpdemux/demuxer.h --- a/libmpdemux/demuxer.h Sat Jan 18 21:09:22 2003 +0000 +++ b/libmpdemux/demuxer.h Sun Jan 19 00:21:54 2003 +0000 @@ -231,7 +231,7 @@ return a*10+b; } -demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid); +demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid,char* filename); int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags); demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd); @@ -240,6 +240,8 @@ extern int force_ni; extern int pts_from_bps; +extern int extension_parsing; + 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); @@ -249,3 +251,5 @@ extern unsigned long demuxer_get_time_length(demuxer_t *demuxer); extern int demuxer_get_percent_pos(demuxer_t *demuxer); + +extern int demuxer_type_by_filename(char* filename); diff -r ebc368360ea2 -r d00997f12257 libmpdemux/extension.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/extension.c Sun Jan 19 00:21:54 2003 +0000 @@ -0,0 +1,56 @@ + +#include +#include +#include + +#include "config.h" + +#include "stream.h" +#include "demuxer.h" + +/* + * An autodetection based on the extension is not a good idea, but we don't care ;-) + */ +static struct { + char *extension; + int demuxer_type; +} extensions_table[] = { + { "mpeg", DEMUXER_TYPE_MPEG_PS }, + { "mpg", DEMUXER_TYPE_MPEG_PS }, + { "mpe", DEMUXER_TYPE_MPEG_ES }, + { "avi", DEMUXER_TYPE_AVI }, + { "mov", DEMUXER_TYPE_MOV }, + { "qt", DEMUXER_TYPE_MOV }, + { "asx", DEMUXER_TYPE_ASF }, + { "asf", DEMUXER_TYPE_ASF }, + { "wmv", DEMUXER_TYPE_ASF }, + { "wma", DEMUXER_TYPE_ASF }, + { "viv", DEMUXER_TYPE_VIVO }, + { "rm", DEMUXER_TYPE_REAL }, + { "ra", DEMUXER_TYPE_REAL }, + { "y4m", DEMUXER_TYPE_Y4M }, + { "mp3", DEMUXER_TYPE_AUDIO }, + { "ogg", DEMUXER_TYPE_OGG }, + { "wav", DEMUXER_TYPE_AUDIO }, + { "pls", DEMUXER_TYPE_PLAYLIST }, + { "m3u", DEMUXER_TYPE_PLAYLIST } +}; + +int demuxer_type_by_filename(char* filename){ + int i; + char* extension=strrchr(filename,'.'); + printf("Searching demuxer type for filename %s ext: %s\n",filename,extension); + if(extension) { + ++extension; +// mp_msg(MSGT_CPLAYER,MSGL_DBG2,"Extension: %s\n", extension ); + // Look for the extension in the extensions table + for( i=0 ; i<(sizeof(extensions_table)/sizeof(extensions_table[0])) ; i++ ) { + if( !strcasecmp(extension, extensions_table[i].extension) ) { + printf("\n!!! trying demuxer %d based on filename extension\n",extensions_table[i].demuxer_type); + return extensions_table[i].demuxer_type; + } + } + } + return DEMUXER_TYPE_UNKNOWN; +} + diff -r ebc368360ea2 -r d00997f12257 mencoder.c --- a/mencoder.c Sat Jan 18 21:09:22 2003 +0000 +++ b/mencoder.c Sun Jan 19 00:21:54 2003 +0000 @@ -389,7 +389,7 @@ // FIXME: get rid of -dvd and other tricky options stream2=open_stream(frameno_filename,0,&i); if(stream2){ - demuxer2=demux_open(stream2,DEMUXER_TYPE_AVI,-1,-1,-2); + demuxer2=demux_open(stream2,DEMUXER_TYPE_AVI,-1,-1,-2,NULL); if(demuxer2) printf(MSGTR_UsingPass3ControllFile,frameno_filename); else mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized); } @@ -492,7 +492,7 @@ if(demuxer2) audio_id=-2; /* do NOT read audio packets... */ //demuxer=demux_open(stream,file_format,video_id,audio_id,dvdsub_id); - demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id); + demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename); if(!demuxer){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized); printf(MSGTR_CannotOpenDemuxer); diff -r ebc368360ea2 -r d00997f12257 mplayer.c --- a/mplayer.c Sat Jan 18 21:09:22 2003 +0000 +++ b/mplayer.c Sun Jan 19 00:21:54 2003 +0000 @@ -1227,7 +1227,7 @@ current_module="demux_open"; -demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id); +demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename); // HACK to get MOV Reference Files working