changeset 9006:d00997f12257

extension-based filetype detection for headerless files (mp3 vs mpeg, etc) inspired by patch by Fabian Franz <FabianFranz@gmx.de>
author arpi
date Sun, 19 Jan 2003 00:21:54 +0000
parents ebc368360ea2
children 12fc55eb3373
files DOCS/mplayer.1 cfg-common.h libmpdemux/Makefile libmpdemux/demuxer.c libmpdemux/demuxer.h libmpdemux/extension.c mencoder.c mplayer.c
diffstat 8 files changed, 117 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- 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 <password> (see \-user option too)
 Specify password for http authentication.
 .TP
--- 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
--- 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 
--- 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);
   }
--- 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);
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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;
+}
+
--- 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);
--- 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