changeset 16175:6b86089c2edd

Demuxer modularization Demuxer selection by name with -demuxer command (bakward compatible)
author rtognimp
date Fri, 05 Aug 2005 19:57:47 +0000
parents b118c000ddd2
children 05716caa47e4
files DOCS/man/en/mplayer.1 cfg-common.h libmpdemux/asfheader.c libmpdemux/demux_aac.c libmpdemux/demux_asf.c libmpdemux/demux_audio.c libmpdemux/demux_avi.c libmpdemux/demux_avs.c libmpdemux/demux_demuxers.c libmpdemux/demux_film.c libmpdemux/demux_fli.c libmpdemux/demux_gif.c libmpdemux/demux_lavf.c libmpdemux/demux_lmlm4.c libmpdemux/demux_mf.c libmpdemux/demux_mkv.c libmpdemux/demux_mov.c libmpdemux/demux_mpc.c libmpdemux/demux_mpg.c libmpdemux/demux_nsv.c libmpdemux/demux_nuv.c libmpdemux/demux_ogg.c libmpdemux/demux_pva.c libmpdemux/demux_rawaudio.c libmpdemux/demux_rawdv.c libmpdemux/demux_rawvideo.c libmpdemux/demux_real.c libmpdemux/demux_realaud.c libmpdemux/demux_roq.c libmpdemux/demux_rtp.cpp libmpdemux/demux_smjpeg.c libmpdemux/demux_ts.c libmpdemux/demux_ty.c libmpdemux/demux_viv.c libmpdemux/demux_vqf.c libmpdemux/demux_xmms.c libmpdemux/demux_y4m.c libmpdemux/demuxer.c libmpdemux/demuxer.h libmpdemux/tv.c mencoder.c mplayer.c
diffstat 42 files changed, 1424 insertions(+), 1328 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1	Fri Aug 05 13:37:32 2005 +0000
+++ b/DOCS/man/en/mplayer.1	Fri Aug 05 19:57:47 2005 +0000
@@ -785,10 +785,12 @@
 .PD 1
 .
 .TP
-.B \-audio-demuxer <number> (\-audiofile only)
+.B \-audio-demuxer <name> (\-audiofile only)
 Force audio demuxer type for \-audiofile.
-Give the demuxer ID as defined in libmpdemux/\:demuxer.h.
-\-audio-demuxer 17 forces MP3.
+Give the demuxer name as printed by \-audio-demuxer help.
+For backward compatibility it also accepts the demuxer ID as defined in
+libmpdemux/\:demuxer.h.
+\-audio-demuxer audio or \-audio-demuxer 17 forces MP3.
 .
 .TP
 .B \-audiofile <filename>
@@ -921,10 +923,12 @@
 with \-ovc copy.
 .
 .TP
-.B \-demuxer <number>
+.B \-demuxer <name>
 Force demuxer type.
-Give the demuxer ID as defined in libmpdemux/\:demuxer.h.
-\-demuxer 17 forces MP3.
+Give the demuxer name as printed by \-demuxer help.
+For backward compatibility it also accepts the demuxer ID as defined in
+libmpdemux/\:demuxer.h.
+\-demuxer audio or \-demuxer 17 forces MP3.
 .
 .TP
 .B \-dumpaudio (MPlayer only)
@@ -1579,9 +1583,11 @@
 255 means white and 0 black.
 .
 .TP
-.B \-sub-demuxer <number> (\-subfile only) (BETA CODE)
+.B \-sub-demuxer <name> (\-subfile only) (BETA CODE)
 Force subtitle demuxer type for \-subfile.
-Give the demuxer ID as defined in subreader.h.
+Give the demuxer name as printed by \-sub-demuxer help.
+For backward compatibility it also accepts the demuxer ID as defined in
+libmpdemux/\:demuxer.h.
 .
 .TP
 .B \-sub-fuzziness <mode>
--- a/cfg-common.h	Fri Aug 05 13:37:32 2005 +0000
+++ b/cfg-common.h	Fri Aug 05 19:57:47 2005 +0000
@@ -113,9 +113,9 @@
 	{ "audiofile", &audio_stream, CONF_TYPE_STRING, 0, 0, 0, NULL },
 	{ "audiofile-cache", &audio_stream_cache, CONF_TYPE_INT, CONF_RANGE, 50, 65536, NULL},
 	{ "subfile", &sub_stream, CONF_TYPE_STRING, 0, 0, 0, NULL },
-	{ "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 },
+	{ "demuxer", &demuxer_name, CONF_TYPE_STRING, 0, 0, 0, NULL },
+	{ "audio-demuxer", &audio_demuxer_name, CONF_TYPE_STRING, 0, 0, 0, NULL },
+	{ "sub-demuxer", &sub_demuxer_name, CONF_TYPE_STRING, 0, 0, 0, NULL },
 	{ "extbased", &extension_parsing, CONF_TYPE_FLAG, 0, 0, 1, NULL },
 	{ "noextbased", &extension_parsing, CONF_TYPE_FLAG, 0, 1, 0, NULL },
 
--- a/libmpdemux/asfheader.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/asfheader.c	Fri Aug 05 19:57:47 2005 +0000
@@ -135,7 +135,7 @@
     mp_msg(MSGT_HEADER,MSGL_V,"ASF_check: invalid subchunks_no %d\n",(int) asfh.cno);
     return 0; // invalid header???
   }
-  return 1;
+  return DEMUXER_TYPE_ASF;
 }
 
 extern void print_wave_header(WAVEFORMATEX *h);
--- a/libmpdemux/demux_aac.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_aac.c	Fri Aug 05 19:57:47 2005 +0000
@@ -64,7 +64,7 @@
 	return 1;
 }
 
-void demux_close_aac(demuxer_t *demuxer)
+static void demux_close_aac(demuxer_t *demuxer)
 {
 	aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
 	
@@ -79,8 +79,8 @@
 	return;
 }
 
-/// returns 1 if it finds 8 ADTS frames in 32768 bytes, 0 otherwise
-int demux_aac_probe(demuxer_t *demuxer)
+/// returns DEMUXER_TYPE_AAC if it finds 8 ADTS frames in 32768 bytes, 0 otherwise
+static int demux_aac_probe(demuxer_t *demuxer)
 {
 	int cnt = 0, c, len, srate, num;
 	off_t init, probed;
@@ -122,14 +122,14 @@
 		goto fail;
 	
 	mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, INIT: %llu, PROBED: %llu, cnt: %d\n", init, probed, cnt);
-	return 1;
+	return DEMUXER_TYPE_AAC;
 
 fail:
 	mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, failed to detect an AAC stream\n");
 	return 0;
 }
 
-int demux_aac_open(demuxer_t *demuxer)
+static demuxer_t* demux_aac_open(demuxer_t *demuxer)
 {
 	sh_audio_t *sh;
 
@@ -140,10 +140,10 @@
 
 	demuxer->filepos = stream_tell(demuxer->stream);
 	
-	return 1;
+	return demuxer;
 }
 
-int demux_aac_fill_buffer(demuxer_t *demuxer)
+static int demux_aac_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
 {
 	aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
 	demux_packet_t *dp;
@@ -209,7 +209,7 @@
 
 
 //This is an almost verbatim copy of high_res_mp3_seek(), from demux_audio.c
-void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
+static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
 {
 	aac_priv_t *priv = (aac_priv_t *) demuxer->priv;
 	demux_stream_t *d_audio=demuxer->audio;
@@ -251,3 +251,19 @@
 	resync_audio_stream(sh_audio);
 }
 
+
+demuxer_desc_t demuxer_desc_aac = {
+  "AAC demuxer",
+  "aac",
+  "AAC",
+  "Nico Sabbi",
+  "Raw AAC files ",
+  DEMUXER_TYPE_AAC,
+  0, // unsafe autodetect
+  demux_aac_probe,
+  demux_aac_fill_buffer,
+  demux_aac_open,
+  demux_close_aac,
+  demux_aac_seek,
+  NULL
+};
--- a/libmpdemux/demux_asf.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_asf.c	Fri Aug 05 19:57:47 2005 +0000
@@ -38,6 +38,8 @@
 extern int asf_packetsize;
 extern double asf_packetrate;
 extern int asf_movielength;
+extern int asf_check_header(demuxer_t *demuxer);
+extern int read_asf_header(demuxer_t *demuxer);
 
 // based on asf file-format doc by Eugene [http://divx.euro.ru]
 
@@ -140,7 +142,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_asf_fill_buffer(demuxer_t *demux){
+static int demux_asf_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
 
   demux->filepos=stream_tell(demux->stream);
   // Brodcast stream have movi_start==movi_end
@@ -360,7 +362,7 @@
 extern void resync_audio_stream(sh_audio_t *sh_audio);
 extern void skip_audio_frame(sh_audio_t *sh_audio);
 
-void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags){
     demux_stream_t *d_audio=demuxer->audio;
     demux_stream_t *d_video=demuxer->video;
     sh_audio_t *sh_audio=d_audio->sh;
@@ -412,7 +414,7 @@
 
 }
 
-int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){
+static 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;
@@ -430,3 +432,58 @@
 	    return DEMUXER_CTRL_NOTIMPL;
     }
 }
+
+
+static demuxer_t* demux_open_asf(demuxer_t* demuxer)
+{
+    sh_audio_t *sh_audio=NULL;
+    sh_video_t *sh_video=NULL;
+
+    //---- ASF header:
+    read_asf_header(demuxer);
+    stream_reset(demuxer->stream);
+    stream_seek(demuxer->stream,demuxer->movi_start);
+//    demuxer->idx_pos=0;
+//    demuxer->endpos=avi_header.movi_end;
+    if(demuxer->video->id != -2) {
+        if(!ds_fill_buffer(demuxer->video)){
+            mp_msg(MSGT_DEMUXER,MSGL_WARN,"ASF: " MSGTR_MissingVideoStream);
+            demuxer->video->sh=NULL;
+            //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n");
+        } else {
+            sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
+            sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms
+            //sh_video->i_bps=10*asf_packetsize; // FIXME!
+        }
+    }
+
+    if(demuxer->audio->id!=-2){
+        mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_ASFSearchingForAudioStream,demuxer->audio->id);
+        if(!ds_fill_buffer(demuxer->audio)){
+            mp_msg(MSGT_DEMUXER,MSGL_INFO,"ASF: " MSGTR_MissingAudioStream);
+            demuxer->audio->sh=NULL;
+        } else {
+            sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
+            sh_audio->format=sh_audio->wf->wFormatTag;
+        }
+    }
+
+    return demuxer;
+}
+
+
+demuxer_desc_t demuxer_desc_asf = {
+  "ASF demuxer",
+  "asv",
+  "ASF",
+  "A'rpi",
+  "ASF, WMV, WMA",
+  DEMUXER_TYPE_ASF,
+  1, // safe autodetect
+  asf_check_header,
+  demux_asf_fill_buffer,
+  demux_open_asf,
+  NULL, //demux_close_asf,
+  demux_seek_asf,
+  demux_asf_control
+};
--- a/libmpdemux/demux_audio.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_audio.c	Fri Aug 05 19:57:47 2005 +0000
@@ -131,7 +131,7 @@
   return NULL;
 }
 
-int demux_audio_open(demuxer_t* demuxer) {
+static int demux_audio_open(demuxer_t* demuxer) {
   stream_t *s;
   sh_audio_t* sh_audio;
   uint8_t hdr[HDR_SIZE];
@@ -383,11 +383,11 @@
 
   mp_msg(MSGT_DEMUX,MSGL_V,"demux_audio: audio data 0x%X - 0x%X  \n",(int)demuxer->movi_start,(int)demuxer->movi_end);
 
-  return 1;
+  return DEMUXER_TYPE_AUDIO;
 }
 
 
-int demux_audio_fill_buffer(demux_stream_t *ds) {
+static int demux_audio_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) {
   int l;
   demux_packet_t* dp;
   sh_audio_t* sh_audio;
@@ -471,7 +471,7 @@
   }
 }
 
-void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
   sh_audio_t* sh_audio;
   stream_t* s;
   int base,pos;
@@ -527,7 +527,7 @@
 
 }
 
-void demux_close_audio(demuxer_t* demuxer) {
+static void demux_close_audio(demuxer_t* demuxer) {
   da_priv_t* priv = demuxer->priv;
 
   if(!priv)
@@ -535,7 +535,7 @@
   free(priv);
 }
 
-int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){
+static int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){
     sh_audio_t *sh_audio=demuxer->audio->sh;
     int audio_length = demuxer->movi_end / sh_audio->i_bps;
     da_priv_t* priv = demuxer->priv;
@@ -556,3 +556,20 @@
 	    return DEMUXER_CTRL_NOTIMPL;
     }
 }
+
+
+demuxer_desc_t demuxer_desc_audio = {
+  "Audio demuxer",
+  "audio",
+  "Audio file",
+  "?",
+  "Audio only files",
+  DEMUXER_TYPE_AUDIO,
+  0, // unsafe autodetect
+  demux_audio_open,
+  demux_audio_fill_buffer,
+  NULL,
+  demux_close_audio,
+  demux_audio_seek,
+  demux_audio_control
+};
--- a/libmpdemux/demux_avi.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_avi.c	Fri Aug 05 19:57:47 2005 +0000
@@ -14,6 +14,9 @@
 
 #include "aviheader.h"
 
+extern demuxer_t* init_avi_with_ogg(demuxer_t* demuxer);
+extern int demux_ogg_open(demuxer_t* demuxer);
+
 // PTS:  0=interleaved  1=BPS-based
 int pts_from_bps=1;
 
@@ -173,7 +176,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_avi_fill_buffer(demuxer_t *demux){
+static int demux_avi_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
 avi_priv_t *priv=demux->priv;
 unsigned int id=0;
 unsigned int len;
@@ -430,7 +433,7 @@
 
 void read_avi_header(demuxer_t *demuxer,int index_mode);
 
-demuxer_t* demux_open_avi(demuxer_t* demuxer){
+static demuxer_t* demux_open_avi(demuxer_t* demuxer){
     demux_stream_t *d_audio=demuxer->audio;
     demux_stream_t *d_video=demuxer->video;
     sh_audio_t *sh_audio=NULL;
@@ -856,3 +859,70 @@
 	    return DEMUXER_CTRL_NOTIMPL;
     }
 }
+
+
+static int avi_check_file(demuxer_t *demuxer)
+{
+  int id=stream_read_dword_le(demuxer->stream); // "RIFF"
+
+  if((id==mmioFOURCC('R','I','F','F')) || (id==mmioFOURCC('O','N','2',' '))) {
+    stream_read_dword_le(demuxer->stream); //filesize
+    id=stream_read_dword_le(demuxer->stream); // "AVI "
+    if(id==formtypeAVI)
+      return DEMUXER_TYPE_AVI;
+    if(id==mmioFOURCC('O','N','2','f')){
+      mp_msg(MSGT_DEMUXER,MSGL_INFO,"ON2 AVI format");
+      return DEMUXER_TYPE_AVI;
+    }
+  }
+
+  return 0;
+}
+
+
+static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer)
+{
+   sh_audio_t* sh_a;
+
+   demuxer = (demuxer_t*) demux_open_avi(demuxer);
+   if(!demuxer) return NULL; // failed to open
+   sh_a = (sh_audio_t*)demuxer->audio->sh;
+   if(demuxer->audio->id != -2 && sh_a) {
+#ifdef HAVE_OGGVORBIS
+    // support for Ogg-in-AVI:
+    if(sh_a->format == 0xFFFE)
+      demuxer = init_avi_with_ogg(demuxer);
+    else if(sh_a->format == 0x674F) {
+      stream_t* s;
+      demuxer_t  *od;
+      s = new_ds_stream(demuxer->audio);
+      od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL);
+      if(!demux_ogg_open(od)) {
+        mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer);
+        free_stream(s);
+        demuxer->audio->id = -2;
+      } else
+        demuxer = new_demuxers_demuxer(demuxer,od,demuxer);
+   }
+#endif
+   }
+
+   return demuxer;
+}
+
+
+demuxer_desc_t demuxer_desc_avi = {
+  "AVI demuxer",
+  "avi",
+  "AVI",
+  "Arpi?",
+  "AVI files, including non interleaved files",
+  DEMUXER_TYPE_AVI,
+  1, // safe autodetect
+  avi_check_file,
+  demux_avi_fill_buffer,
+  demux_open_hack_avi,
+  demux_close_avi,
+  demux_seek_avi,
+  NULL
+};
--- a/libmpdemux/demux_avs.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_avs.c	Fri Aug 05 19:57:47 2005 +0000
@@ -162,7 +162,7 @@
 }
 #endif
 
-int demux_avs_fill_buffer(demuxer_t *demuxer)
+static int demux_avs_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
 {
     AVS_VideoFrame *curr_frame;
     demux_packet_t *dp = NULL;
@@ -219,7 +219,7 @@
     return 1;
 }
 
-int demux_open_avs(demuxer_t* demuxer)
+static demuxer_t* demux_open_avs(demuxer_t* demuxer)
 {
     sh_video_t *sh_video = NULL;
 #ifdef ENABLE_AUDIO
@@ -236,14 +236,14 @@
     if(!AVS->clip)
     {
         mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_take_clip() failed\n");
-        return 0;
+        return NULL;
     }
 
     AVS->video_info = AVS->avs_get_video_info(AVS->clip);
     if (!AVS->video_info)
     {
         mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_get_video_info() call failed\n");
-        return 0;
+        return NULL;
     }
     
     if (!avs_is_yv12(AVS->video_info))
@@ -252,7 +252,7 @@
         if (avs_is_error(AVS->handler))
         {
             mp_msg(MSGT_DEMUX, MSGL_V, "AVS: Cannot convert input video to YV12: %s\n", avs_as_string(AVS->handler));
-            return 0;
+            return NULL;
         }
         
         AVS->clip = AVS->avs_take_clip(AVS->handler, AVS->avs_env);
@@ -260,14 +260,14 @@
         if(!AVS->clip)
         {
             mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_take_clip() failed\n");
-            return 0;
+            return NULL;
         }
 
         AVS->video_info = AVS->avs_get_video_info(AVS->clip);
         if (!AVS->video_info)
         {
             mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_get_video_info() call failed\n");
-            return 0;
+            return NULL;
         }
     }
     
@@ -326,10 +326,13 @@
 #endif
 
     AVS->init = 1;
-    return found;
+    if (found)
+        return demuxer;
+    else
+        return NULL;
 }
 
-int demux_avs_control(demuxer_t *demuxer, int cmd, void *arg)
+static int demux_avs_control(demuxer_t *demuxer, int cmd, void *arg)
 {   
     demux_stream_t *d_video=demuxer->video;
     sh_video_t *sh_video=d_video->sh;
@@ -354,7 +357,7 @@
     }
 }
 
-void demux_close_avs(demuxer_t* demuxer)
+static void demux_close_avs(demuxer_t* demuxer)
 {
     AVS_T *AVS = (AVS_T *) demuxer->priv;
     // TODO release_clip?
@@ -372,7 +375,7 @@
     }
 }
 
-void demux_seek_avs(demuxer_t *demuxer, float rel_seek_secs,int flags)
+static void demux_seek_avs(demuxer_t *demuxer, float rel_seek_secs,int flags)
 {
     demux_stream_t *d_video=demuxer->video;
     sh_video_t *sh_video=d_video->sh;
@@ -394,11 +397,11 @@
     d_video->pts=AVS->frameno / sh_video->fps; // OSD
 }
 
-int avs_check_file(demuxer_t *demuxer, const char *filename)
+static int avs_check_file(demuxer_t *demuxer)
 {
-    mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_check_file - attempting to open file %s\n", filename);
+    mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_check_file - attempting to open file %s\n", demuxer->filename);
 
-    if (!filename) return 0;
+    if (!demuxer->filename) return 0;
     
     /* Avoid crazy memory eating when passing an mpg stream */
     if (demuxer->movi_end > MAX_AVS_SIZE)
@@ -407,13 +410,30 @@
         return 0;
     }
     
-    demuxer->priv = initAVS(filename);
+    demuxer->priv = initAVS(demuxer->filename);
     
     if (demuxer->priv)
     {
         mp_msg(MSGT_DEMUX,MSGL_V, "AVS: Init Ok\n");
-        return 1;
+        return DEMUXER_TYPE_AVS;
     }
     mp_msg(MSGT_DEMUX,MSGL_V, "AVS: Init failed\n");
     return 0;
 }
+
+
+demuxer_desc_t demuxer_desc_avs = {
+  "Avisynth demuxer",
+  "avs",
+  "AVS",
+  "Gianluigi Tiesi",
+  "Requires binary dll",
+  DEMUXER_TYPE_AVS,
+  0, // unsafe autodetect
+  avs_check_file,
+  demux_avs_fill_buffer,
+  demux_open_avs,
+  demux_close_avs,
+  demux_seek_avs,
+  demux_avs_control
+};
--- a/libmpdemux/demux_demuxers.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_demuxers.c	Fri Aug 05 19:57:47 2005 +0000
@@ -13,6 +13,7 @@
   demuxer_t* sd;
 } dd_priv_t;
 
+extern demuxer_desc_t demuxer_desc_demuxers;
 
 demuxer_t*  new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd) {
   demuxer_t* ret;
@@ -34,11 +35,13 @@
   ret->video = vd->video;
   ret->audio = ad->audio;
   ret->sub = sd->sub;
-  
+
+  ret->desc = &demuxer_desc_demuxers;
+
   return ret;
 }
 
-int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds) {
+static int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds) {
   dd_priv_t* priv;
 
   priv=demux->priv;
@@ -54,7 +57,7 @@
   return 0;
 }
 
-void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,int flags) {
+static void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,int flags) {
   dd_priv_t* priv;
   float pos;
   priv=demuxer->priv;
@@ -81,7 +84,7 @@
 
 }
 
-void demux_close_demuxers(demuxer_t* demuxer) {
+static void demux_close_demuxers(demuxer_t* demuxer) {
   int i;
   dd_priv_t* priv = demuxer->priv;
   stream_t *s;
@@ -109,3 +112,19 @@
   free(demuxer);
 }
   
+
+demuxer_desc_t demuxer_desc_demuxers = {
+  "Demuxers demuxer",
+  "", // Not selectable
+  "",
+  "?",
+  "internal use only",
+  DEMUXER_TYPE_DEMUXERS,
+  0, // no autodetect
+  NULL,
+  demux_demuxers_fill_buffer,
+  NULL,
+  demux_close_demuxers,
+  demux_demuxers_seek,
+  NULL
+};
--- a/libmpdemux/demux_film.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_film.c	Fri Aug 05 19:57:47 2005 +0000
@@ -46,7 +46,7 @@
   unsigned int film_version;
 } film_data_t;
 
-void demux_seek_film(demuxer_t *demuxer, float rel_seek_secs, int flags)
+static void demux_seek_film(demuxer_t *demuxer, float rel_seek_secs, int flags)
 {
   film_data_t *film_data = (film_data_t *)demuxer->priv;
   int new_current_chunk=(flags&1)?0:film_data->current_chunk;
@@ -83,7 +83,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_film_fill_buffer(demuxer_t *demuxer)
+static int demux_film_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
 {
   int i;
   unsigned char byte_swap;
@@ -206,7 +206,7 @@
   return 1;
 }
 
-demuxer_t* demux_open_film(demuxer_t* demuxer)
+static demuxer_t* demux_open_film(demuxer_t* demuxer)
 {
   sh_video_t *sh_video = NULL;
   sh_audio_t *sh_audio = NULL;
@@ -436,7 +436,7 @@
   return demuxer;
 }
 
-void demux_close_film(demuxer_t* demuxer) {
+static void demux_close_film(demuxer_t* demuxer) {
   film_data_t *film_data = demuxer->priv;
 
   if(!film_data)
@@ -446,3 +446,31 @@
   free(film_data);
   
 }
+
+static int film_check_file(demuxer_t* demuxer)
+{
+  int signature=stream_read_fourcc(demuxer->stream);
+
+  // check for the FILM file magic number
+  if(signature==mmioFOURCC('F', 'I', 'L', 'M'))
+    return DEMUXER_TYPE_FILM;
+
+  return 0;
+}
+
+
+demuxer_desc_t demuxer_desc_film = {
+  "FILM/CPK demuxer for Sega Saturn CD-ROM games",
+  "film",
+  "FILM",
+  "Mike Melanson",
+  "",
+  DEMUXER_TYPE_FILM,
+  0, // unsafe autodetect (short signature)
+  film_check_file,
+  demux_film_fill_buffer,
+  demux_open_film,
+  demux_close_film,
+  demux_seek_film,
+  NULL
+};
--- a/libmpdemux/demux_fli.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_fli.c	Fri Aug 05 19:57:47 2005 +0000
@@ -22,7 +22,7 @@
   unsigned int *frame_size;
 } fli_frames_t;
 
-void demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,int flags){
   fli_frames_t *frames = (fli_frames_t *)demuxer->priv;
   sh_video_t *sh_video = demuxer->video->sh;
   int newpos=(flags&1)?0:frames->current_frame;
@@ -41,7 +41,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_fli_fill_buffer(demuxer_t *demuxer){
+static int demux_fli_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
   fli_frames_t *frames = (fli_frames_t *)demuxer->priv;
   sh_video_t *sh_video = demuxer->video->sh;
 
@@ -67,7 +67,7 @@
   return 1;
 }
 
-demuxer_t* demux_open_fli(demuxer_t* demuxer){
+static demuxer_t* demux_open_fli(demuxer_t* demuxer){
   sh_video_t *sh_video = NULL;
   fli_frames_t *frames = (fli_frames_t *)malloc(sizeof(fli_frames_t));
   int frame_number;
@@ -164,7 +164,7 @@
   return demuxer;
 }
 
-void demux_close_fli(demuxer_t* demuxer) {
+static void demux_close_fli(demuxer_t* demuxer) {
   fli_frames_t *frames = demuxer->priv;
 
   if(!frames)
@@ -178,3 +178,34 @@
   free(frames);
 
 }
+
+
+static int fli_check_file(demuxer_t* demuxer)
+{
+  int id;
+
+  stream_seek(demuxer->stream, 4);
+  id=stream_read_word_le(demuxer->stream);
+  // check for the FLI file magic number
+  if((id==0xAF11) || (id==0xAF12))
+    return DEMUXER_TYPE_FLI;
+
+  return 0;
+}
+
+
+demuxer_desc_t demuxer_desc_fli = {
+  "Autodesk FLIC demuxer",
+  "fli",
+  "FLI",
+  "Mike Melanson",
+  "Supports also some extensions",
+  DEMUXER_TYPE_FLI,
+  0, // unsafe autodetect (short signature)
+  fli_check_file,
+  demux_fli_fill_buffer,
+  demux_open_fli,
+  demux_close_fli,
+  demux_seek_fli,
+  NULL
+};
--- a/libmpdemux/demux_gif.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_gif.c	Fri Aug 05 19:57:47 2005 +0000
@@ -31,14 +31,14 @@
 }
 #endif
   
-int gif_check_file(demuxer_t *demuxer)
+static int gif_check_file(demuxer_t *demuxer)
 {
   if (stream_read_int24(demuxer->stream) == GIF_SIGNATURE)
-    return 1;
+    return DEMUXER_TYPE_GIF;
   return 0;
 }
 
-int demux_gif_fill_buffer(demuxer_t *demuxer)
+static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
 {
   GifFileType *gif = (GifFileType *)demuxer->priv;
   sh_video_t *sh_video = (sh_video_t *)demuxer->video->sh;
@@ -148,7 +148,7 @@
   return 1;
 }
 
-demuxer_t* demux_open_gif(demuxer_t* demuxer)
+static demuxer_t* demux_open_gif(demuxer_t* demuxer)
 {
   sh_video_t *sh_video = NULL;
   GifFileType *gif = NULL;
@@ -206,7 +206,7 @@
   return demuxer;
 }
 
-void demux_close_gif(demuxer_t* demuxer)
+static void demux_close_gif(demuxer_t* demuxer)
 {
   GifFileType *gif = (GifFileType *)demuxer->priv;
 
@@ -219,4 +219,22 @@
   demuxer->stream->fd = 0;
   demuxer->priv = NULL;
 }
+
+
+demuxer_desc_t demuxer_desc_gif = {
+  "GIF demuxer",
+  "gif",
+  "GIF",
+  "Joey Parrish",
+  "",
+  DEMUXER_TYPE_GIF,
+  0, // unsafe autodetect
+  gif_check_file,
+  demux_gif_fill_buffer,
+  demux_open_gif,
+  demux_close_gif,
+  NULL,
+  NULL
+};
+
 #endif /* HAVE_GIF */
--- a/libmpdemux/demux_lavf.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_lavf.c	Fri Aug 05 19:57:47 2005 +0000
@@ -101,7 +101,7 @@
     mp_close,
 };
 
-int lavf_check_file(demuxer_t *demuxer){
+static int lavf_check_file(demuxer_t *demuxer){
     AVProbeData avpd;
     uint8_t buf[PROBE_BUF_SIZE];
     lavf_priv_t *priv;
@@ -125,10 +125,10 @@
     }else
         mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
 
-    return 1;
+    return DEMUXER_TYPE_LAVF;
 }
     
-int demux_open_lavf(demuxer_t *demuxer){
+static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
     AVFormatContext *avfc;
     AVFormatParameters ap;
     lavf_priv_t *priv= demuxer->priv;
@@ -152,14 +152,14 @@
         
     if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){
         mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
-        return 0;
+        return NULL;
     }
 
     priv->avfc= avfc;
 
     if(av_find_stream_info(avfc) < 0){
         mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
-        return 0;
+        return NULL;
     }
 
     if(avfc->title    [0]) demux_info_add(demuxer, "name"     , avfc->title    );
@@ -304,15 +304,15 @@
     if(!priv->video_streams){
         if(!priv->audio_streams){
 	    mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
-            return 0; 
+            return NULL; 
         }
         demuxer->video->id=-2; // audio-only
     } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
 
-    return 1;
+    return demuxer;
 }
 
-int demux_lavf_fill_buffer(demuxer_t *demux){
+static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
     lavf_priv_t *priv= demux->priv;
     AVPacket pkt;
     demux_packet_t *dp;
@@ -382,7 +382,7 @@
     return 1;
 }
 
-void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags){
+static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags){
     lavf_priv_t *priv = demuxer->priv;
     mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %d)\n", demuxer, rel_seek_secs, flags);
     
@@ -393,7 +393,7 @@
 #endif
 }
 
-int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
+static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
 {
     lavf_priv_t *priv = demuxer->priv;
     
@@ -417,7 +417,7 @@
     }
 }
 
-void demux_close_lavf(demuxer_t *demuxer)
+static void demux_close_lavf(demuxer_t *demuxer)
 {
     lavf_priv_t* priv = demuxer->priv;
     if (priv){
@@ -429,4 +429,21 @@
     }
 }
 
+
+demuxer_desc_t demuxer_desc_lavf = {
+  "libavformat demuxer",
+  "lavf",
+  "libavformat",
+  "Michael Niedermayer",
+  "supports many formats, requires libavformat",
+  DEMUXER_TYPE_LAVF,
+  0, // Check after other demuxer
+  lavf_check_file,
+  demux_lavf_fill_buffer,
+  demux_open_lavf,
+  demux_close_lavf,
+  demux_seek_lavf,
+  demux_lavf_control
+};
+
 #endif // USE_LIBAVFORMAT
--- a/libmpdemux/demux_lmlm4.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_lmlm4.c	Fri Aug 05 19:57:47 2005 +0000
@@ -158,7 +158,7 @@
     return 1;
 }
                         
-int lmlm4_check_file(demuxer_t* demuxer)
+static int lmlm4_check_file(demuxer_t* demuxer)
 {
     FrameInfo frameInfo;
     unsigned int first;
@@ -198,7 +198,7 @@
 //    stream_reset(demuxer->stream);
     mp_msg(MSGT_DEMUX, MSGL_V, "LMLM4 Stream Format found\n");
 
-    return 1;
+    return DEMUXER_TYPE_LMLM4;
 }
 
 static int video = 0;
@@ -207,7 +207,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_lmlm4_fill_buffer(demuxer_t *demux)
+static int demux_lmlm4_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
 {
     FrameInfo frameInfo;
     double pts;
@@ -277,7 +277,9 @@
     return 1;
 }
 
-int demux_open_lmlm4(demuxer_t* demuxer){
+static demuxer_t* demux_open_lmlm4(demuxer_t* demuxer){
+    sh_audio_t *sh_audio=NULL;
+    sh_video_t *sh_video=NULL;
 
 #if 0
     sh_video_t* sh_video;
@@ -327,13 +329,43 @@
 
     demuxer->seekable = 0;
     
-    
+    if(!ds_fill_buffer(demuxer->video)){
+        mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingVideoStream);
+        demuxer->video->sh=NULL;
+    } else {
+        sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
+    }
+    if(demuxer->audio->id!=-2) {
+        if(!ds_fill_buffer(demuxer->audio)){
+            mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingAudioStream);
+            demuxer->audio->sh=NULL;
+        } else {
+            sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
+        }
+    }    
     
-    return 1;
+    return demuxer;
 }
 
-void demux_close_lmlm4(demuxer_t *demuxer)
+static void demux_close_lmlm4(demuxer_t *demuxer)
 {
 //    printf("Close LMLM4 Stream\n");
     return;
 }
+
+
+demuxer_desc_t demuxer_desc_lmlm4 = {
+  "LMLM4 MPEG4 Compression Card stream demuxer",
+  "lmlm4",
+  "RAW LMLM4",
+  "Maxim Yevtyushkin",
+  "",
+  DEMUXER_TYPE_LMLM4,
+  0, // unsafe autodetect
+  lmlm4_check_file,
+  demux_lmlm4_fill_buffer,
+  demux_open_lmlm4,
+  demux_close_lmlm4,
+  NULL,
+  NULL
+};
--- a/libmpdemux/demux_mf.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_mf.c	Fri Aug 05 19:57:47 2005 +0000
@@ -15,7 +15,7 @@
 #include "stheader.h"
 #include "mf.h"
 
-void demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,int flags){
   mf_t * mf = (mf_t *)demuxer->priv;
   sh_video_t   * sh_video = demuxer->video->sh;
   int newpos = (flags & 1)?0:mf->curr_frame;
@@ -30,7 +30,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_mf_fill_buffer(demuxer_t *demuxer){
+static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
   mf_t         * mf;
   struct stat    fs;
   FILE         * f;
@@ -62,7 +62,7 @@
   return 1;
 }
 
-demuxer_t* demux_open_mf(demuxer_t* demuxer){
+static demuxer_t* demux_open_mf(demuxer_t* demuxer){
   sh_video_t   *sh_video = NULL;
   mf_t         *mf = NULL;
   
@@ -130,10 +130,27 @@
   return demuxer;
 }
 
-void demux_close_mf(demuxer_t* demuxer) {
+static void demux_close_mf(demuxer_t* demuxer) {
   mf_t *mf = demuxer->priv;
 
   if(!mf)
     return;
   free(mf);  
 }
+
+
+demuxer_desc_t demuxer_desc_mf = {
+  "mf demuxer",
+  "mf",
+  "MF",
+  "?",
+  "multiframe?, pictures demuxer",
+  DEMUXER_TYPE_MF,
+  0, // no autodetect
+  NULL,
+  demux_mf_fill_buffer,
+  demux_open_mf,
+  demux_close_mf,
+  demux_seek_mf,
+  NULL
+};
--- a/libmpdemux/demux_mkv.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_mkv.c	Fri Aug 05 19:57:47 2005 +0000
@@ -2067,7 +2067,7 @@
   return 0;
 }
 
-void demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, int flags);
+static void demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, int flags);
 
 /** \brief Given a matroska track number and type, find the id that mplayer would ask for.
  *  \param d The demuxer for which the subtitle id should be returned.
@@ -2088,7 +2088,7 @@
   return -1;
 }
 
-int
+static int
 demux_mkv_open (demuxer_t *demuxer)
 {
   stream_t *s = demuxer->stream;
@@ -2344,10 +2344,10 @@
         }
     }
 
-  return 1;
+  return DEMUXER_TYPE_MATROSKA;
 }
 
-void
+static void
 demux_close_mkv (demuxer_t *demuxer)
 {
   mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
@@ -2986,8 +2986,8 @@
   return 0;
 }
 
-int
-demux_mkv_fill_buffer (demuxer_t *demuxer)
+static int
+demux_mkv_fill_buffer (demuxer_t *demuxer, demux_stream_t *ds)
 {
   mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
   stream_t *s = demuxer->stream;
@@ -3100,7 +3100,7 @@
   return 0;
 }
 
-void
+static void
 demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, int flags)
 {
   free_cached_dps (demuxer);
@@ -3216,7 +3216,7 @@
       if (target_timecode <= mkv_d->last_pts * 1000)
         clear_subtitles(demuxer, 0, 1);
 
-      demux_mkv_fill_buffer(demuxer);
+      demux_mkv_fill_buffer(demuxer, NULL);
 
       if(demuxer->audio->sh != NULL)
         resync_audio_stream((sh_audio_t *) demuxer->audio->sh); 
@@ -3262,14 +3262,14 @@
       if (index->timecode <= mkv_d->last_pts * 1000)
         clear_subtitles(demuxer, 0, 1);
 
-      demux_mkv_fill_buffer(demuxer);
+      demux_mkv_fill_buffer(demuxer, NULL);
 
       if(demuxer->audio->sh != NULL)
         resync_audio_stream((sh_audio_t *) demuxer->audio->sh); 
     }
 }
 
-int
+static int
 demux_mkv_control (demuxer_t *demuxer, int cmd, void *arg)
 {
   mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
@@ -3433,4 +3433,21 @@
     }
 }
 
+
+demuxer_desc_t demuxer_desc_matroska = {
+  "Matroska demuxer",
+  "mkv",
+  "Matroska",
+  "Aurelien Jacobs",
+  "based on gstreamer demuxer by Ronald Bultje and demux_mkv.cpp by Moritz Bunkus",
+  DEMUXER_TYPE_MATROSKA,
+  1, // safe autodetect
+  demux_mkv_open,
+  demux_mkv_fill_buffer,
+  NULL,
+  demux_close_mkv,
+  demux_mkv_seek,
+  demux_mkv_control
+};
+
 #endif /* HAVE_MATROSKA */
--- a/libmpdemux/demux_mov.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_mov.c	Fri Aug 05 19:57:47 2005 +0000
@@ -287,7 +287,7 @@
 
 #define MOV_FOURCC(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d))
 
-int mov_check_file(demuxer_t* demuxer){
+static int mov_check_file(demuxer_t* demuxer){
     int flags=0;
     int no=0;
     mov_priv_t* priv=malloc(sizeof(mov_priv_t));
@@ -460,7 +460,7 @@
 	  if(flags==3){
 	    // if we're over the headers, then we can stop parsing here!
 	    demuxer->priv=priv;
-	    return 1;
+	    return DEMUXER_TYPE_MOV;
 	  }
 	  break;
 	case MOV_FOURCC('f','r','e','e'):
@@ -485,12 +485,12 @@
 
     if(flags==3){
 	demuxer->priv=priv;
-	return 1;
+	return DEMUXER_TYPE_MOV;
     }
     free(priv);
 
     if ((flags==5) || (flags==7)) // reference & header sent
-        return 1;
+        return DEMUXER_TYPE_MOV;
 
     if(flags==1)
 	mp_msg(MSGT_DEMUX,MSGL_WARN,"MOV: missing data (mdat) chunk! Maybe broken file...\n");
@@ -500,7 +500,7 @@
     return 0;
 }
 
-void demux_close_mov(demuxer_t *demuxer) {
+static void demux_close_mov(demuxer_t *demuxer) {
   mov_priv_t* priv = demuxer->priv;
   int i;
   if (!priv)
@@ -1681,7 +1681,7 @@
   return 0;
 }
 
-int mov_read_header(demuxer_t* demuxer){
+static demuxer_t* mov_read_header(demuxer_t* demuxer){
     mov_priv_t* priv=demuxer->priv;
     int t_no;
     int best_a_id=-1, best_a_len=0;
@@ -1806,7 +1806,7 @@
     demuxer->stream->eof = 0;
 #endif
 
-    return 1;
+    return demuxer;
 }
 
 /**
@@ -1824,7 +1824,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_mov_fill_buffer(demuxer_t *demuxer,demux_stream_t* ds){
+static int demux_mov_fill_buffer(demuxer_t *demuxer,demux_stream_t* ds){
     mov_priv_t* priv=demuxer->priv;
     mov_track_t* trak=NULL;
     float pts;
@@ -1956,7 +1956,7 @@
 return pts;
 }
 
-void demux_seek_mov(demuxer_t *demuxer,float pts,int flags){
+static void demux_seek_mov(demuxer_t *demuxer,float pts,int flags){
     mov_priv_t* priv=demuxer->priv;
     demux_stream_t* ds;
     mov_track_t* trak;
@@ -1984,7 +1984,7 @@
 
 }
 
-int demux_mov_control(demuxer_t *demuxer, int cmd, void *arg){
+static int demux_mov_control(demuxer_t *demuxer, int cmd, void *arg){
   mov_track_t* track;
 
   // try the video track
@@ -2015,3 +2015,19 @@
   return DEMUXER_CTRL_NOTIMPL;
 }
 
+
+demuxer_desc_t demuxer_desc_mov = {
+  "Quicktime/MP4 demuxer",
+  "mov",
+  "Quicktime/MOV",
+  "Arpi, Al3x, Atmos, others",
+  "Handles Quicktime, MP4, 3GP",
+  DEMUXER_TYPE_MOV,
+  0, // slow autodetect
+  mov_check_file,
+  demux_mov_fill_buffer,
+  mov_read_header,
+  demux_close_mov,
+  demux_seek_mov,
+  demux_mov_control
+};
--- a/libmpdemux/demux_mpc.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_mpc.c	Fri Aug 05 19:57:47 2005 +0000
@@ -46,7 +46,7 @@
   return out & mask;
 }
 
-int demux_mpc_open(demuxer_t* demuxer) {
+static int demux_mpc_open(demuxer_t* demuxer) {
   stream_t *s = demuxer->stream;
   sh_audio_t* sh_audio;
   uint8_t hdr[HDR_SIZE];
@@ -101,10 +101,10 @@
   sh_audio->audio.dwScale = 32 * 36;
   sh_audio->audio.dwRate = sh_audio->samplerate;
 
-  return 1;
+  return DEMUXER_TYPE_MPC;
 }
 
-int demux_mpc_fill_buffer(demux_stream_t *ds) {
+static int demux_mpc_fill_buffer(demux_stream_t *ds, demux_stream_t *dsds) {
   int l;
   int bit_len;
   demux_packet_t* dp;
@@ -134,11 +134,11 @@
   return 1;
 }
 
-void demux_mpc_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_mpc_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
 // TODO
 }
 
-void demux_close_mpc(demuxer_t* demuxer) {
+static void demux_close_mpc(demuxer_t* demuxer) {
   da_priv_t* priv = demuxer->priv;
 
   if(!priv)
@@ -146,6 +146,23 @@
   free(priv);
 }
 
-int demux_mpc_control(demuxer_t *demuxer,int cmd, void *arg){
+static int demux_mpc_control(demuxer_t *demuxer,int cmd, void *arg){
   return DEMUXER_CTRL_NOTIMPL;
 }
+
+
+demuxer_desc_t demuxer_desc_mpc = {
+  "Musepack demuxer",
+  "mpc",
+  "MPC",
+  "Reza Jelveh, Reimar Doeffinger",
+  "supports v7 bitstream only",
+  DEMUXER_TYPE_MPC,
+  0, // unsafe autodetect
+  demux_mpc_open,
+  demux_mpc_fill_buffer,
+  NULL,
+  demux_close_mpc,
+  demux_mpc_seek,
+  demux_mpc_control
+};
--- a/libmpdemux/demux_mpg.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_mpg.c	Fri Aug 05 19:57:47 2005 +0000
@@ -99,7 +99,7 @@
 }
 
 /// Open an mpg physical stream
-int demux_mpg_open(demuxer_t* demuxer) {
+static demuxer_t* demux_mpg_open(demuxer_t* demuxer) {
   stream_t *s = demuxer->stream;
   off_t pos = stream_tell(s);
   off_t end_seq_start = demuxer->movi_end-500000; // 500000 is a wild guess
@@ -134,10 +134,10 @@
     stream_seek(s,pos);
     ds_fill_buffer(demuxer->video);
   }
-  return 1;
+  return demuxer;
 }
 
-void demux_close_mpg(demuxer_t* demuxer) {
+static void demux_close_mpg(demuxer_t* demuxer) {
   mpg_demuxer_t* mpg_d = demuxer->priv;
   if (mpg_d) free(mpg_d);
 }
@@ -418,7 +418,7 @@
 
 static int num_mp3audio_packets=0;
 
-int demux_mpg_probe(demuxer_t *demuxer) {
+static int demux_mpg_probe(demuxer_t *demuxer) {
   int pes=1;
   int tmp;
   off_t tmppos;
@@ -498,7 +498,7 @@
   return file_format;
 }
 
-int demux_mpg_es_fill_buffer(demuxer_t *demux){
+static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
   // Elementary video stream
   if(demux->stream->eof) return 0;
   demux->filepos=stream_tell(demux->stream);
@@ -506,7 +506,7 @@
   return 1;
 }
 
-int demux_mpg_fill_buffer(demuxer_t *demux){
+int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
 unsigned int head=0;
 int skipped=0;
 int max_packs=256; // 512kbyte
@@ -770,3 +770,126 @@
 	    return DEMUXER_CTRL_NOTIMPL;
     }
 }
+
+
+static int demux_mpg_pes_probe(demuxer_t *demuxer) {
+   demuxer->synced = 3;
+   return demux_mpg_probe(demuxer);
+}
+
+
+static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
+{
+    sh_video_t *sh_video=NULL;
+
+    demuxer->audio->sh = NULL;   // ES streams has no audio channel
+    demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
+    sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
+
+    return demuxer;
+}
+
+
+static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
+{
+    sh_audio_t *sh_audio=NULL;
+    sh_video_t *sh_video=NULL;
+
+    sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
+
+    if(demuxer->audio->id!=-2) {
+        if(!ds_fill_buffer(demuxer->audio)){
+            mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);
+            demuxer->audio->sh=NULL;
+        } else {
+            sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
+        }
+    }
+
+    return demuxer;
+}
+
+
+demuxer_desc_t demuxer_desc_mpeg_ps = {
+  "MPEG PS demuxer",
+  "mpegps",
+  "MPEG-PS",
+  "Arpi?",
+  "Mpeg",
+  DEMUXER_TYPE_MPEG_PS,
+  0, // unsafe autodetect
+  demux_mpg_probe,
+  demux_mpg_fill_buffer,
+  demux_mpg_ps_open,
+  demux_close_mpg,
+  demux_seek_mpg,
+  NULL
+};
+
+
+demuxer_desc_t demuxer_desc_mpeg_pes = {
+  "MPEG PES demuxer",
+  "mpegpes",
+  "MPEG-PES",
+  "Arpi?",
+  "Mpeg",
+  DEMUXER_TYPE_MPEG_PES,
+  0, // unsafe autodetect
+  demux_mpg_pes_probe,
+  demux_mpg_fill_buffer,
+  NULL,
+  demux_close_mpg,
+  demux_seek_mpg,
+  NULL
+};
+
+
+demuxer_desc_t demuxer_desc_mpeg_es = {
+  "MPEG ES demuxer",
+  "mpeges",
+  "MPEG-ES",
+  "Arpi?",
+  "Mpeg",
+  DEMUXER_TYPE_MPEG_ES,
+  0, // hack autodetection
+  NULL,
+  demux_mpg_es_fill_buffer,
+  demux_mpg_es_open,
+  demux_close_mpg,
+  demux_seek_mpg,
+  NULL
+};
+
+
+demuxer_desc_t demuxer_desc_mpeg4_es = {
+  "MPEG4 ES demuxer",
+  "mpeg4es",
+  "MPEG-ES",
+  "Arpi?",
+  "Mpeg",
+  DEMUXER_TYPE_MPEG4_ES,
+  0, // hack autodetection
+  NULL,
+  demux_mpg_es_fill_buffer,
+  demux_mpg_es_open,
+  demux_close_mpg,
+  demux_seek_mpg,
+  NULL
+};
+
+
+demuxer_desc_t demuxer_desc_h264_es = {
+  "H.264 ES demuxer",
+  "h264es",
+  "H264-ES",
+  "Arpi?",
+  "Mpeg",
+  DEMUXER_TYPE_H264_ES,
+  0, // hack autodetection
+  NULL,
+  demux_mpg_es_fill_buffer,
+  demux_mpg_es_open,
+  demux_close_mpg,
+  demux_seek_mpg,
+  NULL
+};
--- a/libmpdemux/demux_nsv.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_nsv.c	Fri Aug 05 19:57:47 2005 +0000
@@ -31,13 +31,13 @@
 /**
  * Seeking still to be implemented
  */
-void demux_seek_nsv ( demuxer_t *demuxer, float rel_seek_secs, int flags )
+static void demux_seek_nsv ( demuxer_t *demuxer, float rel_seek_secs, int flags )
 {
 // seeking is not yet implemented
 }
 
 
-int demux_nsv_fill_buffer ( demuxer_t *demuxer )
+static int demux_nsv_fill_buffer ( demuxer_t *demuxer, demux_stream_t *ds )
 {  
     unsigned char hdr[17];
     // for the extra data
@@ -132,7 +132,7 @@
 }
 
 
-demuxer_t* demux_open_nsv ( demuxer_t* demuxer )
+static demuxer_t* demux_open_nsv ( demuxer_t* demuxer )
 {
     // last 2 bytes 17 and 18 are unknown but right after that comes the length
     unsigned char hdr[17];
@@ -314,7 +314,7 @@
     return demuxer;
 }
 
-int nsv_check_file ( demuxer_t* demuxer )
+static int nsv_check_file ( demuxer_t* demuxer )
 {
     unsigned int id;
 
@@ -332,10 +332,10 @@
     stream_seek(demuxer->stream,demuxer->stream->start_pos);
 
     
-    return 1;
+    return DEMUXER_TYPE_NSV;
 }
 
-void demux_close_nsv(demuxer_t* demuxer) {
+static void demux_close_nsv(demuxer_t* demuxer) {
     nsv_priv_t* priv = demuxer->priv;
 
     if(!priv)
@@ -343,3 +343,20 @@
     free(priv);
 
 }
+
+
+demuxer_desc_t demuxer_desc_nsv = {
+  "NullsoftVideo demuxer",
+  "nsv",
+  "Nullsoft Streaming Video",
+  "Reza Jelveh",
+  "nsv and nsa streaming files",
+  DEMUXER_TYPE_NSV,
+  1, // safe autodetect
+  nsv_check_file,
+  demux_nsv_fill_buffer,
+  demux_open_nsv,
+  demux_close_nsv,
+  demux_seek_nsv,
+  NULL
+};
--- a/libmpdemux/demux_nuv.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_nuv.c	Fri Aug 05 19:57:47 2005 +0000
@@ -63,7 +63,7 @@
 /**
  * Seek to a position relative to the current position, indicated in time.
  */
-void demux_seek_nuv ( demuxer_t *demuxer, float rel_seek_secs, int flags )
+static void demux_seek_nuv ( demuxer_t *demuxer, float rel_seek_secs, int flags )
 {
 #define MAX_TIME 1000000
 	nuv_priv_t* priv = demuxer->priv;
@@ -152,7 +152,7 @@
 }
 
 
-int demux_nuv_fill_buffer ( demuxer_t *demuxer )
+static int demux_nuv_fill_buffer ( demuxer_t *demuxer, demux_stream_t *ds )
 {
 	struct rtframeheader rtjpeg_frameheader;
 	off_t orig_pos;
@@ -309,7 +309,7 @@
   return 0;
 }
 
-demuxer_t* demux_open_nuv ( demuxer_t* demuxer )
+static demuxer_t* demux_open_nuv ( demuxer_t* demuxer )
 {
 	sh_video_t *sh_video = NULL;
 	sh_audio_t *sh_audio = NULL;
@@ -404,7 +404,7 @@
 	return demuxer;
 }
 
-int nuv_check_file ( demuxer_t* demuxer )
+static int nuv_check_file ( demuxer_t* demuxer )
 {
 	struct nuv_signature ns;
 
@@ -426,10 +426,10 @@
 
 	/* Return to original position */
 	stream_seek ( demuxer->stream, orig_pos );
-	return 1;
+	return DEMUXER_TYPE_NUV;
 }
 
-void demux_close_nuv(demuxer_t* demuxer) {
+static void demux_close_nuv(demuxer_t* demuxer) {
   nuv_priv_t* priv = demuxer->priv;
   nuv_position_t* pos;
   if(!priv)
@@ -441,3 +441,20 @@
   }
   free(priv);
 }
+
+
+demuxer_desc_t demuxer_desc_nuv = {
+  "NuppelVideo demuxer",
+  "nuv",
+  "NuppelVideo",
+  "Panagiotis Issaris",
+  "",
+  DEMUXER_TYPE_NUV,
+  1, // safe autodetect
+  nuv_check_file,
+  demux_nuv_fill_buffer,
+  demux_open_nuv,
+  demux_close_nuv,
+  demux_seek_nuv,
+  NULL
+};
--- a/libmpdemux/demux_ogg.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_ogg.c	Fri Aug 05 19:57:47 2005 +0000
@@ -734,7 +734,7 @@
   return (index < 0) ? NULL : (index >= ogg_d->n_text) ? NULL : ogg_d->text_langs[index];
 }
 
-void demux_close_ogg(demuxer_t* demuxer);
+static void demux_close_ogg(demuxer_t* demuxer);
 
 static inline unsigned int store_ughvlc(unsigned char *s, unsigned int v)
 {
@@ -819,6 +819,7 @@
 
 
 /// Open an ogg physical stream
+// Not static because it's used also in demuxer_avi.c
 int demux_ogg_open(demuxer_t* demuxer) {
   ogg_demuxer_t* ogg_d;
   stream_t *s;
@@ -1194,14 +1195,14 @@
     if(sh_a->format == FOURCC_VORBIS)
       fixup_vorbis_wf(sh_a);
 
-  return 1;
+  return DEMUXER_TYPE_OGG;
 
 err_out:
   return 0;
 }
 
 
-int demux_ogg_fill_buffer(demuxer_t *d) {
+static int demux_ogg_fill_buffer(demuxer_t *d, demux_stream_t *dsds) {
   ogg_demuxer_t* ogg_d;
   stream_t *s;
   demux_stream_t *ds;
@@ -1344,7 +1345,7 @@
 
   // Create the ds_stream and the ogg demuxer
   s = new_ds_stream(demuxer->audio);
-  od = new_demuxer(s,DEMUXER_TYPE_OGG,0,-2,-2);
+  od = new_demuxer(s,DEMUXER_TYPE_OGG,0,-2,-2,NULL);
 
   /// Add the header packets in the ogg demuxer audio stream
   // Initial header
@@ -1380,7 +1381,7 @@
 
 extern void resync_audio_stream(sh_audio_t *sh_audio);
 
-void demux_ogg_seek(demuxer_t *demuxer,float rel_seek_secs,int flags) {
+static void demux_ogg_seek(demuxer_t *demuxer,float rel_seek_secs,int flags) {
   ogg_demuxer_t* ogg_d = demuxer->priv;
   ogg_sync_state* sync = &ogg_d->sync;
   ogg_page* page= &ogg_d->page;
@@ -1557,7 +1558,7 @@
 
 }
 
-void demux_close_ogg(demuxer_t* demuxer) {
+static void demux_close_ogg(demuxer_t* demuxer) {
   ogg_demuxer_t* ogg_d = demuxer->priv;
   int i;
 
@@ -1587,7 +1588,7 @@
   free(ogg_d);
 }
 
-int demux_ogg_control(demuxer_t *demuxer,int cmd, void *arg){
+static int demux_ogg_control(demuxer_t *demuxer,int cmd, void *arg){
   ogg_demuxer_t* ogg_d = demuxer->priv;
   ogg_stream_t* os;
   float rate;
@@ -1617,4 +1618,22 @@
     }
 }
 
+
+
+demuxer_desc_t demuxer_desc_ogg = {
+  "Ogg demuxer",
+  "ogg",
+  "Ogg",
+  "?",
+  "",
+  DEMUXER_TYPE_OGG,
+  1, // safe autodetect
+  demux_ogg_open,
+  demux_ogg_fill_buffer,
+  NULL,
+  demux_close_ogg,
+  demux_ogg_seek,
+  demux_ogg_control
+};
+
 #endif
--- a/libmpdemux/demux_pva.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_pva.c	Fri Aug 05 19:57:47 2005 +0000
@@ -104,7 +104,7 @@
 	}
 }
 
-int pva_check_file(demuxer_t * demuxer)
+static int pva_check_file(demuxer_t * demuxer)
 {
 	uint8_t buffer[5]={0,0,0,0,0};
 	mp_msg(MSGT_DEMUX, MSGL_V, "Checking for PVA\n");
@@ -112,7 +112,7 @@
 	if(buffer[0]=='A' && buffer[1] == 'V' && buffer[4] == 0x55)
 	{
 		mp_msg(MSGT_DEMUX,MSGL_DBG2, "Success: PVA\n");
-		return 1;
+		return DEMUXER_TYPE_PVA;
 	}
 	else
 	{
@@ -121,7 +121,7 @@
 	}
 }
 
-demuxer_t * demux_open_pva (demuxer_t * demuxer)
+static demuxer_t * demux_open_pva (demuxer_t * demuxer)
 {
 	sh_video_t *sh_video = new_sh_video(demuxer,0);
         sh_audio_t *sh_audio = new_sh_audio(demuxer,0);
@@ -189,7 +189,7 @@
 
 // 0 = EOF or no stream found
 // 1 = successfully read a packet
-int demux_pva_fill_buffer (demuxer_t * demux)
+static int demux_pva_fill_buffer (demuxer_t * demux, demux_stream_t *ds)
 {
 	uint8_t done=0;
 	demux_packet_t * dp;
@@ -466,7 +466,7 @@
 	return 1;
 }
 
-int demux_seek_pva(demuxer_t * demuxer,float rel_seek_secs,int flags)
+static int demux_seek_pva(demuxer_t * demuxer,float rel_seek_secs,int flags)
 {
 	int total_bitrate=0;
 	off_t dest_offset;
@@ -507,7 +507,7 @@
 
 
 
-void demux_close_pva(demuxer_t * demuxer)
+static void demux_close_pva(demuxer_t * demuxer)
 {
 	if(demuxer->priv)
 	{
@@ -516,3 +516,19 @@
 	}
 }
 			
+
+demuxer_desc_t demuxer_desc_pva = {
+  "PVA demuxer",
+  "pva",
+  "PVA",
+  "Matteo Giani",
+  "streams from DVB cards",
+  DEMUXER_TYPE_PVA,
+  0, // unsafe autodetect
+  pva_check_file,
+  demux_pva_fill_buffer,
+  demux_open_pva,
+  demux_close_pva,
+  demux_seek_pva,
+  NULL
+};
--- a/libmpdemux/demux_rawaudio.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_rawaudio.c	Fri Aug 05 19:57:47 2005 +0000
@@ -33,7 +33,7 @@
 
 extern void resync_audio_stream(sh_audio_t *sh_audio);
 
-int demux_rawaudio_open(demuxer_t* demuxer) {
+static demuxer_t* demux_rawaudio_open(demuxer_t* demuxer) {
   sh_audio_t* sh_audio;
   WAVEFORMATEX* w;
 
@@ -59,10 +59,10 @@
   demuxer->audio->sh = sh_audio;
   sh_audio->ds = demuxer->audio;
 
-  return 1;
+  return demuxer;
 }
 
-int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
+static int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
   sh_audio_t* sh_audio = demuxer->audio->sh;
   int l = sh_audio->wf->nAvgBytesPerSec;
   off_t spos = stream_tell(demuxer->stream);
@@ -82,7 +82,7 @@
   return 1;
 }
 
-void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
   stream_t* s = demuxer->stream;
   sh_audio_t* sh_audio = demuxer->audio->sh;
   off_t base,pos;
@@ -99,3 +99,20 @@
   resync_audio_stream(sh_audio);
 //  printf("demux_rawaudio: streamtell=%d\n",(int)stream_tell(demuxer->stream));
 }
+
+
+demuxer_desc_t demuxer_desc_rawaudio = {
+  "Raw audio demuxer",
+  "rawaudio",
+  "rawaudio",
+  "?",
+  "",
+  DEMUXER_TYPE_RAWAUDIO,
+  0, // no autodetect
+  NULL,
+  demux_rawaudio_fill_buffer,
+  demux_rawaudio_open,
+  NULL,
+  demux_rawaudio_seek,
+  NULL
+};
--- a/libmpdemux/demux_rawdv.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_rawdv.c	Fri Aug 05 19:57:47 2005 +0000
@@ -36,7 +36,7 @@
    dv_decoder_t *decoder;
 } rawdv_frames_t;
 
-void demux_seek_rawdv(demuxer_t *demuxer,float rel_seek_secs,int flags)
+static void demux_seek_rawdv(demuxer_t *demuxer,float rel_seek_secs,int flags)
 {
    rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv;
    sh_video_t *sh_video = demuxer->video->sh;
@@ -59,7 +59,7 @@
    frames->current_filepos=newpos*frames->frame_size;
 }
 
-int rawdv_check_file(demuxer_t *demuxer)
+static int rawdv_check_file(demuxer_t *demuxer)
 {
    unsigned char tmp_buffer[DV_PAL_FRAME_SIZE];
    int bytes_read=0;
@@ -86,13 +86,16 @@
        && ((td->height==576) || (td->height==480)))
       result=1;
    dv_decoder_free(td);
-   return result;
+   if (result)
+      return DEMUXER_TYPE_RAWDV;
+   else
+      return 0;
 }
 
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_rawdv_fill_buffer(demuxer_t *demuxer)
+static int demux_rawdv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
 {
    rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv;
    demux_packet_t* dp_video=NULL;
@@ -125,7 +128,7 @@
    return 1;
 }
 
-demuxer_t* demux_open_rawdv(demuxer_t* demuxer)
+static demuxer_t* demux_open_rawdv(demuxer_t* demuxer)
 {
    unsigned char dv_frame[DV_PAL_FRAME_SIZE];
    sh_video_t *sh_video = NULL;
@@ -216,7 +219,7 @@
    return demuxer;
 }
 
-void demux_close_rawdv(demuxer_t* demuxer)
+static void demux_close_rawdv(demuxer_t* demuxer)
 {
    rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv;
 
@@ -225,7 +228,7 @@
   free(frames);
 }
 
-int demux_rawdv_control(demuxer_t *demuxer,int cmd, void *arg) {
+static int demux_rawdv_control(demuxer_t *demuxer,int cmd, void *arg) {
     rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv;
     sh_video_t *sh_video=demuxer->video->sh;
 
@@ -243,4 +246,21 @@
     }
 }
 
+
+demuxer_desc_t demuxer_desc_rawdv = {
+  "Raw DV demuxer",
+  "rawdv",
+  "RAWDV",
+  "Alexander Neundorf",
+  "",
+  DEMUXER_TYPE_RAWDV,
+  0, // unsafe autodetect
+  rawdv_check_file,
+  demux_rawdv_fill_buffer,
+  demux_open_rawdv,
+  demux_close_rawdv,
+  demux_seek_rawdv,
+  demux_rawdv_control
+};
+
 #endif
--- a/libmpdemux/demux_rawvideo.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_rawvideo.c	Fri Aug 05 19:57:47 2005 +0000
@@ -53,7 +53,7 @@
 };
 
 
-int demux_rawvideo_open(demuxer_t* demuxer) {
+static demuxer_t* demux_rawvideo_open(demuxer_t* demuxer) {
   sh_video_t* sh_video;
 
   switch(size_id){
@@ -100,10 +100,10 @@
   demuxer->video->sh = sh_video;
   sh_video->ds = demuxer->video;
 
-  return 1;
+  return demuxer;
 }
 
-int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
+static int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
   sh_video_t* sh = demuxer->video->sh;
   off_t pos;
   if(demuxer->stream->eof) return 0;
@@ -113,7 +113,7 @@
   return 1;
 }
 
-void demux_rawvideo_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_rawvideo_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
   stream_t* s = demuxer->stream;
   sh_video_t* sh_video = demuxer->video->sh;
   off_t pos;
@@ -131,3 +131,20 @@
   demuxer->video->pts = pos * sh_video->frametime;
 //  printf("demux_rawvideo: streamtell=%d\n",(int)stream_tell(demuxer->stream));
 }
+
+
+demuxer_desc_t demuxer_desc_rawvideo = {
+  "Raw video demuxer",
+  "rawvideo",
+  "rawvideo",
+  "?",
+  "",
+  DEMUXER_TYPE_RAWVIDEO,
+  0, // no autodetect
+  NULL,
+  demux_rawvideo_fill_buffer,
+  demux_rawvideo_open,
+  NULL,
+  demux_rawvideo_seek,
+  NULL
+};
--- a/libmpdemux/demux_real.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_real.c	Fri Aug 05 19:57:47 2005 +0000
@@ -433,7 +433,7 @@
 #endif
 
 
-int real_check_file(demuxer_t* demuxer)
+static int real_check_file(demuxer_t* demuxer)
 {
     real_priv_t *priv;
     int c;
@@ -450,7 +450,7 @@
     memset(priv, 0, sizeof(real_priv_t));
     demuxer->priv = priv;
 
-    return 1;
+    return DEMUXER_TYPE_REAL;
 }
 
 void hexdump(char *, unsigned long);
@@ -517,7 +517,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_real_fill_buffer(demuxer_t *demuxer)
+static int demux_real_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds)
 {
     real_priv_t *priv = demuxer->priv;
     demux_stream_t *ds = NULL;
@@ -956,7 +956,7 @@
 
 extern void print_wave_header(WAVEFORMATEX *h);
 
-void demux_open_real(demuxer_t* demuxer)
+static demuxer_t* demux_open_real(demuxer_t* demuxer)
 {
     real_priv_t* priv = demuxer->priv;
     int num_of_headers;
@@ -1730,9 +1730,10 @@
 	    sh->disp_w,sh->disp_h,sh->aspect,sh->fps);
     }
 
+    return demuxer;
 }
 
-void demux_close_real(demuxer_t *demuxer)
+static void demux_close_real(demuxer_t *demuxer)
 {
     int i;
     real_priv_t* priv = demuxer->priv;
@@ -1750,7 +1751,7 @@
 extern void resync_audio_stream(sh_audio_t * sh_audio);
 
 /* please upload RV10 samples WITH INDEX CHUNK */
-int demux_seek_real(demuxer_t *demuxer, float rel_seek_secs, int flags)
+static int demux_seek_real(demuxer_t *demuxer, float rel_seek_secs, int flags)
 {
     real_priv_t *priv = demuxer->priv;
     demux_stream_t *d_audio = demuxer->audio;
@@ -1838,13 +1839,13 @@
     if (next_offset)
         stream_seek(demuxer->stream, next_offset);
 
-    demux_real_fill_buffer(demuxer);
+    demux_real_fill_buffer(demuxer, NULL);
     if (sh_audio)
         resync_audio_stream(sh_audio);
     return 1;
 }
 
-int demux_real_control(demuxer_t *demuxer, int cmd, void *arg)
+static int demux_real_control(demuxer_t *demuxer, int cmd, void *arg)
 {
     real_priv_t *priv = demuxer->priv;
     int lastpts = priv->v_pts ? priv->v_pts : priv->a_pts;
@@ -1868,3 +1869,20 @@
 	    return DEMUXER_CTRL_NOTIMPL;
     }
 }
+
+
+demuxer_desc_t demuxer_desc_real = {
+  "Realmedia demuxer",
+  "real",
+  "REAL",
+  "Alex Beregszasi, Florian Schneider, A'rpi, Roberto Togni",
+  "handles new .RMF files",
+  DEMUXER_TYPE_REAL,
+  1, // safe autodetect
+  real_check_file,
+  demux_real_fill_buffer,
+  demux_open_real,
+  demux_close_real,
+  demux_seek_real,
+  demux_real_control
+};
--- a/libmpdemux/demux_realaud.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_realaud.c	Fri Aug 05 19:57:47 2005 +0000
@@ -40,13 +40,13 @@
 
 
 
-int ra_check_file(demuxer_t* demuxer)
+static int ra_check_file(demuxer_t* demuxer)
 {
 	unsigned int chunk_id;
   
 	chunk_id = stream_read_dword_le(demuxer->stream);
 	if (chunk_id == FOURCC_DOTRA)
-		return 1;
+		return DEMUXER_TYPE_REALAUDIO;
 	else
 		return 0;
 }
@@ -58,7 +58,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_ra_fill_buffer(demuxer_t *demuxer)
+static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds)
 {
 	ra_priv_t *ra_priv = demuxer->priv;
 	int len;
@@ -92,7 +92,7 @@
 
 
 
-int demux_open_ra(demuxer_t* demuxer)
+static demuxer_t* demux_open_ra(demuxer_t* demuxer)
 {
 	ra_priv_t* ra_priv = demuxer->priv;
 	sh_audio_t *sh;
@@ -264,12 +264,12 @@
 	if(!ds_fill_buffer(demuxer->audio))
 		mp_msg(MSGT_DEMUXER,MSGL_INFO,"[RealAudio] No data.\n");
 
-    return 1;
+    return demuxer;
 }
 
 
 
-void demux_close_ra(demuxer_t *demuxer)
+static void demux_close_ra(demuxer_t *demuxer)
 {
 	ra_priv_t* ra_priv = demuxer->priv;
  
@@ -295,3 +295,20 @@
     return stream_seek(demuxer->stream, next_offset);
 }
 #endif
+
+
+demuxer_desc_t demuxer_desc_realaudio = {
+  "Realaudio demuxer",
+  "realaudio",
+  "REALAUDIO",
+  "Roberto Togni",
+  "handles old audio only .ra files",
+  DEMUXER_TYPE_REALAUDIO,
+  1, // safe autodetect
+  ra_check_file,
+  demux_ra_fill_buffer,
+  demux_open_ra,
+  demux_close_ra,
+  NULL,
+  NULL
+};
--- a/libmpdemux/demux_roq.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_roq.c	Fri Aug 05 19:57:47 2005 +0000
@@ -48,11 +48,11 @@
 // Check if a stream qualifies as a RoQ file based on the magic numbers
 // at the start of the file:
 //  84 10 FF FF FF FF xx xx
-int roq_check_file(demuxer_t *demuxer)
+static int roq_check_file(demuxer_t *demuxer)
 {
   if ((stream_read_dword(demuxer->stream) == 0x8410FFFF) &&
       ((stream_read_dword(demuxer->stream) & 0xFFFF0000) == 0xFFFF0000))
-    return 1;
+    return DEMUXER_TYPE_ROQ;
   else
     return 0;
 }
@@ -60,7 +60,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_roq_fill_buffer(demuxer_t *demuxer)
+static int demux_roq_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
 {
   sh_video_t *sh_video = demuxer->video->sh;
   roq_data_t *roq_data = (roq_data_t *)demuxer->priv;
@@ -87,7 +87,7 @@
   return 1;
 }
 
-demuxer_t* demux_open_roq(demuxer_t* demuxer)
+static demuxer_t* demux_open_roq(demuxer_t* demuxer)
 {
   sh_video_t *sh_video = NULL;
   sh_audio_t *sh_audio = NULL;
@@ -240,7 +240,7 @@
   return demuxer;
 }
 
-void demux_close_roq(demuxer_t* demuxer) {
+static void demux_close_roq(demuxer_t* demuxer) {
   roq_data_t *roq_data = demuxer->priv;
 
   if(!roq_data)
@@ -248,3 +248,19 @@
   free(roq_data);
 }
   
+
+demuxer_desc_t demuxer_desc_roq = {
+  "RoQ demuxer",
+  "roq",
+  "ROQ",
+  "Mike Melanson",
+  "",
+  DEMUXER_TYPE_ROQ,
+  0, // unsafe autodetect
+  roq_check_file,
+  demux_roq_fill_buffer,
+  demux_open_roq,
+  demux_close_roq,
+  NULL,
+  NULL
+};
--- a/libmpdemux/demux_rtp.cpp	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_rtp.cpp	Fri Aug 05 19:57:47 2005 +0000
@@ -577,3 +577,20 @@
 
   return dp;
 }
+
+
+demuxer_desc_t demuxer_desc_rtp = {
+  "live.com RTP demuxer",
+  "rtp",
+  "",
+  "Ross Finlayson",
+  "requires live.com library",
+  DEMUXER_TYPE_RTP,
+  0, // no autodetect
+  NULL,
+  demux_rtp_fill_buffer,
+  demux_open_rtp,
+  demux_close_rtp,
+  NULL,
+  NULL
+};
--- a/libmpdemux/demux_smjpeg.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_smjpeg.c	Fri Aug 05 19:57:47 2005 +0000
@@ -22,7 +22,7 @@
 #include "stheader.h"
 #include "bswap.h"
 
-int smjpeg_check_file(demuxer_t* demuxer){
+static int smjpeg_check_file(demuxer_t* demuxer){
     int orig_pos = stream_tell(demuxer->stream);
     char buf[8];
     int version;
@@ -52,14 +52,14 @@
     
     stream_seek(demuxer->stream, orig_pos);
 
-    return 1;
+    return DEMUXER_TYPE_SMJPEG;
 }
 
 
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_smjpeg_fill_buffer(demuxer_t *demux)
+static int demux_smjpeg_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
 {
     int dtype, dsize, dpts;
 
@@ -89,7 +89,7 @@
     return 1;
 }
 
-int demux_open_smjpeg(demuxer_t* demuxer){
+static demuxer_t* demux_open_smjpeg(demuxer_t* demuxer){
     sh_video_t* sh_video;
     sh_audio_t* sh_audio;
     unsigned int htype = 0, hleng;
@@ -164,10 +164,27 @@
 
     demuxer->seekable = 0;
     
-    return 1;
+    return demuxer;
 }
 
-void demux_close_smjpeg(demuxer_t *demuxer)
+static void demux_close_smjpeg(demuxer_t *demuxer)
 {
     return;
 }
+
+
+demuxer_desc_t demuxer_desc_smjpeg = {
+  "smjpeg demuxer",
+  "smjpeg",
+  "SMJPEG",
+  "Alex Beregszasi",
+  "",
+  DEMUXER_TYPE_SMJPEG,
+  1, // safe autodetect
+  smjpeg_check_file,
+  demux_smjpeg_fill_buffer,
+  demux_open_smjpeg,
+  demux_close_smjpeg,
+  NULL,
+  NULL
+};
--- a/libmpdemux/demux_ts.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_ts.c	Fri Aug 05 19:57:47 2005 +0000
@@ -263,7 +263,7 @@
 
 
 
-int ts_check_file(demuxer_t * demuxer)
+static int ts_check_file(demuxer_t * demuxer)
 {
 	const int buf_size = (TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS);
 	unsigned char buf[TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS], done = 0, *ptr;
@@ -360,9 +360,9 @@
 	mp_msg(MSGT_DEMUX, MSGL_V, "GOOD CC: %d, BAD CC: %d\n", good, bad);
 
 	if(good >= bad)
-		return size;
+			return size;
 	else
-		return 0;
+			return 0;
 }
 
 
@@ -827,7 +827,7 @@
 	return 1;
 }
 
-demuxer_t *demux_open_ts(demuxer_t * demuxer)
+static demuxer_t *demux_open_ts(demuxer_t * demuxer)
 {
 	int i;
 	uint8_t packet_size;
@@ -984,7 +984,7 @@
 	return demuxer;
 }
 
-void demux_close_ts(demuxer_t * demuxer)
+static void demux_close_ts(demuxer_t * demuxer)
 {
 	uint16_t i;
 	ts_priv_t *priv = (ts_priv_t*) demuxer->priv;
@@ -3028,7 +3028,7 @@
 extern int sync_video_packet(demux_stream_t *);
 extern int skip_video_packet(demux_stream_t *);
 
-void demux_seek_ts(demuxer_t *demuxer, float rel_seek_secs, int flags)
+static void demux_seek_ts(demuxer_t *demuxer, float rel_seek_secs, int flags)
 {
 	demux_stream_t *d_audio=demuxer->audio;
 	demux_stream_t *d_video=demuxer->video;
@@ -3129,7 +3129,7 @@
 }
 
 
-int demux_ts_fill_buffer(demuxer_t * demuxer)
+static int demux_ts_fill_buffer(demuxer_t * demuxer, demux_stream_t *ds)
 {
 	ES_stream_t es;
 	ts_priv_t *priv = (ts_priv_t *)demuxer->priv;
@@ -3138,4 +3138,24 @@
 }
 
 
-
+static int ts_check_file_dmx(demuxer_t *demuxer)
+{
+    return ts_check_file(demuxer) ? DEMUXER_TYPE_MPEG_TS : 0;
+}
+
+
+demuxer_desc_t demuxer_desc_mpeg_ts = {
+  "MPEG-TS demuxer",
+  "mpegts",
+  "TS",
+  "Nico Sabbi",
+  "",
+  DEMUXER_TYPE_MPEG_TS,
+  0, // unsafe autodetect
+  ts_check_file_dmx,
+  demux_ts_fill_buffer,
+  demux_open_ts,
+  demux_close_ts,
+  demux_seek_ts,
+  NULL
+};
--- a/libmpdemux/demux_ty.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_ty.c	Fri Aug 05 19:57:47 2005 +0000
@@ -585,7 +585,7 @@
 static unsigned char ty_MPEGAudioPacket[] = { 0x00, 0x00, 0x01, 0xc0 };
 static unsigned char ty_AC3AudioPacket[] = { 0x00, 0x00, 0x01, 0xbd };
 
-int demux_ty_fill_buffer( demuxer_t *demux )
+static int demux_ty_fill_buffer( demuxer_t *demux, demux_stream_t *dsds )
 {
    int              invalidType = 0;
    int              errorHeader = 0;
@@ -1238,7 +1238,7 @@
    return( 1 );
 }
 
-void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, int flags )
+static void demux_seek_ty( demuxer_t *demuxer, float rel_seek_secs, int flags )
 {
    demux_stream_t *d_audio = demuxer->audio;
    demux_stream_t *d_video = demuxer->video;
@@ -1362,7 +1362,7 @@
 }
 
 
-int demux_close_ty( demuxer_t *demux )
+static int demux_close_ty( demuxer_t *demux )
 {
    TiVoInfo         *tivo = 0;
 
@@ -1377,3 +1377,44 @@
 }
 
 
+static int ty_check_file(demuxer_t* demuxer)
+{
+  return ds_fill_buffer(demuxer->video) ? DEMUXER_TYPE_MPEG_TY : 0;
+}
+
+
+static demuxer_t* demux_open_ty(demuxer_t* demuxer)
+{
+    sh_audio_t *sh_audio=NULL;
+    sh_video_t *sh_video=NULL;
+
+    sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
+
+    if(demuxer->audio->id!=-2) {
+        if(!ds_fill_buffer(demuxer->audio)){
+            mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);
+            demuxer->audio->sh=NULL;
+        } else {
+            sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
+        }
+    }
+
+    return demuxer;
+}
+
+
+demuxer_desc_t demuxer_desc_mpeg_ty = {
+  "TiVo demuxer",
+  "tivo",
+  "TiVo",
+  "Christopher R. Wingert",
+  "Demux streams from TiVo",
+  DEMUXER_TYPE_MPEG_TY,
+  0, // unsafe autodetect
+  ty_check_file,
+  demux_ty_fill_buffer,
+  demux_open_ty,
+  demux_close_ty,
+  demux_seek_ty,
+  demux_ty_control
+};
--- a/libmpdemux/demux_viv.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_viv.c	Fri Aug 05 19:57:47 2005 +0000
@@ -221,7 +221,7 @@
 	free(param);
 }
 
-int vivo_check_file(demuxer_t* demuxer){
+static int vivo_check_file(demuxer_t* demuxer){
     int i=0;
     int len;
     int c;
@@ -281,7 +281,7 @@
 
     stream_seek(demuxer->stream, orig_pos);
 
-return 1;
+return DEMUXER_TYPE_VIVO;
 }
 
 static int audio_pos=0;
@@ -290,7 +290,7 @@
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_vivo_fill_buffer(demuxer_t *demux){
+static int demux_vivo_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
   demux_stream_t *ds=NULL;
   int c;
   int len=0;
@@ -537,12 +537,12 @@
 
 
 
-void demux_open_vivo(demuxer_t* demuxer){
+static demuxer_t* demux_open_vivo(demuxer_t* demuxer){
     vivo_priv_t* priv=demuxer->priv;
 
   if(!ds_fill_buffer(demuxer->video)){
     mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingVideoStreamBug);
-    return;
+    return NULL;
   }
 
     audio_pos=0;
@@ -714,13 +714,13 @@
 		sh->ds=demuxer->audio;
 		demuxer->audio->id=1;
 nosound:
-		return;
+		return demuxer;
 }
 }
+    return demuxer;
+}
 
-}
-
-void demux_close_vivo(demuxer_t *demuxer)
+static void demux_close_vivo(demuxer_t *demuxer)
 {
     vivo_priv_t* priv=demuxer->priv;
  
@@ -737,3 +737,20 @@
     }
     return;
 }
+
+
+demuxer_desc_t demuxer_desc_vivo = {
+  "Vivo demuxer",
+  "vivo",
+  "VIVO",
+  "A'rpi, Alex Beregszasi",
+  "",
+  DEMUXER_TYPE_VIVO,
+  0, // unsafe autodetect
+  vivo_check_file,
+  demux_vivo_fill_buffer,
+  demux_open_vivo,
+  demux_close_vivo,
+  NULL,
+  NULL
+};
--- a/libmpdemux/demux_vqf.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_vqf.c	Fri Aug 05 19:57:47 2005 +0000
@@ -11,18 +11,18 @@
 
 extern void resync_audio_stream(sh_audio_t *sh_audio);
 
-int demux_probe_vqf(demuxer_t* demuxer) 
+static int demux_probe_vqf(demuxer_t* demuxer) 
 {
   char buf[KEYWORD_BYTES];
   stream_t *s;
   s = demuxer->stream;
   if(stream_read(s,buf,KEYWORD_BYTES)!=KEYWORD_BYTES)
     return 0;
-  if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return 1; /*version: 97012000*/
+  if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return DEMUXER_TYPE_VQF; /*version: 97012000*/
   return 0;
 }
 
-demuxer_t* demux_open_vqf(demuxer_t* demuxer) {
+static demuxer_t* demux_open_vqf(demuxer_t* demuxer) {
   sh_audio_t* sh_audio;
   WAVEFORMATEX* w;
   stream_t *s;
@@ -161,7 +161,7 @@
   return demuxer;
 }
 
-int demux_vqf_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
+static int demux_vqf_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
   sh_audio_t* sh_audio = demuxer->audio->sh;
   int l = sh_audio->wf->nAvgBytesPerSec;
   off_t spos = stream_tell(demuxer->stream);
@@ -181,7 +181,7 @@
   return 1;
 }
 
-void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,int flags){
 #if 0
   stream_t* s = demuxer->stream;
   sh_audio_t* sh_audio = demuxer->audio->sh;
@@ -199,4 +199,21 @@
 #endif
 }
 
-void demux_close_vqf(demuxer_t* demuxer) {}
+static void demux_close_vqf(demuxer_t* demuxer) {}
+
+
+demuxer_desc_t demuxer_desc_vqf = {
+  "TwinVQ demuxer",
+  "vqf",
+  "VQF",
+  "Nick Kurshev",
+  "ported frm MPlayerXP",
+  DEMUXER_TYPE_VQF,
+  1, // safe autodetect
+  demux_probe_vqf,
+  demux_vqf_fill_buffer,
+  demux_open_vqf,
+  demux_close_vqf,
+  demux_seek_vqf,
+  NULL
+};
--- a/libmpdemux/demux_xmms.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_xmms.c	Fri Aug 05 19:57:47 2005 +0000
@@ -201,7 +201,7 @@
 
 //extern void resync_audio_stream(sh_audio_t *sh_audio);
 
-int demux_xmms_open(demuxer_t* demuxer) {
+static int demux_xmms_open(demuxer_t* demuxer) {
   InputPlugin* ip = NULL;
   sh_audio_t* sh_audio;
   WAVEFORMATEX* w;
@@ -267,10 +267,10 @@
   w->nBlockAlign = sh_audio->samplesize*sh_audio->channels;
   w->cbSize = 0;
   
-  return 1;
+  return DEMUXER_TYPE_XMMS;
 }
 
-int demux_xmms_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
+static int demux_xmms_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
   sh_audio_t *sh_audio = demuxer->audio->sh;
   xmms_priv_t *priv=demuxer->priv;
   demux_packet_t*  dp;
@@ -299,7 +299,7 @@
   return 1;
 }
 
-void demux_xmms_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+static void demux_xmms_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
   stream_t* s = demuxer->stream;
   sh_audio_t* sh_audio = demuxer->audio->sh;
   xmms_priv_t *priv=demuxer->priv;
@@ -321,7 +321,7 @@
   sh_audio->delay=pos; //priv->spos / sh_audio->wf->nAvgBytesPerSec;
 }
 
-int demux_close_xmms(demuxer_t* demuxer) {
+static void demux_close_xmms(demuxer_t* demuxer) {
   xmms_priv_t *priv=demuxer->priv;
   xmms_playing=0;
   xmms_audiopos=0; // xmp on exit waits until buffer is free enough
@@ -331,10 +331,9 @@
     free(priv); xmms_priv=demuxer->priv=NULL;
   }
   cleanup_plugins();
-  return 1;
 }
 
-int demux_xmms_control(demuxer_t *demuxer,int cmd, void *arg){
+static int demux_xmms_control(demuxer_t *demuxer,int cmd, void *arg){
     demux_stream_t *d_video=demuxer->video;
     sh_audio_t *sh_audio=demuxer->audio->sh;
     xmms_priv_t *priv=demuxer->priv;
@@ -355,3 +354,20 @@
 	    return DEMUXER_CTRL_NOTIMPL;
     }
 }
+
+
+demuxer_desc_t demuxer_desc_xmms = {
+  "XMMS demuxer",
+  "xmms",
+  "XMMS",
+  "?",
+  "requires XMMS plugins",
+  DEMUXER_TYPE_XMMS,
+  0, // safe autodetect
+  demux_xmms_open,
+  demux_xmms_fill_buffer,
+  NULL,
+  demux_close_xmms,
+  demux_xmms_seek,
+  demux_xmms_control
+};
--- a/libmpdemux/demux_y4m.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demux_y4m.c	Fri Aug 05 19:57:47 2005 +0000
@@ -23,7 +23,7 @@
     int is_older;
 } y4m_priv_t;
 
-int y4m_check_file(demuxer_t* demuxer){
+static int y4m_check_file(demuxer_t* demuxer){
     int orig_pos = stream_tell(demuxer->stream);
     char buf[10];
     y4m_priv_t* priv;
@@ -54,14 +54,14 @@
 
     stream_seek(demuxer->stream, orig_pos);
 
-    return 1;
+    return DEMUXER_TYPE_Y4M;
 }
 
 
 // return value:
 //     0 = EOF or no stream found
 //     1 = successfully read a packet
-int demux_y4m_fill_buffer(demuxer_t *demux) {
+static int demux_y4m_fill_buffer(demuxer_t *demux, demux_stream_t *dsds) {
   demux_stream_t *ds=demux->video;
   demux_packet_t *dp;
   y4m_priv_t *priv=demux->priv;
@@ -117,7 +117,7 @@
   return 1;
 }
 
-void demux_open_y4m(demuxer_t* demuxer){
+static demuxer_t* demux_open_y4m(demuxer_t* demuxer){
     y4m_priv_t* priv = demuxer->priv;
     y4m_ratio_t ratio;
     sh_video_t* sh=new_sh_video(demuxer,0);
@@ -227,9 +227,11 @@
     mp_msg(MSGT_DEMUX, MSGL_INFO, "YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n",
             demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
             sh->bih->biHeight);
+
+    return demuxer;
 }
 
-int demux_seek_y4m(demuxer_t *demuxer, float rel_seek_secs, int flags) {
+static void demux_seek_y4m(demuxer_t *demuxer, float rel_seek_secs, int flags) {
     sh_video_t* sh = demuxer->video->sh;
     y4m_priv_t* priv = demuxer->priv;
     int rel_seek_frames = sh->fps*rel_seek_secs;
@@ -254,10 +256,9 @@
 	     * is disabled. */
 	    mp_msg(MSGT_DEMUX, MSGL_WARN, "Seeking for YUV4MPEG2 not yet implemented!\n");
     }
-    return 0; 
 }
 
-void demux_close_y4m(demuxer_t *demuxer)
+static void demux_close_y4m(demuxer_t *demuxer)
 {
     y4m_priv_t* priv = demuxer->priv;
 
@@ -269,3 +270,20 @@
     free(demuxer->priv);
     return;
 }
+
+
+demuxer_desc_t demuxer_desc_y4m = {
+  "YUV4MPEG2 demuxer",
+  "y4m",
+  "YUV4MPEG2",
+  "Rik snel",
+  "",
+  DEMUXER_TYPE_Y4M,
+  1, // safe autodetect
+  y4m_check_file,
+  demux_y4m_fill_buffer,
+  demux_open_y4m,
+  demux_close_y4m,
+  demux_seek_y4m,
+  NULL
+};
--- a/libmpdemux/demuxer.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demuxer.c	Fri Aug 05 19:57:47 2005 +0000
@@ -21,6 +21,105 @@
 #include "../libaf/af_format.h"
 #include "../libvo/fastmemcpy.h"
 
+
+// Demuxer list
+extern demuxer_desc_t demuxer_desc_rawaudio;
+extern demuxer_desc_t demuxer_desc_rawvideo;
+extern demuxer_desc_t demuxer_desc_tv;
+extern demuxer_desc_t demuxer_desc_mf;
+extern demuxer_desc_t demuxer_desc_avi;
+extern demuxer_desc_t demuxer_desc_y4m;
+extern demuxer_desc_t demuxer_desc_asf;
+extern demuxer_desc_t demuxer_desc_nsv;
+extern demuxer_desc_t demuxer_desc_nuv;
+extern demuxer_desc_t demuxer_desc_real;
+extern demuxer_desc_t demuxer_desc_smjpeg;
+extern demuxer_desc_t demuxer_desc_matroska;
+extern demuxer_desc_t demuxer_desc_realaudio;
+extern demuxer_desc_t demuxer_desc_vqf;
+extern demuxer_desc_t demuxer_desc_mov;
+extern demuxer_desc_t demuxer_desc_vivo;
+extern demuxer_desc_t demuxer_desc_fli;
+extern demuxer_desc_t demuxer_desc_film;
+extern demuxer_desc_t demuxer_desc_roq;
+extern demuxer_desc_t demuxer_desc_gif;
+extern demuxer_desc_t demuxer_desc_ogg;
+extern demuxer_desc_t demuxer_desc_avs;
+extern demuxer_desc_t demuxer_desc_pva;
+extern demuxer_desc_t demuxer_desc_mpeg_ts;
+extern demuxer_desc_t demuxer_desc_lmlm4;
+extern demuxer_desc_t demuxer_desc_mpeg_ps;
+extern demuxer_desc_t demuxer_desc_mpeg_pes;
+extern demuxer_desc_t demuxer_desc_mpeg_es;
+extern demuxer_desc_t demuxer_desc_mpeg4_es;
+extern demuxer_desc_t demuxer_desc_h264_es;
+extern demuxer_desc_t demuxer_desc_rawdv;
+extern demuxer_desc_t demuxer_desc_audio;
+extern demuxer_desc_t demuxer_desc_xmms;
+extern demuxer_desc_t demuxer_desc_mpeg_ty;
+extern demuxer_desc_t demuxer_desc_rtp;
+extern demuxer_desc_t demuxer_desc_lavf;
+extern demuxer_desc_t demuxer_desc_aac;
+
+demuxer_desc_t* demuxer_list[] = {
+  &demuxer_desc_rawaudio,
+  &demuxer_desc_rawvideo,
+#ifdef USE_TV
+  &demuxer_desc_tv,
+#endif
+  &demuxer_desc_mf,
+  &demuxer_desc_avi,
+  &demuxer_desc_y4m,
+  &demuxer_desc_asf,
+  &demuxer_desc_nsv,
+  &demuxer_desc_nuv,
+  &demuxer_desc_real,
+  &demuxer_desc_smjpeg,
+#ifdef HAVE_MATROSKA
+  &demuxer_desc_matroska,
+#endif
+  &demuxer_desc_realaudio,
+  &demuxer_desc_vqf,
+  &demuxer_desc_mov,
+  &demuxer_desc_vivo,
+  &demuxer_desc_fli,
+  &demuxer_desc_film,
+  &demuxer_desc_roq,
+#ifdef HAVE_GIF
+  &demuxer_desc_gif,
+#endif
+#ifdef HAVE_OGGVORBIS
+  &demuxer_desc_ogg,
+#endif
+#ifdef USE_WIN32DLL
+  &demuxer_desc_avs,
+#endif
+  &demuxer_desc_pva,
+  &demuxer_desc_mpeg_ts,
+  &demuxer_desc_lmlm4,
+  &demuxer_desc_mpeg_ps,
+  &demuxer_desc_mpeg_pes,
+  &demuxer_desc_mpeg_es,
+  &demuxer_desc_mpeg4_es,
+  &demuxer_desc_h264_es,
+#ifdef HAVE_LIBDV095
+  &demuxer_desc_rawdv,
+#endif
+  &demuxer_desc_audio,
+#ifdef HAVE_XMMS
+  &demuxer_desc_xmms,
+#endif
+  &demuxer_desc_mpeg_ty,
+#ifdef STREAMING_LIVE_DOT_COM
+  &demuxer_desc_rtp,
+#endif
+#ifdef USE_LIBAVFORMAT
+  &demuxer_desc_lavf,
+#endif
+  &demuxer_desc_aac,
+  NULL
+};
+
 // Should be set to 1 by demux module if ids it passes to new_sh_audio and
 // new_sh_video don't match aids and vids it accepts from the command line
 int demux_aid_vid_mismatch = 0;
@@ -56,7 +155,26 @@
   return ds;
 }
 
-demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id){
+
+/**
+ * Get demuxer description structure for a given demuxer type
+ *
+ * @param file_format    type of the demuxer
+ * @return               structure for the demuxer, NULL if not found
+ */
+static demuxer_desc_t* get_demuxer_desc_from_type(int file_format)
+{
+  int i;
+
+  for (i = 0; demuxer_list[i]; i++)
+    if (file_format == demuxer_list[i]->type)
+      return demuxer_list[i];
+
+  return NULL;
+}
+
+
+demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename){
   demuxer_t *d=malloc(sizeof(demuxer_t));
   memset(d,0,sizeof(demuxer_t));
   d->stream=stream;
@@ -69,6 +187,11 @@
   d->video=new_demuxer_stream(d,v_id);
   d->sub=new_demuxer_stream(d,s_id);
   d->type=type;
+  if(type)
+    if (!(d->desc = get_demuxer_desc_from_type(type)))
+      mp_msg(MSGT_DEMUXER,MSGL_ERR,"BUG! Invalid demuxer type in new_demuxer(), big troubles ahead.");
+  if(filename) // Filename hack for avs_check_file
+    d->filename=strdup(filename);
   stream_reset(stream);
   stream_seek(stream,stream->start_pos);
   return d;
@@ -130,141 +253,14 @@
     free(sh);
 }
 
-extern void demux_close_vivo(demuxer_t *demuxer);
-extern void demux_close_real(demuxer_t *demuxer);
-extern void demux_close_y4m(demuxer_t *demuxer);
-extern void demux_close_mf(demuxer_t* demuxer);
-extern void demux_close_roq(demuxer_t* demuxer);
-extern void demux_close_film(demuxer_t* demuxer);
-extern void demux_close_fli(demuxer_t* demuxer);
-extern void demux_close_nsv(demuxer_t* demuxer);
-extern void demux_close_nuv(demuxer_t* demuxer);
-extern void demux_close_audio(demuxer_t* demuxer);
-extern void demux_close_mpc(demuxer_t* demuxer);
-extern void demux_close_ogg(demuxer_t* demuxer);
-extern void demux_close_mpg(demuxer_t* demuxer);
-extern void demux_close_rtp(demuxer_t* demuxer);
-extern void demux_close_demuxers(demuxer_t* demuxer);
-extern void demux_close_avi(demuxer_t *demuxer);
-extern void demux_close_rawdv(demuxer_t* demuxer);
-extern void demux_close_pva(demuxer_t* demuxer);
-extern void demux_close_smjpeg(demuxer_t* demuxer);
-extern void demux_close_xmms(demuxer_t* demuxer);
-extern void demux_close_gif(demuxer_t* demuxer);
-extern void demux_close_lmlm4(demuxer_t* demuxer);
-extern void demux_close_ts(demuxer_t* demuxer);
-extern void demux_close_mkv(demuxer_t* demuxer);
-extern void demux_close_ra(demuxer_t* demuxer);
-extern void demux_close_ty(demuxer_t* demuxer);
-extern void demux_close_lavf(demuxer_t* demuxer);
-extern void demux_close_vqf(demuxer_t* demuxer);
-extern void demux_close_aac(demuxer_t* demuxer);
-#ifdef USE_WIN32DLL
-extern void demux_close_avs(demuxer_t* demuxer);
-#endif
-extern void demux_close_mov(demuxer_t* demuxer);
-
-
-#ifdef USE_TV
-#include "tv.h"
-extern int tv_param_on;
-
-extern int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds);
-extern int demux_open_tv(demuxer_t *demuxer);
-#if defined(USE_TV) && (defined(HAVE_TV_V4L) || defined(HAVE_TV_V4L2))
-extern void demux_close_tv(demuxer_t *demuxer);
-#endif
-#endif
-
 void free_demuxer(demuxer_t *demuxer){
     int i;
     mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing demuxer at %p\n",demuxer);
-    switch(demuxer->type) {
-    case DEMUXER_TYPE_PVA:
-      demux_close_pva(demuxer); break;
-    case DEMUXER_TYPE_VIVO:
-      demux_close_vivo(demuxer); break;
-    case DEMUXER_TYPE_REAL:
-      demux_close_real(demuxer); break;
-    case DEMUXER_TYPE_Y4M:
-      demux_close_y4m(demuxer); break;
-    case DEMUXER_TYPE_MF:
-      demux_close_mf(demuxer); break;
-    case DEMUXER_TYPE_ROQ:
-      demux_close_roq(demuxer);  break;
-    case DEMUXER_TYPE_FILM:
-      demux_close_film(demuxer); break;
-    case DEMUXER_TYPE_FLI:
-      demux_close_fli(demuxer); break;
-    case DEMUXER_TYPE_NSV:
-      demux_close_nsv(demuxer); break;
-    case DEMUXER_TYPE_NUV:
-      demux_close_nuv(demuxer); break;
-    case DEMUXER_TYPE_MPEG_TY:
-      demux_close_ty(demuxer); break;
-#if defined(USE_TV) && (defined(HAVE_TV_V4L) || defined(HAVE_TV_V4L2))
-    case DEMUXER_TYPE_TV:
-	demux_close_tv(demuxer); break;
-#endif
-#ifdef HAVE_LIBDV095
-    case DEMUXER_TYPE_RAWDV:
-      demux_close_rawdv(demuxer); break;
-#endif
-    case DEMUXER_TYPE_AUDIO:
-      demux_close_audio(demuxer); break;
-    case DEMUXER_TYPE_MPC:
-      demux_close_mpc(demuxer); break;
-#ifdef HAVE_OGGVORBIS
-    case DEMUXER_TYPE_OGG:
-      demux_close_ogg(demuxer); break;
-#endif
-#ifdef HAVE_MATROSKA
-    case DEMUXER_TYPE_MATROSKA:
-      demux_close_mkv(demuxer); break;
-#endif
-#ifdef STREAMING_LIVE_DOT_COM
-    case DEMUXER_TYPE_RTP:
-      demux_close_rtp(demuxer); break;
-#endif
-    case DEMUXER_TYPE_SMJPEG:
-      demux_close_smjpeg(demuxer); break;
-    case DEMUXER_TYPE_DEMUXERS:
-      demux_close_demuxers(demuxer); return;
-    case DEMUXER_TYPE_AVI: 
-    case DEMUXER_TYPE_AVI_NI:
-    case DEMUXER_TYPE_AVI_NINI:
-      demux_close_avi(demuxer); break;
-#ifdef HAVE_XMMS
-    case DEMUXER_TYPE_XMMS:
-      demux_close_xmms(demuxer); break;
-#endif
-#ifdef HAVE_GIF
-    case DEMUXER_TYPE_GIF:
-      demux_close_gif(demuxer); break;
-#endif
-    case DEMUXER_TYPE_LMLM4:
-      demux_close_lmlm4(demuxer); break;
-    case DEMUXER_TYPE_MPEG_TS:
-      demux_close_ts(demuxer); break;
-    case DEMUXER_TYPE_MPEG_PS:
-      demux_close_mpg(demuxer); break;
-    case DEMUXER_TYPE_REALAUDIO:
-      demux_close_ra(demuxer); break;
-    case DEMUXER_TYPE_VQF:
-      demux_close_vqf(demuxer); break;
-    case DEMUXER_TYPE_AAC:
-      demux_close_aac(demuxer); break;
-#ifdef USE_LIBAVFORMAT
-    case DEMUXER_TYPE_LAVF:
-      demux_close_lavf(demuxer); break;
-#endif
-#ifdef USE_WIN32DLL
-    case DEMUXER_TYPE_AVS:
-      demux_close_avs(demuxer); break;
-#endif
-    case DEMUXER_TYPE_MOV:
-      demux_close_mov(demuxer); break;
-    }
+    if(demuxer->desc->close)
+      demuxer->desc->close(demuxer);
+    // Very ugly hack to make it behave like old implementation
+    if (demuxer->desc->type == DEMUXER_TYPE_DEMUXERS)
+      return;
     // free streams:
     for(i = 0; i < MAX_A_STREAMS; i++)
 	if(demuxer->a_streams[i]) free_sh_audio(demuxer->a_streams[i]);
@@ -281,6 +277,8 @@
 	free(demuxer->info[i]);
       free(demuxer->info);
     }
+    if(demuxer->filename)
+      free(demuxer->filename);
     free(demuxer);
 }
 
@@ -320,112 +318,11 @@
 // return value:
 //     0 = EOF or no stream found or invalid type
 //     1 = successfully read a packet
-int demux_mf_fill_buffer( demuxer_t *demux);
-int demux_roq_fill_buffer(demuxer_t *demux);
-int demux_film_fill_buffer(demuxer_t *demux);
-int demux_fli_fill_buffer(demuxer_t *demux);
-int demux_mpg_es_fill_buffer(demuxer_t *demux);
-int demux_mpg_fill_buffer(demuxer_t *demux);
-int demux_ty_fill_buffer(demuxer_t *demux);
-int demux_avi_fill_buffer(demuxer_t *demux);
-int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t *ds);
-int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t *ds);
-int demux_asf_fill_buffer(demuxer_t *demux);
-int demux_mov_fill_buffer(demuxer_t *demux,demux_stream_t* ds);
-int demux_vivo_fill_buffer(demuxer_t *demux);
-int demux_real_fill_buffer(demuxer_t *demuxer);
-int demux_nsv_fill_buffer(demuxer_t *demux);
-int demux_nuv_fill_buffer(demuxer_t *demux);
-int demux_rtp_fill_buffer(demuxer_t *demux, demux_stream_t* ds);
-int demux_rawdv_fill_buffer(demuxer_t *demuxer);
-int demux_y4m_fill_buffer(demuxer_t *demux);
-int demux_audio_fill_buffer(demux_stream_t *ds);
-int demux_mpc_fill_buffer(demux_stream_t *ds);
-int demux_pva_fill_buffer(demuxer_t *demux);
-int demux_xmms_fill_buffer(demuxer_t *demux,demux_stream_t *ds);
-int demux_gif_fill_buffer(demuxer_t *demux);
-int demux_ts_fill_buffer(demuxer_t *demux);
-int demux_ra_fill_buffer(demuxer_t *demux);
-int demux_vqf_fill_buffer(demuxer_t *demux);
-
-extern int demux_aac_fill_buffer(demuxer_t *demux);
-extern int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds);
-extern int demux_ogg_fill_buffer(demuxer_t *d);
-extern int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds);
-extern int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds);
-extern int demux_smjpeg_fill_buffer(demuxer_t* demux);
-extern int demux_lmlm4_fill_buffer(demuxer_t* demux);
-extern int demux_mkv_fill_buffer(demuxer_t *d);
-extern int demux_lavf_fill_buffer(demuxer_t *d);
-#ifdef USE_WIN32DLL
-extern int demux_avs_fill_buffer(demuxer_t *d);
-#endif
 
 int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
   // Note: parameter 'ds' can be NULL!
 //  printf("demux->type=%d\n",demux->type);
-  switch(demux->type){
-    case DEMUXER_TYPE_MF: return demux_mf_fill_buffer(demux);
-    case DEMUXER_TYPE_ROQ: return demux_roq_fill_buffer(demux);
-    case DEMUXER_TYPE_FILM: return demux_film_fill_buffer(demux);
-    case DEMUXER_TYPE_FLI: return demux_fli_fill_buffer(demux);
-    case DEMUXER_TYPE_MPEG_TY: return demux_ty_fill_buffer( demux );
-    case DEMUXER_TYPE_MPEG4_ES:
-    case DEMUXER_TYPE_H264_ES:
-    case DEMUXER_TYPE_MPEG_ES: return demux_mpg_es_fill_buffer(demux);
-    case DEMUXER_TYPE_MPEG_PS: return demux_mpg_fill_buffer(demux);
-    case DEMUXER_TYPE_AVI: return demux_avi_fill_buffer(demux);
-    case DEMUXER_TYPE_AVI_NI: return demux_avi_fill_buffer_ni(demux,ds);
-    case DEMUXER_TYPE_AVI_NINI: return demux_avi_fill_buffer_nini(demux,ds);
-    case DEMUXER_TYPE_ASF: return demux_asf_fill_buffer(demux);
-    case DEMUXER_TYPE_MOV: return demux_mov_fill_buffer(demux,ds);
-    case DEMUXER_TYPE_VIVO: return demux_vivo_fill_buffer(demux);
-    case DEMUXER_TYPE_PVA: return demux_pva_fill_buffer(demux);
-#ifdef HAVE_LIBDV095
-    case DEMUXER_TYPE_RAWDV: return demux_rawdv_fill_buffer(demux);
-#endif
-    case DEMUXER_TYPE_REAL: return demux_real_fill_buffer(demux);
-    case DEMUXER_TYPE_NSV: return demux_nsv_fill_buffer(demux);
-    case DEMUXER_TYPE_NUV: return demux_nuv_fill_buffer(demux);
-#ifdef USE_TV
-    case DEMUXER_TYPE_TV: return demux_tv_fill_buffer(demux, ds);
-#endif
-    case DEMUXER_TYPE_Y4M: return demux_y4m_fill_buffer(demux);
-    case DEMUXER_TYPE_AUDIO: return demux_audio_fill_buffer(ds);
-    case DEMUXER_TYPE_MPC: return demux_mpc_fill_buffer(ds);
-#ifdef HAVE_XMMS
-    case DEMUXER_TYPE_XMMS: return demux_xmms_fill_buffer(demux,ds);
-#endif
-    case DEMUXER_TYPE_DEMUXERS: return demux_demuxers_fill_buffer(demux,ds);
-#ifdef HAVE_OGGVORBIS
-    case DEMUXER_TYPE_OGG: return demux_ogg_fill_buffer(demux);
-#endif
-#ifdef HAVE_MATROSKA
-    case DEMUXER_TYPE_MATROSKA: return demux_mkv_fill_buffer(demux);
-#endif
-    case DEMUXER_TYPE_RAWAUDIO: return demux_rawaudio_fill_buffer(demux,ds);
-    case DEMUXER_TYPE_RAWVIDEO: return demux_rawvideo_fill_buffer(demux,ds);
-#ifdef STREAMING_LIVE_DOT_COM
-    case DEMUXER_TYPE_RTP: return demux_rtp_fill_buffer(demux, ds);
-#endif
-    case DEMUXER_TYPE_SMJPEG: return demux_smjpeg_fill_buffer(demux);
-#ifdef HAVE_GIF
-    case DEMUXER_TYPE_GIF: return demux_gif_fill_buffer(demux);
-#endif
-    case DEMUXER_TYPE_LMLM4: return demux_lmlm4_fill_buffer(demux);
-    case DEMUXER_TYPE_MPEG_TS: 
-	return demux_ts_fill_buffer(demux);
-    case DEMUXER_TYPE_REALAUDIO: return demux_ra_fill_buffer(demux);
-    case DEMUXER_TYPE_VQF: return demux_vqf_fill_buffer(demux);
-    case DEMUXER_TYPE_AAC: return demux_aac_fill_buffer(demux);
-#ifdef USE_LIBAVFORMAT
-     case DEMUXER_TYPE_LAVF: return demux_lavf_fill_buffer(demux);
-#endif
-#ifdef USE_WIN32DLL
-    case DEMUXER_TYPE_AVS: return demux_avs_fill_buffer(demux);
-#endif
-  }
-  return 0;
+  return demux->desc->fill_buffer(demux, ds);
 }
 
 // return value:
@@ -605,74 +502,53 @@
 //extern int video_id;
 //extern int dvdsub_id;
 
-int asf_check_header(demuxer_t *demuxer);
-int read_asf_header(demuxer_t *demuxer);
-demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id);
-demuxer_t* demux_open_avi(demuxer_t* demuxer);
-int mov_check_file(demuxer_t* demuxer);
-int mov_read_header(demuxer_t* demuxer);
-int demux_open_fli(demuxer_t* demuxer);
-int demux_open_mf(demuxer_t* demuxer);
-int demux_open_film(demuxer_t* demuxer);
-int demux_open_roq(demuxer_t* demuxer);
-int demux_mpg_probe(demuxer_t *demuxer);
-#ifdef HAVE_LIBDV095
-int demux_open_rawdv(demuxer_t* demuxer);
-extern int rawdv_check_file(demuxer_t *demuxer);
-#endif
+void demuxer_help(void)
+{
+  int i;
 
-#ifdef USE_WIN32DLL
-int avs_check_file(demuxer_t *demuxer, const char *filename);
-#endif
+  mp_msg(MSGT_DEMUXER, MSGL_INFO, "Available demuxers:\n");
+  mp_msg(MSGT_DEMUXER, MSGL_INFO, " demuxer:  type  info:  (comment)\n");
+  for (i = 0; demuxer_list[i]; i++) {
+    if (demuxer_list[i]->type > DEMUXER_TYPE_MAX) // Don't display special demuxers
+      continue;
+    if (demuxer_list[i]->comment && strlen(demuxer_list[i]->comment))
+      mp_msg(MSGT_DEMUXER, MSGL_INFO, "%10s  %2d   %s (%s)\n",
+             demuxer_list[i]->name, demuxer_list[i]->type, demuxer_list[i]->info, demuxer_list[i]->comment);
+    else
+      mp_msg(MSGT_DEMUXER, MSGL_INFO, "%10s  %2d   %s\n",
+             demuxer_list[i]->name, demuxer_list[i]->type, demuxer_list[i]->info);
+  }
+}
+
 
-extern int demux_aac_open(demuxer_t *demuxer);
-extern int demux_aac_probe(demuxer_t *demuxer);
-extern int vivo_check_file(demuxer_t *demuxer);
-extern void demux_open_vivo(demuxer_t *demuxer);
-extern int y4m_check_file(demuxer_t *demuxer);
-extern void demux_open_y4m(demuxer_t *demuxer);
-extern int roq_check_file(demuxer_t *demuxer);
-extern int pva_check_file(demuxer_t * demuxer);
-extern demuxer_t * demux_open_pva(demuxer_t * demuxer);
-extern int real_check_file(demuxer_t *demuxer);
-extern void demux_open_real(demuxer_t *demuxer);
-extern int nsv_check_file(demuxer_t *demuxer);
-extern int nuv_check_file(demuxer_t *demuxer);
-extern void demux_open_nsv(demuxer_t *demuxer);
-extern void demux_open_nuv(demuxer_t *demuxer);
-extern int demux_audio_open(demuxer_t* demuxer);
-extern int demux_mpc_open(demuxer_t* demuxer);
-extern int demux_ogg_open(demuxer_t* demuxer);
-extern int demux_mpg_open(demuxer_t* demuxer);
-extern int demux_rawaudio_open(demuxer_t* demuxer);
-extern int demux_rawvideo_open(demuxer_t* demuxer);
-extern int smjpeg_check_file(demuxer_t *demuxer);
-extern int demux_open_smjpeg(demuxer_t* demuxer);
-extern int demux_xmms_open(demuxer_t* demuxer);
-extern int gif_check_file(demuxer_t *demuxer);
-extern int demux_open_gif(demuxer_t* demuxer);
-extern int lmlm4_check_file(demuxer_t* demuxer);
-extern int demux_open_lmlm4(demuxer_t* demuxer);
-extern int ts_check_file(demuxer_t * demuxer);
-extern int demux_open_ts(demuxer_t *demuxer);
-extern int demux_open_mkv(demuxer_t *demuxer);
-extern int ra_check_file(demuxer_t *demuxer);
-extern int demux_open_ra(demuxer_t* demuxer);
-extern int demux_probe_vqf(demuxer_t *demuxer);
-extern int demux_open_vqf(demuxer_t* demuxer);
-#ifdef HAVE_MATROSKA
-extern int demux_mkv_open(demuxer_t *demuxer);
-#endif
-extern int lavf_check_file(demuxer_t *demuxer);
-extern int demux_open_lavf(demuxer_t* demuxer);
-#ifdef USE_WIN32DLL
-extern int demux_open_avs(demuxer_t* demuxer);
-#endif
+/**
+ * Get demuxer type for a given demuxer name
+ *
+ * @param demuxer_name    string with demuxer name of demuxer number
+ * @return                DEMUXER_TYPE_xxx, -1 if error or not found
+ */
+int get_demuxer_type_from_name(char *demuxer_name)
+{
+  int i;
+  long type_int;
+  char *endptr;
 
-extern demuxer_t* init_avi_with_ogg(demuxer_t* demuxer);
-#ifdef STREAMING_LIVE_DOT_COM
-extern demuxer_t* demux_open_rtp(demuxer_t* demuxer);
-#endif
+  for (i = 0; demuxer_list[i]; i++) {
+    if (demuxer_list[i]->type > DEMUXER_TYPE_MAX) // Can't select special demuxers from commandline
+      continue;
+    if (strcmp(demuxer_name, demuxer_list[i]->name) == 0)
+      return  demuxer_list[i]->type;
+  }
+
+  // No match found, try to parse name as an integer (demuxer number)
+  type_int = strtol(demuxer_name, &endptr, 0);
+  if (*endptr) // Conversion failed
+    return -1;
+  if ((type_int > 0) && (type_int <= DEMUXER_TYPE_MAX))
+    return (int)type_int;
+
+  return -1;
+}
 
 int extension_parsing=1; // 0=off 1=mixed (used only for unstable formats)
 
@@ -695,162 +571,68 @@
 
 demuxer_t *demuxer=NULL;
 
-demux_stream_t *d_audio=NULL;
-demux_stream_t *d_video=NULL;
+sh_video_t *sh_video=NULL;
 
-sh_audio_t *sh_audio=NULL;
-sh_video_t *sh_video=NULL;
+demuxer_desc_t *demuxer_desc;
+int fformat;
+int i;
 
 //printf("demux_open(%p,%d,%d,%d,%d)  \n",stream,file_format,audio_id,video_id,dvdsub_id);
 
-if(file_format == DEMUXER_TYPE_RAWAUDIO) {
-  demuxer = new_demuxer(stream,DEMUXER_TYPE_RAWAUDIO,audio_id,video_id,dvdsub_id);
-}
-if(file_format == DEMUXER_TYPE_RAWVIDEO) {
-  demuxer = new_demuxer(stream,DEMUXER_TYPE_RAWVIDEO,audio_id,video_id,dvdsub_id);
+// If somebody requested a demuxer check it
+if (file_format) {
+  if ((demuxer_desc = get_demuxer_desc_from_type(file_format))) {
+    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);
+    if (demuxer_desc->check_file) {
+      if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
+        if (fformat == demuxer_desc->type) {
+          // Move messages to demuxer detection code?
+          mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc);
+          file_format = demuxer_desc->type = fformat;
+        } else {
+          // Format changed after check, recurse
+          free_demuxer(demuxer);
+          return demux_open_stream(stream,fformat,audio_id,video_id,dvdsub_id,filename);
+        }
+      } else {
+        // Check failed for forced demuxer, quit
+        free_demuxer(demuxer);
+        return NULL;
+      }
+    }
+  }
 }
 
-#ifdef USE_TV
-//=============== Try to open as TV-input: =================
-if(file_format==DEMUXER_TYPE_TV){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_TV,audio_id,video_id,dvdsub_id);
-  mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedTV);
-}
-#endif
-
-//=============== Try to open as multi file: =================
-if(file_format==DEMUXER_TYPE_MF){
-     demuxer=new_demuxer(stream,DEMUXER_TYPE_MF,audio_id,video_id,dvdsub_id);
-     mp_msg( MSGT_DEMUXER,MSGL_INFO,"[demuxer] mf support.\n" );
-}
+if (demuxer)
+  goto dmx_open;
 
-//=============== Try to open as AVI file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVI){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_AVI,audio_id,video_id,dvdsub_id);
-  { //---- RIFF header:
-    int id=stream_read_dword_le(demuxer->stream); // "RIFF"
-    if((id==mmioFOURCC('R','I','F','F')) || (id==mmioFOURCC('O','N','2',' '))){
-      stream_read_dword_le(demuxer->stream); //filesize
-      id=stream_read_dword_le(demuxer->stream); // "AVI "
-      if(id==formtypeAVI){ 
-        mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"AVI");
-        file_format=DEMUXER_TYPE_AVI;
-      }	
-      if(id==mmioFOURCC('O','N','2','f')){ 
-        mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"ON2 AVI");
-        file_format=DEMUXER_TYPE_AVI;
-      }	
-    }
-    if (file_format==DEMUXER_TYPE_UNKNOWN) {
+// Test demuxers with safe file checks
+for (i = 0; (demuxer_desc = demuxer_list[i]); i++) {
+  if (demuxer_desc->safe_check) {
+    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);
+    if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
+      if (fformat == demuxer_desc->type) {
+        mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc);
+        file_format = fformat;
+        break;
+      } else {
+        // Format changed after check, recurse
+        free_demuxer(demuxer);
+        demuxer=demux_open_stream(stream,fformat,audio_id,video_id,dvdsub_id,filename);
+        if(demuxer) return demuxer; // done!
+        file_format = DEMUXER_TYPE_UNKNOWN;
+      }
+    } else {
       free_demuxer(demuxer);
       demuxer = NULL;
     }
   }
 }
-//=============== Try to open as Y4M file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_Y4M){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_Y4M,audio_id,video_id,dvdsub_id);
-  if(y4m_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"YUV4MPEG2");
-      file_format=DEMUXER_TYPE_Y4M;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-//=============== Try to open as ASF file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_ASF){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_ASF,audio_id,video_id,dvdsub_id);
-  if(asf_check_header(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"ASF");
-      file_format=DEMUXER_TYPE_ASF;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-//=============== Try to open as NSV file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_NSV){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_NSV,audio_id,video_id,dvdsub_id);
-  if(file_format==DEMUXER_TYPE_NSV||nsv_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"Nullsoft Streaming Video");
-      file_format=DEMUXER_TYPE_NSV;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-//=============== Try to open as NUV file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_NUV){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_NUV,audio_id,video_id,dvdsub_id);
-  if(nuv_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"NuppelVideo");
-      file_format=DEMUXER_TYPE_NUV;
-  } else {
-      free_demuxer(demuxer);
-      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;
-  }
-}
-#ifdef HAVE_MATROSKA
-//=============== Try to open as Matroska file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MATROSKA){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_MATROSKA,audio_id,video_id,dvdsub_id);
-  if(demux_mkv_open(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"Matroska");
-      file_format=DEMUXER_TYPE_MATROSKA;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-#endif
-//=============== Try to open as REALAUDIO file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_REALAUDIO){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_REALAUDIO,audio_id,video_id,dvdsub_id);
-  if(ra_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"REALAUDIO");
-      file_format=DEMUXER_TYPE_REALAUDIO;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
 
-//=============== Try to open as VQF file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_VQF){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_VQF,audio_id,video_id,dvdsub_id);
-  if(demux_probe_vqf(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"VQF");
-      file_format=DEMUXER_TYPE_VQF;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
+if (demuxer)
+  goto dmx_open;
 
-//=============== Try based on filename EXTENSION: =================
+// If no forced demuxer perform file extension based detection
 // 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:
@@ -865,495 +647,43 @@
   }
 }
 
-//=============== 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);
-  if(mov_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"QuickTime/MOV");
-      file_format=demuxer->type;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-//=============== Try to open as VIVO file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_VIVO){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_VIVO,audio_id,video_id,dvdsub_id);
-  if(vivo_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "VIVO");
-      file_format=DEMUXER_TYPE_VIVO;
-  } 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);
-  {
-    int id;
-    stream_seek(demuxer->stream, 4);
-    id=stream_read_word_le(demuxer->stream);
-    // check for the FLI file magic number
-    if((id==0xAF11) || (id==0xAF12)){ 
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"FLI");
-      file_format=DEMUXER_TYPE_FLI;
-    } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-    }
-  }
-}
-//=============== Try to open as FILM file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_FILM){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_FILM,audio_id,video_id,dvdsub_id);
-  {
-    int signature=stream_read_fourcc(demuxer->stream);
-    // check for the FLI file magic number
-    if(signature==mmioFOURCC('F', 'I', 'L', 'M')){ 
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"FILM");
-      file_format=DEMUXER_TYPE_FILM;
+// Try detection for all other demuxers
+for (i = 0; (demuxer_desc = demuxer_list[i]); i++) {
+  if (!demuxer_desc->safe_check && demuxer_desc->check_file) {
+    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);
+    if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
+      if (fformat == demuxer_desc->type) {
+        mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc);
+        file_format = fformat;
+        break;
+      } else {
+        // Format changed after check, recurse
+        free_demuxer(demuxer);
+        demuxer=demux_open_stream(stream,fformat,audio_id,video_id,dvdsub_id,filename);
+        if(demuxer) return demuxer; // done!
+        file_format = DEMUXER_TYPE_UNKNOWN;
+      }
     } else {
       free_demuxer(demuxer);
       demuxer = NULL;
     }
   }
 }
-//=============== Try to open as RoQ file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_ROQ){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_ROQ,audio_id,video_id,dvdsub_id);
-  if(roq_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"ROQ");
-      file_format=DEMUXER_TYPE_ROQ;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-#ifdef HAVE_GIF
-//=============== Try to open as GIF file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_GIF){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_GIF,audio_id,video_id,dvdsub_id);
-  if(gif_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"GIF");
-      file_format=DEMUXER_TYPE_GIF;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-#endif
-#ifdef HAVE_OGGVORBIS
-//=============== Try to open as Ogg file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_OGG){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_OGG,audio_id,video_id,dvdsub_id);
-  if(demux_ogg_open(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"Ogg");
-      file_format=DEMUXER_TYPE_OGG;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-#endif
-#ifdef USE_WIN32DLL
-//=============== Try to open as Avisynth file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVS){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_AVS,audio_id,video_id,dvdsub_id);
-  if (avs_check_file(demuxer, filename)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"AVS");
-      file_format=DEMUXER_TYPE_AVS;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-#endif
-//=============== Try to open as PVA file: =================
-if(file_format == DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_PVA){
-	demuxer=new_demuxer(stream,DEMUXER_TYPE_PVA,audio_id,video_id,dvdsub_id);
-	if(pva_check_file(demuxer)) {
-		mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"PVA");
-		file_format=DEMUXER_TYPE_PVA;
-	} else {
-		free_demuxer(demuxer);
-		demuxer=NULL;
-	}
-}
-//=============== Try to open as MPEG-TS file: =================
-if(file_format == DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_TS){
-	demuxer=new_demuxer(stream,DEMUXER_TYPE_MPEG_TS,audio_id,video_id,dvdsub_id);
-	if(ts_check_file(demuxer)) {
-		mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"TS");
-		file_format=DEMUXER_TYPE_MPEG_TS;
-	} else {
-		free_demuxer(demuxer);
-		demuxer=NULL;
-	}
-}
-//=============== Try to open as LMLM4 file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_LMLM4){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_LMLM4,audio_id,video_id,dvdsub_id);
-  if(lmlm4_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"RAW LMLM4");
-      file_format=DEMUXER_TYPE_LMLM4;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
 
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_PS){
- demuxer=new_demuxer(stream,DEMUXER_TYPE_MPEG_PS,audio_id,video_id,dvdsub_id);
- file_format = demux_mpg_probe(demuxer);
- mp_msg(MSGT_DEMUXER,MSGL_V,"demux_mpg_probe returned file_format %d\n", file_format);
- if(file_format==DEMUXER_TYPE_UNKNOWN) {
-   free_demuxer(demuxer);
-   demuxer=new_demuxer(stream,DEMUXER_TYPE_MPEG_PS,audio_id,video_id,dvdsub_id);
-   demuxer->synced = 3;
-   file_format = demux_mpg_probe(demuxer);
-   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_mpg_probe returned file_format %d\n", file_format);
-   if(file_format==DEMUXER_TYPE_MPEG_PS)
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"MPEG-PES");
- } else if(file_format==DEMUXER_TYPE_MPEG_PS)
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"MPEG-PS");
-  
- if(file_format != DEMUXER_TYPE_MPEG_PS) {
-   free_demuxer(demuxer);
-   demuxer = NULL;
- }
-}
-//=============== Try to open as MPEG-ES file: =================
-if(file_format==DEMUXER_TYPE_MPEG_ES || file_format==DEMUXER_TYPE_MPEG4_ES  || file_format==DEMUXER_TYPE_H264_ES){ // little hack, see above!
-  demuxer=new_demuxer(stream,file_format,audio_id,video_id,dvdsub_id);
-  if(!ds_fill_buffer(demuxer->video)){
-    mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_InvalidMPEGES);
-    file_format=DEMUXER_TYPE_UNKNOWN;
-    free_demuxer(demuxer);
-    demuxer = NULL;
-  } else {
-    switch(file_format){
-    case DEMUXER_TYPE_MPEG_ES: 
-        mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "MPEG-ES"); break;
-    case DEMUXER_TYPE_MPEG4_ES: 
-        mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "MPEG4-ES"); break;
-    case DEMUXER_TYPE_H264_ES: 
-        mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "H264-ES"); break;
-    }
-  }
-}
-#ifdef HAVE_LIBDV095
-//=============== Try to open raw DV file, as produced by dvgrab --format raw =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_RAWDV)
-{
-   demuxer=new_demuxer(stream,DEMUXER_TYPE_RAWDV,audio_id,video_id,dvdsub_id);
-   if(rawdv_check_file(demuxer))
-   {
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"RAWDV");
-      file_format=DEMUXER_TYPE_RAWDV;
-   }
-   else {
-      free_demuxer(demuxer);
-      demuxer=NULL;
-   }
-}
-#endif
-//=============== Try to open as audio file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AUDIO){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_AUDIO,audio_id,video_id,dvdsub_id);
-  if(demux_audio_open(demuxer)){
-    mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedAudiofile);
-    file_format=DEMUXER_TYPE_AUDIO;
-  } else {
-    free_demuxer(demuxer);
-    demuxer = NULL;
-  }
-}
-//=============== Try to open as musepack file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPC){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_MPC,audio_id,video_id,dvdsub_id);
-  if(demux_mpc_open(demuxer)){
-    mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "MPC");
-    file_format=DEMUXER_TYPE_MPC;
-  } else {
-    free_demuxer(demuxer);
-    demuxer = NULL;
-  }
-}
-#ifdef HAVE_XMMS
-//=============== Try to open as XMMS file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_XMMS){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_XMMS,audio_id,video_id,dvdsub_id);
-  if(demux_xmms_open(demuxer)){
-    mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedAudiofile);
-    file_format=DEMUXER_TYPE_XMMS;
-  } else {
-    free_demuxer(demuxer);
-    demuxer = NULL;
-  }
-}
-#endif
-//=============== Try to open as MPEG-TY file: =================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_TY)
-{
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_MPEG_TY,audio_id,video_id,dvdsub_id);
-  if(ds_fill_buffer(demuxer->video)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"TiVo");
-      file_format=DEMUXER_TYPE_MPEG_TY;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-//=============== Try to open as a RTP stream: ===========
- if(file_format==DEMUXER_TYPE_RTP) {
-   demuxer=new_demuxer(stream,DEMUXER_TYPE_RTP,audio_id,video_id,dvdsub_id);
- }
-//=============== Try to open with LAVF: =================
-#ifdef USE_LIBAVFORMAT
- if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_LAVF){
-  demuxer=new_demuxer(stream,DEMUXER_TYPE_LAVF,audio_id,video_id,dvdsub_id);
-  if(lavf_check_file(demuxer)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"libavformat"); //FIXME print format
-      file_format=DEMUXER_TYPE_LAVF;
-  } else {
-      free_demuxer(demuxer);
-      demuxer = NULL;
-  }
-}
-#endif
-//================Try AAC ===============================
-if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AAC) {
- demuxer=new_demuxer(stream,DEMUXER_TYPE_AAC,audio_id,video_id,dvdsub_id);
- if(! demux_aac_probe(demuxer)) {
-   free_demuxer(demuxer);
-   demuxer = NULL;
- } else file_format = DEMUXER_TYPE_AAC;
-}
 //=============== Unknown, exiting... ===========================
 if(file_format==DEMUXER_TYPE_UNKNOWN || demuxer == NULL){
   //mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized); // will be done by mplayer.c after fallback to playlist-parsing
   return NULL;
 }
 //====== File format recognized, set up these for compatibility: =========
-d_audio=demuxer->audio;
-d_video=demuxer->video;
-//d_dvdsub=demuxer->sub;
+dmx_open:
 
 demuxer->file_format=file_format;
 
-switch(file_format){
-#ifdef HAVE_LIBDV095
- case DEMUXER_TYPE_RAWDV:
- {
-   if (!demux_open_rawdv(demuxer)) return NULL;
-   break;
- }
-#endif
- case DEMUXER_TYPE_RAWAUDIO: {
-   demux_rawaudio_open(demuxer);
-   break;
- }
- case DEMUXER_TYPE_RAWVIDEO: {
-   demux_rawvideo_open(demuxer);
-   break;
- }
- case DEMUXER_TYPE_MF: {
-  if (!demux_open_mf(demuxer)) return NULL;
-  break;
- }
- case DEMUXER_TYPE_FLI: {
-  if (!demux_open_fli(demuxer)) return NULL;
-  break;
- }
- case DEMUXER_TYPE_FILM: {
-  if (!demux_open_film(demuxer)) return NULL;
-  break;
- }
-#ifdef HAVE_GIF
- case DEMUXER_TYPE_GIF: {
-  if (!demux_open_gif(demuxer)) return NULL;
-  break;
- }
-#endif
- case DEMUXER_TYPE_ROQ: {
-  if (!demux_open_roq(demuxer)) return NULL;
-  break;
- }
- case DEMUXER_TYPE_SMJPEG: {
-  if (!demux_open_smjpeg(demuxer)) return NULL;
-  break;
- }
- case DEMUXER_TYPE_MOV: {
-  if(!mov_read_header(demuxer)) return NULL;
-//  sh_video=d_video->sh;if(sh_video) sh_video->ds=d_video;
-//  sh_audio=d_audio->sh;if(sh_audio) sh_audio->ds=d_audio;
-  break;
- }
- case DEMUXER_TYPE_AVI: {
-   sh_audio_t* sh_a;
-   demuxer = (demuxer_t*) demux_open_avi(demuxer);
-   if(!demuxer) return NULL; // failed to open
-   sh_a = (sh_audio_t*)demuxer->audio->sh;
-   if(demuxer->audio->id != -2 && sh_a) {
-#ifdef HAVE_OGGVORBIS
-    // support for Ogg-in-AVI:
-     if(sh_a->format == 0xFFFE)
-       demuxer = init_avi_with_ogg(demuxer);
-     else if(sh_a->format == 0x674F) {
-       stream_t* s;
-       demuxer_t  *od;
-       s = new_ds_stream(demuxer->audio);
-       od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2);
-       if(!demux_ogg_open(od)) {
-	 mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer);
-	 free_stream(s);
-	 demuxer->audio->id = -2;
-       } else
-	 demuxer = new_demuxers_demuxer(demuxer,od,demuxer);
-     }
-#endif
-   }       
-   return demuxer;
-//  break;
- }
- case DEMUXER_TYPE_NSV: {
-  demux_open_nsv(demuxer);
-  break;
- }
- case DEMUXER_TYPE_NUV: {
-  demux_open_nuv(demuxer);
-  break;
- }
- case DEMUXER_TYPE_VIVO: {
-  demux_open_vivo(demuxer);
-  break;
- }
- case DEMUXER_TYPE_PVA: {
-  demux_open_pva(demuxer);
-  break;
- }
- case DEMUXER_TYPE_Y4M: {
-  demux_open_y4m(demuxer);
-  break;
- }
- case DEMUXER_TYPE_LMLM4: {
-  demux_open_lmlm4(demuxer);
-  if(!ds_fill_buffer(d_video)){
-    mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingVideoStream);
-    d_video->sh=NULL;
-  } else {
-    sh_video=d_video->sh;sh_video->ds=d_video;
-  }
-  if(audio_id!=-2) {
-   if(!ds_fill_buffer(d_audio)){
-    mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingAudioStream);
-    d_audio->sh=NULL;
-   } else {
-    sh_audio=d_audio->sh;sh_audio->ds=d_audio;
-   }
-  }
-  break;
- }
- case DEMUXER_TYPE_REAL: {
-  demux_open_real(demuxer);
-  break;
- }
- case DEMUXER_TYPE_ASF: {
-  //---- ASF header:
-  read_asf_header(demuxer);
-  stream_reset(demuxer->stream);
-  stream_seek(demuxer->stream,demuxer->movi_start);
-//  demuxer->idx_pos=0;
-//  demuxer->endpos=avi_header.movi_end;
-  if(d_video->id != -2) {
-    if(!ds_fill_buffer(d_video)){
-      mp_msg(MSGT_DEMUXER,MSGL_WARN,"ASF: " MSGTR_MissingVideoStream);
-      d_video->sh=NULL;
-      //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n");
-    } else {
-      sh_video=d_video->sh;sh_video->ds=d_video;
-      sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms
-      //      sh_video->i_bps=10*asf_packetsize; // FIXME!
-    }
-  }
-  if(d_audio->id!=-2){
-    mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_ASFSearchingForAudioStream,d_audio->id);
-    if(!ds_fill_buffer(d_audio)){
-      mp_msg(MSGT_DEMUXER,MSGL_INFO,"ASF: " MSGTR_MissingAudioStream);
-      d_audio->sh=NULL;
-    } else {
-      sh_audio=d_audio->sh;sh_audio->ds=d_audio;
-      sh_audio->format=sh_audio->wf->wFormatTag;
-    }
-  }
-  break;
- }
- case DEMUXER_TYPE_H264_ES:
- case DEMUXER_TYPE_MPEG4_ES:
- case DEMUXER_TYPE_MPEG_ES: {
-   d_audio->sh=NULL;   // ES streams has no audio channel
-   d_video->sh=new_sh_video(demuxer,0); // create dummy video stream header, id=0
-   sh_video=d_video->sh;sh_video->ds=d_video;
-   break;
- }
+if (demuxer->desc->open)
+  if (!(demuxer = demuxer->desc->open(demuxer)))
+    return NULL;
 
- case DEMUXER_TYPE_MPEG_TY: 
- case DEMUXER_TYPE_MPEG_PS: {
-  sh_video=d_video->sh;sh_video->ds=d_video;
-//  if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD
-
-  if(audio_id!=-2) {
-   if(!ds_fill_buffer(d_audio)){
-    mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream);
-    d_audio->sh=NULL;
-   } else {
-    sh_audio=d_audio->sh;sh_audio->ds=d_audio;
-   }
-  }
-  break;
- }
-#ifdef USE_TV
- case DEMUXER_TYPE_TV: {
-    if (!demux_open_tv(demuxer)) return(NULL);
-    break;
- }
-#endif
-#ifdef STREAMING_LIVE_DOT_COM
- case DEMUXER_TYPE_RTP: {
-   if (!(demuxer = demux_open_rtp(demuxer))) return NULL;
-   break;
- }
-#endif
- case DEMUXER_TYPE_MPEG_TS: {
-  demux_open_ts(demuxer);
-  break;
- }
- case DEMUXER_TYPE_REALAUDIO: {
-  if (!demux_open_ra(demuxer)) return NULL;
-  break;
- }
- case DEMUXER_TYPE_VQF: {
-  if (!demux_open_vqf(demuxer)) return NULL;
-  break;
- }
- case DEMUXER_TYPE_AAC: {
-  if (!demux_aac_open(demuxer)) return NULL;
-  break;
- }
-#ifdef USE_LIBAVFORMAT
-  case DEMUXER_TYPE_LAVF: {
-  if (!demux_open_lavf(demuxer)) return NULL;
-  break;
- }
-#endif
-#ifdef USE_WIN32DLL
-  case DEMUXER_TYPE_AVS: {
-  if (!demux_open_avs(demuxer)) return NULL;
-  break;
- }
-#endif
-} // switch(file_format)
 pts_from_bps=0; // !!!
 if ((sh_video=demuxer->video->sh) && sh_video->bih)
   mp_msg(MSGT_DEMUX,MSGL_INFO,"VIDEO:  [%.4s]  %ldx%ld  %dbpp  %5.3f fps  %5.1f kbps (%4.1f kbyte/s)\n",
@@ -1369,9 +699,13 @@
 
 char* audio_stream = NULL;
 char* sub_stream = NULL;
-int demuxer_type = 0, audio_demuxer_type = 0, sub_demuxer_type = 0;
+int demuxer_type = 0; // used by rawaudio and rawvideo
 int audio_stream_cache = 0;
 
+char *demuxer_name = NULL; // parameter from -demuxer
+char *audio_demuxer_name = NULL; // parameter from -audio-demuxer
+char *sub_demuxer_name = NULL; // parameter from -sub-demuxer
+
 extern int hr_mp3_seek;
 
 extern float stream_cache_min_percent;
@@ -1381,9 +715,20 @@
   stream_t *as = NULL,*ss = NULL;
   demuxer_t *vd,*ad = NULL,*sd = NULL;
   int afmt =DEMUXER_TYPE_UNKNOWN,sfmt = DEMUXER_TYPE_UNKNOWN ;
+  int audio_demuxer_type = 0, sub_demuxer_type = 0;
 
   demux_aid_vid_mismatch = 0;
 
+  if (demuxer_name && ((demuxer_type = get_demuxer_type_from_name(demuxer_name)) < 0)) {
+    mp_msg(MSGT_DEMUXER,MSGL_ERR,"-demuxer %s does not exist.\n",demuxer_name);
+  }
+  if (audio_demuxer_name && ((audio_demuxer_type = get_demuxer_type_from_name(audio_demuxer_name)) < 0)) {
+    mp_msg(MSGT_DEMUXER,MSGL_ERR,"-audio-demuxer %s does not exist.\n",audio_demuxer_name);
+  }
+  if (sub_demuxer_name && ((sub_demuxer_type = get_demuxer_type_from_name(sub_demuxer_name)) < 0)) {
+    mp_msg(MSGT_DEMUXER,MSGL_ERR,"-sub-demuxer %s does not exist.\n",sub_demuxer_name);
+  }
+
   if(audio_stream) {
     as = open_stream(audio_stream,0,&afmt);
     if(!as) {
@@ -1440,38 +785,6 @@
     return vd;
 }
 
-int demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_ty(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_y4m(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_film(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_nuv(demuxer_t *demuxer,float rel_seek_secs,int flags);
-void demux_seek_mov(demuxer_t *demuxer,float pts,int flags);
-int demux_seek_real(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_pva(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_ts(demuxer_t *demuxer,float rel_seek_secs,int flags);
-int demux_seek_lavf(demuxer_t *demuxer,float rel_seek_secs,int flags);
-#ifdef USE_WIN32DLL
-int demux_seek_avs(demuxer_t *demuxer,float rel_seek_secs,int flags);
-#endif
-
-#ifdef HAVE_LIBDV095
-int demux_seek_rawdv(demuxer_t *demuxer, float pts, int flags);
-#endif
-
-extern void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_mpc_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_ogg_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_rawvideo_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_xmms_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_mkv_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,int flags);
-extern void demux_aac_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
 
 int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
     demux_stream_t *d_audio=demuxer->audio;
@@ -1506,86 +819,8 @@
     if(sh_video) sh_video->timer=0; // !!!!!!
 #endif
 
-switch(demuxer->file_format){
-
-#ifdef HAVE_LIBDV095
-  case DEMUXER_TYPE_RAWDV:
-      demux_seek_rawdv(demuxer,rel_seek_secs,flags);  break;
-#endif
-  case DEMUXER_TYPE_AVI:
-      demux_seek_avi(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_ASF:
-      demux_seek_asf(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_MPEG_TY:
-      demux_seek_ty(demuxer,rel_seek_secs,flags);  break;
-  
-  case DEMUXER_TYPE_H264_ES:
-  case DEMUXER_TYPE_MPEG4_ES:
-  case DEMUXER_TYPE_MPEG_ES:
-  case DEMUXER_TYPE_MPEG_PS:
-      demux_seek_mpg(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_MOV:
-      demux_seek_mov(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_REAL:
-      demux_seek_real(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_Y4M:
-      demux_seek_y4m(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_MF:
-      demux_seek_mf(demuxer,rel_seek_secs,flags);  break;
-
-  case DEMUXER_TYPE_PVA:
-      demux_seek_pva(demuxer,rel_seek_secs,flags); break;
-      
-  case DEMUXER_TYPE_FLI:
-      demux_seek_fli(demuxer,rel_seek_secs,flags);  break;
-  case DEMUXER_TYPE_FILM:
-      demux_seek_film(demuxer,rel_seek_secs,flags);  break;
-  case DEMUXER_TYPE_NUV:
-      demux_seek_nuv(demuxer,rel_seek_secs,flags);  break;
-  case DEMUXER_TYPE_AUDIO:
-      demux_audio_seek(demuxer,rel_seek_secs,flags);  break;
-  case DEMUXER_TYPE_MPC:
-      demux_mpc_seek(demuxer,rel_seek_secs,flags);  break;
- case DEMUXER_TYPE_DEMUXERS:
-      demux_demuxers_seek(demuxer,rel_seek_secs,flags);  break;
-#ifdef HAVE_OGGVORBIS
- case DEMUXER_TYPE_OGG:
-      demux_ogg_seek(demuxer,rel_seek_secs,flags);  break;
-#endif
- case DEMUXER_TYPE_RAWAUDIO:
-      demux_rawaudio_seek(demuxer,rel_seek_secs,flags);  break;
- case DEMUXER_TYPE_RAWVIDEO:
-      demux_rawvideo_seek(demuxer,rel_seek_secs,flags);  break;
-#ifdef HAVE_XMMS
- case DEMUXER_TYPE_XMMS:
-      demux_xmms_seek(demuxer,rel_seek_secs,flags); break;
-#endif
-#ifdef HAVE_MATROSKA
- case DEMUXER_TYPE_MATROSKA:
-      demux_mkv_seek(demuxer,rel_seek_secs,flags);  break;
-#endif
- case DEMUXER_TYPE_MPEG_TS:
-      demux_seek_ts(demuxer,rel_seek_secs,flags); break;
- #ifdef USE_LIBAVFORMAT
- case DEMUXER_TYPE_LAVF:
-      demux_seek_lavf(demuxer,rel_seek_secs,flags); break;
- #endif
- case DEMUXER_TYPE_VQF:
-      demux_seek_vqf(demuxer,rel_seek_secs,flags); break;
- #ifdef USE_WIN32DLL
- case DEMUXER_TYPE_AVS:
-      demux_seek_avs(demuxer,rel_seek_secs,flags); break;
- #endif
- case DEMUXER_TYPE_AAC:
-      demux_aac_seek(demuxer,rel_seek_secs,flags); break;
-
-} // switch(demuxer->file_format)
+if (demuxer->desc->seek)
+    demuxer->desc->seek(demuxer,rel_seek_secs,flags);
 
 return 1;
 }
@@ -1648,75 +883,12 @@
   return NULL;
 }
 
-extern int demux_ty_control(demuxer_t *demuxer, int cmd, void *arg);
-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);
-extern int demux_xmms_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_audio_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_mpc_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_ogg_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_real_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg);
-extern int demux_mov_control(demuxer_t *demuxer, int cmd, void *arg);
-#ifdef USE_WIN32DLL
-extern int demux_avs_control(demuxer_t *demuxer, int cmd, void *arg);
-#endif
-#ifdef HAVE_LIBDV095
-extern int demux_rawdv_control(demuxer_t *demuxer,int cmd, void *arg);
-#endif
+int demux_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_TY:
-	    return demux_ty_control(demuxer,cmd,arg);
-	case DEMUXER_TYPE_MPEG4_ES:
-	case DEMUXER_TYPE_MPEG_ES:
-	case DEMUXER_TYPE_MPEG_PS:
-	case DEMUXER_TYPE_MPEG_TS:
-	    return demux_mpg_control(demuxer,cmd,arg);
-	case DEMUXER_TYPE_ASF:
-	    return demux_asf_control(demuxer,cmd,arg);
-	case DEMUXER_TYPE_AVI:
-	case DEMUXER_TYPE_AVI_NI:
-	case DEMUXER_TYPE_AVI_NINI:
-	    return demux_avi_control(demuxer,cmd,arg);
-	case DEMUXER_TYPE_AUDIO:
-	    return demux_audio_control(demuxer,cmd,arg);
-	case DEMUXER_TYPE_MPC:
-	    return demux_mpc_control(demuxer,cmd,arg);
-#ifdef HAVE_OGGVORBIS
-	case DEMUXER_TYPE_OGG:
-	    return demux_ogg_control(demuxer,cmd,arg);
-#endif
-#ifdef HAVE_XMMS
-	case DEMUXER_TYPE_XMMS:
-	    return demux_xmms_control(demuxer,cmd,arg);
-#endif
-#ifdef HAVE_MATROSKA
-        case DEMUXER_TYPE_MATROSKA:
-	    return demux_mkv_control(demuxer,cmd,arg);
-#endif
-	case DEMUXER_TYPE_REAL:
-	    return demux_real_control(demuxer, cmd, arg);
-#ifdef USE_LIBAVFORMAT
-        case DEMUXER_TYPE_LAVF:
-	    return demux_lavf_control(demuxer, cmd, arg);
-#endif
-        case DEMUXER_TYPE_MOV:
-   	    return demux_mov_control(demuxer, cmd, arg);
-#ifdef USE_WIN32DLL
-        case DEMUXER_TYPE_AVS:
-   	    return demux_avs_control(demuxer, cmd, arg);
-#endif 
-#ifdef HAVE_LIBDV095
-        case DEMUXER_TYPE_RAWDV:
-            return demux_rawdv_control(demuxer,cmd, arg);
-#endif
-	default:
-	    return DEMUXER_CTRL_NOTIMPL;
-    }
+    if (demuxer->desc->control)
+      return demuxer->desc->control(demuxer,cmd,arg);
+
+    return DEMUXER_CTRL_NOTIMPL;
 }
 
 
--- a/libmpdemux/demuxer.h	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/demuxer.h	Fri Aug 05 19:57:47 2005 +0000
@@ -48,11 +48,12 @@
 #define DEMUXER_TYPE_AVS 38
 #define DEMUXER_TYPE_AAC 39
 #define DEMUXER_TYPE_MPC 40
+#define DEMUXER_TYPE_MPEG_PES 41
 
 // This should always match the higest demuxer type number.
 // Unless you want to disallow users to force the demuxer to some types
 #define DEMUXER_TYPE_MIN 0
-#define DEMUXER_TYPE_MAX 40
+#define DEMUXER_TYPE_MAX 41
 
 #define DEMUXER_TYPE_DEMUXERS (1<<16)
 // A virtual demuxer type for the network code
@@ -125,11 +126,42 @@
 #define MAX_A_STREAMS 256
 #define MAX_V_STREAMS 256
 
+struct demuxer_st;
+
+/**
+ * Demuxer description structure
+ */
+typedef struct demuxers_desc_st {
+  const char *info; ///< What is it (long name and/or description)
+  const char *name; ///< Demuxer name, used with -demuxer switch
+  const char *shortdesc; ///< Description printed at demuxer detection
+  const char *author; ///< Demuxer author(s)
+  const char *comment; ///< Comment, printed with -demuxer help
+
+  int type; ///< DEMUXER_TYPE_xxx
+  int safe_check; ///< If 1 detection is safe and fast, do it before file extension check
+
+  /// Check if can demux the file, return DEMUXER_TYPE_xxx on success
+  int (*check_file)(struct demuxer_st *demuxer); ///< Mandatory if safe_check == 1, else optional 
+  /// Get packets from file, return 0 on eof
+  int (*fill_buffer)(struct demuxer_st *demuxer, demux_stream_t *ds); ///< Mandatory
+  /// Open the demuxer, return demuxer on success, NULL on failure
+  struct demuxer_st* (*open)(struct demuxer_st *demuxer); ///< Optional
+  /// Close the demuxer
+  void (*close)(struct demuxer_st *demuxer); ///< Optional
+  // Seek
+  void (*seek)(struct demuxer_st *demuxer, float rel_seek_secs, int flags); ///< Optional
+  // Control
+  int (*control)(struct demuxer_st *demuxer, int cmd, void *arg); ///< Optional
+} demuxer_desc_t;
+
 typedef struct demuxer_st {
+  demuxer_desc_t *desc;  ///< Demuxer description structure
   off_t filepos; // input stream current pos.
   off_t movi_start;
   off_t movi_end;
   stream_t *stream;
+  char *filename; ///< Needed by avs_check_file
   int synced;  // stream synced (used by mpeg)
   int type;    // demuxer type: mpeg PS, mpeg ES, avi, avi-ni, avi-nini, asf
   int file_format;  // file format: mpeg/avi/asf
@@ -203,7 +235,7 @@
 }
 
 demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id);
-demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id);
+demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename);
 void free_demuxer_stream(demux_stream_t *ds);
 void free_demuxer(demuxer_t *demuxer);
 
@@ -292,3 +324,6 @@
 extern int demuxer_switch_audio(demuxer_t *demuxer, int index);
 
 extern int demuxer_type_by_filename(char* filename);
+
+extern void demuxer_help(void);
+extern int get_demuxer_type_from_name(char *demuxer_name);
--- a/libmpdemux/tv.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/libmpdemux/tv.c	Fri Aug 05 19:57:47 2005 +0000
@@ -90,7 +90,7 @@
 */
 /* fill demux->video and demux->audio */
 
-int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
+static int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
 {
     tvi_handle_t *tvh=(tvi_handle_t*)(demux->priv);
     demux_packet_t* dp;
@@ -454,18 +454,18 @@
 	return 1;
 }
 
-int demux_open_tv(demuxer_t *demuxer)
+static demuxer_t* demux_open_tv(demuxer_t *demuxer)
 {
     tvi_handle_t *tvh;
     sh_video_t *sh_video;
     sh_audio_t *sh_audio = NULL;
     tvi_functions_t *funcs;
     
-    if(!(tvh=tv_begin())) return 0;
-    if (!tv_init(tvh)) return 0;
+    if(!(tvh=tv_begin())) return NULL;
+    if (!tv_init(tvh)) return NULL;
     if (!open_tv(tvh)){
 	tv_uninit(tvh);
-	return 0;
+	return NULL;
     }
     funcs = tvh->functions;
     demuxer->priv=tvh;
@@ -591,7 +591,7 @@
     if(!(funcs->start(tvh->priv))){
 	// start failed :(
 	tv_uninit(tvh);
-	return 0;
+	return NULL;
     }
 
     /* set color eq */
@@ -600,10 +600,10 @@
     tv_set_color_options(tvh, TV_COLOR_SATURATION, tv_param_saturation);
     tv_set_color_options(tvh, TV_COLOR_CONTRAST, tv_param_contrast);
 
-    return 1;
+    return demuxer;
 }
 
-int demux_close_tv(demuxer_t *demuxer)
+static int demux_close_tv(demuxer_t *demuxer)
 {
     tvi_handle_t *tvh=(tvi_handle_t*)(demuxer->priv);
     return(tvh->functions->uninit(tvh->priv));
@@ -853,4 +853,20 @@
     return(1);
 }
 
+demuxer_desc_t demuxer_desc_tv = {
+  "Tv card demuxer",
+  "tv",
+  "TV",
+  "Alex Beregszaszi, Charles R. Henrich",
+  "?",
+  DEMUXER_TYPE_TV,
+  0, // no autodetect
+  NULL,
+  demux_tv_fill_buffer,
+  demux_open_tv,
+  demux_close_tv,
+  NULL,
+  NULL
+};
+
 #endif /* USE_TV */
--- a/mencoder.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/mencoder.c	Fri Aug 05 19:57:47 2005 +0000
@@ -115,6 +115,9 @@
 static char** video_codec_list=NULL;  // override video codec
 static char** audio_fm_list=NULL;     // override audio codec family 
 static char** video_fm_list=NULL;     // override video codec family 
+extern char *demuxer_name; // override demuxer
+extern char *audio_demuxer_name; // override audio demuxer
+extern char *sub_demuxer_name; // override sub demuxer
 
 static int out_audio_codec=-1;
 static int out_video_codec=-1;
--- a/mplayer.c	Fri Aug 05 13:37:32 2005 +0000
+++ b/mplayer.c	Fri Aug 05 19:57:47 2005 +0000
@@ -249,6 +249,11 @@
 char **audio_fm_list=NULL;    // override audio codec family 
 char **video_fm_list=NULL;    // override video codec family 
 
+// demuxer:
+extern char *demuxer_name; // override demuxer
+extern char *audio_demuxer_name; // override audio demuxer
+extern char *sub_demuxer_name; // override sub demuxer
+
 // streaming:
 int audio_id=-1;
 int video_id=-1;
@@ -1268,6 +1273,13 @@
       exit_player_with_rc(NULL, 0);
     }
 #endif
+    if((demuxer_name && strcmp(demuxer_name,"help")==0) ||
+       (audio_demuxer_name && strcmp(audio_demuxer_name,"help")==0) ||
+       (sub_demuxer_name && strcmp(sub_demuxer_name,"help")==0)){
+      demuxer_help();
+      mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
+      exit_player_with_rc(NULL, 0);
+    }
 
 #ifdef USE_EDL
 if (edl_check_mode() == EDL_ERROR && edl_filename)