Add the new -vf option wich is the same as vop in reverse order.
authoralbeu <albeu@b3059339-0415-0410-9bf9-f77b7e298cf2>
Sat, 15 Mar 2003 18:01:02 +0000 (18:01 +0000)
committeralbeu <albeu@b3059339-0415-0410-9bf9-f77b7e298cf2>
Sat, 15 Mar 2003 18:01:02 +0000 (18:01 +0000)
Syntax is we decided, so you can give the nomes or not with both
vop and vf. vf take precedence over vop.

git-svn-id: svn://git.mplayerhq.hu/mplayer/trunk@9594 b3059339-0415-0410-9bf9-f77b7e298cf2

49 files changed:
cfg-common.h
libmpcodecs/vf.c
libmpcodecs/vf.h
libmpcodecs/vf_1bpp.c
libmpcodecs/vf_2xsai.c
libmpcodecs/vf_bmovl.c
libmpcodecs/vf_boxblur.c
libmpcodecs/vf_crop.c
libmpcodecs/vf_cropdetect.c
libmpcodecs/vf_denoise3d.c
libmpcodecs/vf_detc.c
libmpcodecs/vf_dint.c
libmpcodecs/vf_down3dright.c
libmpcodecs/vf_dvbscale.c
libmpcodecs/vf_eq.c
libmpcodecs/vf_eq2.c
libmpcodecs/vf_expand.c
libmpcodecs/vf_fame.c
libmpcodecs/vf_field.c
libmpcodecs/vf_flip.c
libmpcodecs/vf_format.c
libmpcodecs/vf_halfpack.c
libmpcodecs/vf_hqdn3d.c
libmpcodecs/vf_il.c
libmpcodecs/vf_lavc.c
libmpcodecs/vf_lavcdeint.c
libmpcodecs/vf_mirror.c
libmpcodecs/vf_noise.c
libmpcodecs/vf_palette.c
libmpcodecs/vf_perspective.c
libmpcodecs/vf_pp.c
libmpcodecs/vf_rectangle.c
libmpcodecs/vf_rgb2bgr.c
libmpcodecs/vf_rotate.c
libmpcodecs/vf_sab.c
libmpcodecs/vf_scale.c
libmpcodecs/vf_smartblur.c
libmpcodecs/vf_swapuv.c
libmpcodecs/vf_telecine.c
libmpcodecs/vf_test.c
libmpcodecs/vf_tfields.c
libmpcodecs/vf_unsharp.c
libmpcodecs/vf_vo.c
libmpcodecs/vf_yuy2.c
libmpcodecs/vf_yvu9.c
m_config.c
m_option.c
m_option.h
mplayer.c

index 4a8876e..ac222ef 100644 (file)
         {"pphelp", &pp_help, CONF_TYPE_PRINT_INDIRECT, CONF_NOCFG, 0, 0, NULL},
 #endif
 
-       {"vop", &vo_plugin_args, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
+       {"vop", &vo_plugin_args, CONF_TYPE_OBJ_SETTINGS_LIST, 0, 0, 0,&vf_obj_list },
+       {"vf", &vf_settings, CONF_TYPE_OBJ_SETTINGS_LIST, 0, 0, 0, &vf_obj_list},
 
        // scaling:
        {"sws", &sws_flags, CONF_TYPE_INT, 0, 0, 2, NULL},
@@ -336,6 +337,8 @@ extern int    mf_w;
 extern int    mf_h;
 extern float  mf_fps;
 extern char * mf_type;
+extern m_obj_settings_t* vf_settings;
+extern m_obj_list_t vf_obj_list;
 
 struct config mfopts_conf[]={
         {"on", &mf_support, CONF_TYPE_FLAG, 0, 0, 1, NULL},
@@ -346,7 +349,7 @@ struct config mfopts_conf[]={
         {NULL, NULL, 0, 0, 0, 0, NULL}
 };
                                                
-extern char** vo_plugin_args;
+extern m_obj_settings_t* vo_plugin_args;
 
 #include "libaf/af.h"
 extern af_cfg_t af_cfg; // Audio filter configuration, defined in libmpcodecs/dec_audio.c
index d4629d7..e833065 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "../mp_msg.h"
 #include "../help_mp.h"
+#include "../m_option.h"
+#include "../m_struct.h"
 
 
 #include "img_format.h"
@@ -60,8 +62,6 @@ extern vf_info_t vf_info_detc;
 extern vf_info_t vf_info_telecine;
 extern vf_info_t vf_info_tfields;
 
-char** vo_plugin_args=(char**) NULL;
-
 // list of available filters:
 static vf_info_t* filter_list[]={
     &vf_info_rectangle,
@@ -116,6 +116,17 @@ static vf_info_t* filter_list[]={
     NULL
 };
 
+// For the vf option
+m_obj_settings_t* vf_settings = NULL;
+// For the vop option
+m_obj_settings_t* vo_plugin_args = NULL;
+m_obj_list_t vf_obj_list = {
+  (void**)filter_list,
+  M_ST_OFF(vf_info_t,name),
+  M_ST_OFF(vf_info_t,info),
+  M_ST_OFF(vf_info_t,opts)
+};
+
 //============================================================================
 // mpi stuff:
 
@@ -306,7 +317,7 @@ static int vf_default_query_format(struct vf_instance_s* vf, unsigned int fmt){
   return vf_next_query_format(vf,fmt);
 }
 
-vf_instance_t* vf_open_plugin(vf_info_t** filter_list, vf_instance_t* next, char *name, char *args){
+vf_instance_t* vf_open_plugin(vf_info_t** filter_list, vf_instance_t* next, char *name, char **args){
     vf_instance_t* vf;
     int i;
     for(i=0;;i++){
@@ -326,18 +337,48 @@ vf_instance_t* vf_open_plugin(vf_info_t** filter_list, vf_instance_t* next, char
     vf->put_image=vf_next_put_image;
     vf->default_caps=VFCAP_ACCEPT_STRIDE;
     vf->default_reqs=0;
-    if(vf->info->open(vf,args)>0) return vf; // Success!
+    if(vf->info->opts) { // vf_vo get some special argument
+      m_struct_t* st = vf->info->opts;
+      void* vf_priv = m_struct_alloc(st);
+      int n;
+      for(n = 0 ; args && args[2*n] ; n++)
+       m_struct_set(st,vf_priv,args[2*n],args[2*n+1]);
+      vf->priv = vf_priv;
+      args = NULL;
+    } else // Otherwise we should have the '_oldargs_'
+      if(args && !strcmp(args[0],"_oldargs_"))
+       args = (char**)args[1];
+      else
+       args = NULL;
+    if(vf->info->open(vf,(char*)args)>0) return vf; // Success!
     free(vf);
     mp_msg(MSGT_VFILTER,MSGL_ERR,MSGTR_CouldNotOpenVideoFilter,name);
     return NULL;
 }
 
-vf_instance_t* vf_open_filter(vf_instance_t* next, char *name, char *args){
-    if(strcmp(name,"vo"))
-    mp_msg(MSGT_VFILTER,MSGL_INFO,
-       args ? MSGTR_OpeningVideoFilter "[%s=%s]\n"
-            : MSGTR_OpeningVideoFilter "[%s]\n",name,args);
-    return vf_open_plugin(filter_list,next,name,args);
+vf_instance_t* vf_open_filter(vf_instance_t* next, char *name, char **args){
+  if(args && strcmp(args[0],"_oldargs_")) {
+    int i,l = 0;
+    for(i = 0 ; args && args[2*i] ; i++)
+      l += 1 + strlen(args[2*i]) + 1 + strlen(args[2*i+1]);
+    l += strlen(name);
+    {
+      char str[l+1];
+      char* p = str;
+      p += sprintf(str,"%s",name);
+      for(i = 0 ; args && args[2*i] ; i++)
+       p += sprintf(p," %s=%s",args[2*i],args[2*i+1]);
+      mp_msg(MSGT_VFILTER,MSGL_INFO,MSGTR_OpeningVideoFilter "[%s]\n",str);
+    }
+  } else if(strcmp(name,"vo")) {
+    if(args && strcmp(args[0],"_oldargs_") == 0)
+      mp_msg(MSGT_VFILTER,MSGL_INFO,MSGTR_OpeningVideoFilter
+            "[%s=%s]\n", name,args[1]);
+    else
+      mp_msg(MSGT_VFILTER,MSGL_INFO,MSGTR_OpeningVideoFilter
+            "[%s]\n", name);
+  }
+  return vf_open_plugin(filter_list,next,name,args);
 }
 
 //============================================================================
@@ -425,19 +466,27 @@ void vf_next_draw_slice(struct vf_instance_s* vf,unsigned char** src, int * stri
 //============================================================================
 
 vf_instance_t* append_filters(vf_instance_t* last){
-    vf_instance_t* vf;
-    char** plugin_args = vo_plugin_args;
-    if(!vo_plugin_args) return last;
-    while(*plugin_args){
-       char* name=strdup(*plugin_args);
-       char* args=strchr(name,'=');
-       if(args){args[0]=0;++args;}
-       vf=vf_open_filter(last,name,args);
-       if(vf) last=vf;
-       free(name);
-       ++plugin_args;
+  vf_instance_t* vf;
+  int i; 
+
+  // -vf take precedence over -vop
+  if(vf_settings) {
+    // We want to add them in the 'right order'
+    for(i = 0 ; vf_settings[i].name ; i++)
+      /* NOP */;
+    for(i-- ; i >= 0 ; i--) {
+      //printf("Open filter %s\n",vf_settings[i].name);
+      vf = vf_open_filter(last,vf_settings[i].name,vf_settings[i].attribs);
+      if(vf) last=vf;
     }
-    return last;
+  } else if(vo_plugin_args) {
+    for(i = 0 ; vo_plugin_args[i].name ; i++) {
+      vf = vf_open_filter(last,vo_plugin_args[i].name,
+                         vo_plugin_args[i].attribs);
+      if(vf) last=vf;
+    }
+  }
+  return last;
 }
 
 //============================================================================
index ffe8ef9..1f21500 100644 (file)
@@ -8,6 +8,8 @@ typedef struct vf_info_s {
     const char *author;
     const char *comment;
     int (*open)(struct vf_instance_s* vf,char* args);
+    // Ptr to a struct dscribing the options
+    void* opts;
 } vf_info_t;
 
 typedef struct vf_image_context_s {
@@ -67,8 +69,8 @@ typedef struct vf_seteq_s
 void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h);
 mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h);
 
-vf_instance_t* vf_open_plugin(vf_info_t** filter_list, vf_instance_t* next, char *name, char *args);
-vf_instance_t* vf_open_filter(vf_instance_t* next, char *name, char *args);
+vf_instance_t* vf_open_plugin(vf_info_t** filter_list, vf_instance_t* next, char *name, char **args);
+vf_instance_t* vf_open_filter(vf_instance_t* next, char *name, char **args);
 vf_instance_t* vf_open_encoder(vf_instance_t* next, char *name, char *args);
 
 unsigned int vf_match_csp(vf_instance_t** vfp,unsigned int* list,unsigned int preferred);
index 2d6a959..f1c9e59 100644 (file)
@@ -178,7 +178,8 @@ vf_info_t vf_info_1bpp = {
     "1bpp",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 20db798..21a8f48 100644 (file)
@@ -357,7 +357,8 @@ vf_info_t vf_info_2xsai = {
     "2xsai",
     "A'rpi",
     "http://elektron.its.tudelft.nl/~dalikifa/",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 5cba56d..8f5bad8 100644 (file)
@@ -452,5 +452,6 @@ vf_info_t vf_info_bmovl = {
     "bmovl",
     "Per Wigren",
     "",
-    vf_open
+    vf_open,
+    NULL
 };
index a5e7f97..729c174 100644 (file)
@@ -212,7 +212,8 @@ vf_info_t vf_info_boxblur = {
     "boxblur",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index f00ccca..110bac5 100644 (file)
@@ -115,7 +115,8 @@ vf_info_t vf_info_crop = {
     "crop",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index c8d4aae..e8bdf83 100644 (file)
@@ -133,7 +133,8 @@ vf_info_t vf_info_cropdetect = {
     "cropdetect",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 03b4569..ea9e5f2 100644 (file)
@@ -265,7 +265,8 @@ vf_info_t vf_info_denoise3d = {
     "denoise3d",
     "Daniel Moreno",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index bccd3c6..bf311d7 100644 (file)
@@ -457,7 +457,8 @@ vf_info_t vf_info_detc = {
     "detc",
     "Rich Felker",
     "",
-    open
+    open,
+    NULL
 };
 
 
index 679a306..80f95b1 100644 (file)
@@ -191,5 +191,6 @@ vf_info_t vf_info_dint = {
     "dint",
     "A.G.",
     "",
-    open
+    open,
+    NULL
 };
index c142c05..6a9f979 100644 (file)
@@ -139,6 +139,7 @@ vf_info_t vf_info_down3dright = {
        "down3dright",
        "Zdenek Kabelac",
        "",
-       open
+       open,
+       NULL
 };
 
index 987482e..3dcdb1b 100644 (file)
@@ -42,7 +42,8 @@ vf_info_t vf_info_dvbscale = {
     "dvbscale",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 8ee2f6b..a5c27b7 100644 (file)
@@ -219,6 +219,7 @@ vf_info_t vf_info_eq = {
        "eq",
        "Richard Felker",
        "",
-       open
+       open,
+       NULL
 };
 
index 919b2ad..ae7ce9b 100644 (file)
@@ -463,5 +463,6 @@ vf_info_t vf_info_eq2 = {
   "eq2",
   "Hampa Hug, Daniel Moreno, Richard Felker",
   "",
-  &open
+  &open,
+  NULL
 };
index 550fdb2..e3681d9 100644 (file)
@@ -356,7 +356,8 @@ vf_info_t vf_info_expand = {
     "expand",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index a996019..820865e 100644 (file)
@@ -145,7 +145,8 @@ vf_info_t vf_info_fame = {
     "fame",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 0e2a5c9..21efc7b 100644 (file)
@@ -72,7 +72,8 @@ vf_info_t vf_info_field = {
     "field",
     "Rich Felker",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 78706af..7977dd9 100644 (file)
@@ -90,7 +90,8 @@ vf_info_t vf_info_flip = {
     "flip",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 5e351f0..772a575 100644 (file)
@@ -66,7 +66,8 @@ vf_info_t vf_info_format = {
     "format",
     "A'rpi",
     "FIXME! get_image()/put_image()",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index dac3c61..b4fc0e6 100644 (file)
@@ -216,6 +216,7 @@ vf_info_t vf_info_halfpack = {
        "halfpack",
        "Richard Felker",
        "",
-       open
+       open,
+       NULL
 };
 
index 341c282..ce59d0f 100644 (file)
@@ -290,7 +290,8 @@ vf_info_t vf_info_hqdn3d = {
     "hqdn3d",
     "Daniel Moreno & A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index d4e9a84..1cbf113 100644 (file)
@@ -145,7 +145,8 @@ vf_info_t vf_info_il = {
     "il",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 5c84665..57378e9 100644 (file)
@@ -200,7 +200,8 @@ vf_info_t vf_info_lavc = {
     "lavc",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index eee1287..7b4188e 100644 (file)
@@ -183,7 +183,8 @@ vf_info_t vf_info_lavcdeint = {
     "Joe Rabinoff",
     "libavcodec's internal deinterlacer, in case you don't like "
       "the builtin ones (invoked with -pp or -npp)",
-    open
+    open,
+    NULL
 };
 
 
index a16a062..3d77730 100644 (file)
@@ -109,7 +109,8 @@ vf_info_t vf_info_mirror = {
     "mirror",
     "Eyck",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 7a1ce5b..d11178a 100644 (file)
@@ -464,7 +464,8 @@ vf_info_t vf_info_noise = {
     "noise",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index b7f2cd7..51d6940 100644 (file)
@@ -190,7 +190,8 @@ vf_info_t vf_info_palette = {
     "palette",
     "A'rpi & Alex",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 30ee17f..59e2f3f 100644 (file)
@@ -335,7 +335,8 @@ vf_info_t vf_info_perspective = {
     "perspective",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 58b996b..f9b7903 100644 (file)
@@ -239,7 +239,8 @@ vf_info_t vf_info_pp = {
     "pp",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index a27c3f8..2325c08 100644 (file)
@@ -168,5 +168,6 @@ vf_info_t vf_info_rectangle = {
     "rectangle",
     "Kim Minh Kaplan",
     "",
-    open
+    open,
+    NULL
 };
index 99574b1..0db4b2c 100644 (file)
@@ -97,7 +97,8 @@ vf_info_t vf_info_rgb2bgr = {
     "rgb2bgr",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index fb5e7e9..5cb42a8 100644 (file)
@@ -130,7 +130,8 @@ vf_info_t vf_info_rotate = {
     "rotate",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index d4b6d5b..3c6e686 100644 (file)
@@ -311,7 +311,8 @@ vf_info_t vf_info_sab = {
     "sab",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index fd8a1f0..9637804 100644 (file)
 #include "../libvo/fastmemcpy.h"
 #include "../postproc/swscale.h"
 
-struct vf_priv_s {
+#include "m_option.h"
+#include "m_struct.h"
+
+static struct vf_priv_s {
     int w,h;
     int v_chr_drop;
     int param;
@@ -21,6 +24,14 @@ struct vf_priv_s {
     struct SwsContext *ctx;
     unsigned char* palette;
     mp_image_t *dmpi;
+} vf_priv_dflt = {
+  -1,-1,
+  0,
+  0,
+  0,
+  NULL,
+  NULL,
+  NULL
 };
 
 extern int opt_screen_size_x;
@@ -348,6 +359,7 @@ static int open(vf_instance_t *vf, char* args){
     vf->put_image=put_image;
     vf->query_format=query_format;
     vf->control= control;
+    if(!vf->priv) {
     vf->priv=malloc(sizeof(struct vf_priv_s));
     // TODO: parse args ->
     vf->priv->ctx=NULL;
@@ -356,6 +368,7 @@ static int open(vf_instance_t *vf, char* args){
     vf->priv->v_chr_drop=0;
     vf->priv->param=0;
     vf->priv->palette=NULL;
+    } // if(!vf->priv)
     if(args) sscanf(args, "%d:%d:%d:%d",
     &vf->priv->w,
     &vf->priv->h,
@@ -367,12 +380,66 @@ static int open(vf_instance_t *vf, char* args){
     return 1;
 }
 
+/// An example of presets usage
+static struct size_preset {
+  char* name;
+  int w, h;
+} vf_size_presets_defs[] = {
+  // TODO add more 'standard' resolutions
+  { "pal", 768, 576 },
+  { NULL, 0, 0}
+};
+
+#define ST_OFF(f) M_ST_OFF(struct size_preset,f)
+static m_option_t vf_size_preset_fields[] = {
+  {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL},
+  {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL},
+  { NULL, NULL, 0, 0, 0, 0,  NULL }
+};
+
+static m_struct_t vf_size_preset = {
+  "scale_size_preset",
+  sizeof(struct size_preset),
+  NULL,
+  vf_size_preset_fields
+};
+
+static m_struct_t vf_opts;
+static m_obj_presets_t size_preset = {
+  &vf_size_preset, // Input struct desc
+  &vf_opts, // Output struct desc
+  vf_size_presets_defs, // The list of presets
+  ST_OFF(name) // At wich offset is the name field in the preset struct
+};
+
+/// Now the options
+#undef ST_OFF
+#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)
+static m_option_t vf_opts_fields[] = {
+  {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL},
+  {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL},
+  {"chr-drop", ST_OFF(v_chr_drop), CONF_TYPE_INT, M_OPT_RANGE, 0, 3, NULL},
+  {"param", ST_OFF(param), CONF_TYPE_INT, M_OPT_RANGE, 0, 100, NULL},
+  // Note that here the 2 field is NULL (ie 0)
+  // As we want this option to act on the option struct itself
+  {"presize", 0, CONF_TYPE_OBJ_PRESETS, 0, 0, 0, &size_preset},
+  { NULL, NULL, 0, 0, 0, 0,  NULL }
+};
+
+static m_struct_t vf_opts = {
+  "scale",
+  sizeof(struct vf_priv_s),
+  &vf_priv_dflt,
+  vf_opts_fields
+};
+
 vf_info_t vf_info_scale = {
     "software scaling",
     "scale",
     "A'rpi",
     "",
-    open
+    open,
+    &vf_opts
 };
 
 //===========================================================================//
index 006a3f3..3156bd1 100644 (file)
@@ -266,7 +266,8 @@ vf_info_t vf_info_smartblur = {
     "smartblur",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 5e1df3a..d624bed 100644 (file)
@@ -106,7 +106,8 @@ vf_info_t vf_info_swapuv = {
     "swapuv",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index a71494d..b29f72c 100644 (file)
@@ -145,7 +145,8 @@ vf_info_t vf_info_telecine = {
     "telecine",
     "Rich Felker",
     "",
-    open
+    open,
+    NULL
 };
 
 
index 1f3a63b..d4adfde 100644 (file)
@@ -325,7 +325,8 @@ vf_info_t vf_info_test = {
     "test",
     "Michael Niedermayer",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 635fa40..6b1a226 100644 (file)
@@ -181,7 +181,8 @@ vf_info_t vf_info_tfields = {
     "tfields",
     "Rich Felker",
     "",
-    open
+    open,
+    NULL
 };
 
 
index 7a2384c..63248a7 100644 (file)
@@ -334,7 +334,8 @@ vf_info_t vf_info_unsharp = {
     "unsharp",
     "RĂ©mi Guyomarch",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index 05f6511..4fe36e0 100644 (file)
@@ -143,7 +143,8 @@ vf_info_t vf_info_vo = {
     "vo",
     "A'rpi",
     "for internal use",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index b7ab4b1..9d60d9a 100644 (file)
@@ -73,7 +73,8 @@ vf_info_t vf_info_yuy2 = {
     "yuy2",
     "A'rpi",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index c2dc079..6ab5a33 100644 (file)
@@ -81,7 +81,8 @@ vf_info_t vf_info_yvu9 = {
     "yvu9",
     "alex",
     "",
-    open
+    open,
+    NULL
 };
 
 //===========================================================================//
index abaf2b9..06f32fc 100644 (file)
@@ -239,7 +239,7 @@ m_config_parse_option(m_config_t *config, char* arg, char* param,int set) {
     char** lst = NULL;
     int i,sr;
     // Parse the child options
-    r = m_option_parse(co->opt,arg,param,&lst,config->mode);
+    r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE);
     // Set them now
     if(r >= 0)
     for(i = 0 ; lst && lst[2*i] ; i++) {
index 418214a..f623047 100644 (file)
 //#include "m_config.h"
 #include "mp_msg.h"
 
+// Don't free for 'production' atm
+#ifndef MP_DEBUG
+#define NO_FREE
+#endif
+
+m_option_t* m_option_list_find(m_option_t* list,char* name) {
+  int i;
+
+  for(i = 0 ; list[i].name ; i++) {
+    int l = strlen(list[i].name) - 1;
+    if((list[i].type->flags & M_OPT_TYPE_ALLOW_WILDCARD) &&
+       (l > 0) && (list[i].name[l] == '*')) {
+      if(strncasecmp(list[i].name,name,l) == 0)
+       return &list[i];
+    } else if(strcasecmp(list[i].name,name) == 0)
+      return &list[i];
+  }
+  return NULL;
+}
+
 // Default function that just do a memcpy
 
 static void copy_opt(m_option_t* opt,void* dst,void* src) {
@@ -321,14 +341,18 @@ static char* print_str(m_option_t* opt,  void* val) {
 
 static void copy_str(m_option_t* opt,void* dst, void* src) {
   if(dst && src) {
-//    if(VAL(dst)) free(VAL(dst)); //FIXME!!!
+#ifndef NO_FREE
+    if(VAL(dst)) free(VAL(dst)); //FIXME!!!
+#endif
     VAL(dst) = VAL(src) ? strdup(VAL(src)) : NULL;
   }
 }
   
 static void free_str(void* src) {
-  if(src && VAL(src)){ 
-//    free(VAL(src)); //FIXME!!!
+  if(src && VAL(src)){
+#ifndef NO_FREE
+    free(VAL(src)); //FIXME!!!
+#endif
     VAL(src) = NULL;
   }
 }
@@ -366,9 +390,11 @@ static void free_str_list(void* dst) {
   d = VAL(dst);
 
 // FIXME!!!
-//  for(i = 0 ; d[i] != NULL ; i++)
-//    free(d[i]);
-//  free(d);
+#ifndef NO_FREE
+  for(i = 0 ; d[i] != NULL ; i++)
+    free(d[i]);
+  free(d);
+#endif
   VAL(dst) = NULL;
 }
 
@@ -809,7 +835,7 @@ m_option_type_t m_option_type_print_indirect = {
 static int parse_subconf(m_option_t* opt,char *name, char *param, void* dst, int src) {
   char *subparam;
   char *subopt;
-  int nr = 0;
+  int nr = 0,i,r;
   m_option_t *subopts;
   char *token;
   char *p;
@@ -839,6 +865,16 @@ static int parse_subconf(m_option_t* opt,char *name, char *param, void* dst, int
        case 1:
          subparam[0] = 0;
        case 2:
+         for(i = 0 ; subopts[i].name ; i++) {
+           if(!strcmp(subopts[i].name,subopt)) break;
+         }
+         if(!subopts[i].name) {
+           mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Unknow suboption %s\n",name,subopt);
+           return M_OPT_UNKNOW;
+         }
+         r = m_option_parse(&subopts[i],subopt,
+                            subparam[0] == 0 ? NULL : subparam,NULL,src);
+         if(r < 0) return r;
          if(dst) {
            lst = (char**)realloc(lst,2 * (nr+2) * sizeof(char*));
            lst[2*nr] = strdup(subopt);
@@ -857,7 +893,8 @@ static int parse_subconf(m_option_t* opt,char *name, char *param, void* dst, int
   free(subparam);
   free(subopt);
   free(p);
-  VAL(dst) = lst;
+  if(dst)
+    VAL(dst) = lst;
 
   return 1;
 }
@@ -1040,4 +1077,395 @@ m_option_type_t m_option_type_span = {
   NULL
 };
 
+
+//// Objects (ie filters, etc) settings
+
+#include "m_struct.h"
+
+#undef VAL
+#define VAL(x) (*(m_obj_settings_t**)(x))
+
+static int find_obj_desc(char* name,m_obj_list_t* l,m_struct_t** ret) {
+  int i;
+  char* n;
+
+  for(i = 0 ; l->list[i] ; i++) {
+    n = M_ST_MB(char*,l->list[i],l->name_off);
+    if(!strcmp(n,name)) {
+      *ret = M_ST_MB(m_struct_t*,l->list[i],l->desc_off);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static int get_obj_param(char* opt_name,char* obj_name, m_struct_t* desc,
+                        char* str,int* nold,int oldmax,char** dst) {
+  char* eq,param;
+  m_option_t* opt;
+  int r;
+
+  eq = strchr(str,'=');
+  if(eq && eq == str)
+    eq = NULL;
+
+  if(eq) {
+    char* p = eq + 1;
+    if(p[0] == '\0') p = NULL;
+    eq[0] = '\0';
+    opt = m_option_list_find(desc->fields,str);
+    if(!opt) {
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: %s doesn't have a %s parameter\n",opt_name,obj_name,str);
+      return M_OPT_UNKNOW;
+    }
+    r = m_option_parse(opt,str,p,NULL,M_CONFIG_FILE);
+    if(r < 0) {
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: error while parsing %s parameter %s (%s)\n",opt_name,obj_name,str,p);
+      eq[0] = '=';
+      return r;
+    }
+    if(dst) {
+      dst[0] = strdup(str);
+      dst[1] = p ? strdup(p) : NULL;
+    }
+    eq[0] = '=';
+  } else {
+    if((*nold) >= oldmax) {
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: %s have only %d params, so yon can't give more than that unnamed params\n",
+            opt_name,obj_name,oldmax);
+      return M_OPT_OUT_OF_RANGE;
+    }
+    opt = &desc->fields[(*nold)];
+    r = m_option_parse(opt,opt->name,str,NULL,M_CONFIG_FILE);
+    if(r < 0) {
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: error while parsing %s parameter %s (%s)\n",opt_name,obj_name,opt->name,str);
+      return r;
+    }
+    if(dst) {
+      dst[0] = strdup(opt->name);
+      dst[1] = strdup(str);
+    }
+    (*nold)++;
+  }
+  return 1;
+}
+
+static int get_obj_params(char* opt_name, char* name,char* params,
+                         m_struct_t* desc,char*** _ret) {
+  int n = 0,nold = 0, nopts,r;
+  char* ptr,*last_ptr = params,*eq;
+  char** ret;
+
+  if(!strcmp(params,"help")) { // Help
+    char min[50],max[50];
+    if(!desc->fields) {
+      printf("%s doesn't have any options\n\n",name);
+      //exit_player();
+      exit(0);
+    }
+    printf("\n Name                 Type            Min        Max\n\n");
+    for(n = 0 ; desc->fields[n].name ; n++) {
+      m_option_t* opt = &desc->fields[n];
+      if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue;
+      if(opt->flags & M_OPT_MIN)
+       sprintf(min,"%-8.0f",opt->min);
+      else
+       strcpy(min,"No");
+      if(opt->flags & M_OPT_MAX)
+       sprintf(max,"%-8.0f",opt->max);
+      else
+       strcpy(max,"No");
+      printf(" %-20.20s %-15.15s %-10.10s %-10.10s\n",
+            opt->name,
+            opt->type->name,
+            min,
+            max);
+    }
+    printf("\n");
+    //exit_player() isn't avaible in mencoder
+    exit(0);
+  }
+
+  for(nopts = 0 ; desc->fields[nopts].name ; nopts++)
+    /* NOP */;
+
+  // TODO : Check that each opt can be parsed
+  r = 1;
+  while(last_ptr && last_ptr[0] != '\0') {
+    ptr = strchr(last_ptr,':');
+    if(!ptr) {
+      r = get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,NULL);
+      n++;
+      break;
+    }
+    ptr[0] = '\0';
+    r = get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,NULL);
+    ptr[0] = ':';
+    if(r < 0) break;
+    n++;
+    last_ptr = ptr+1;
+  }
+  if(r < 0) return r;
+  if(!_ret) // Just test
+    return 1;
+
+  ret = malloc((n+2)*2*sizeof(char*));
+  n = nold = 0;
+  last_ptr = params;
+  
+  while(last_ptr && last_ptr[0] != '\0') {
+    ptr = strchr(last_ptr,':');
+    if(!ptr) {
+      get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,&ret[n*2]);
+      n++;
+      break;
+    }
+    ptr[0] = '\0';
+    get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,&ret[n*2]);
+    n++;
+    last_ptr = ptr+1;
+  }
+  ret[n*2] = ret[n*2+1] = NULL;  
+  *_ret = ret;
+  
+  return 1;
+}
+
+
+static int parse_obj_settings(char* opt,char* str,m_obj_list_t* list,
+                             m_obj_settings_t **_ret, int ret_n) {
+  int r;
+  char *param,**plist = NULL;
+  m_struct_t* desc;
+  m_obj_settings_t *ret = _ret ? *_ret : NULL;
+  
+
+  // Now check that the object exist
+  param = strchr(str,'=');
+  if(param) {
+    param[0] = '\0';
+    param++;
+    if(strlen(param) <= 0)
+      param = NULL;
+  }
+
+
+  if(!find_obj_desc(str,list,&desc)) {
+    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: %s doesn't exist\n",opt,str);
+    return M_OPT_INVALID;
+  }
+
+  if(param) {
+    if(!desc && _ret) {
+      plist = calloc(4,sizeof(char*));
+      plist[0] = strdup("_oldargs_");
+      plist[1] = strdup(param);
+    } else if(desc) {
+      r = get_obj_params(opt,str,param,desc,_ret ? &plist : NULL);
+      if(r < 0)
+       return r;
+    }
+  }
+  if(!_ret)
+    return 1;
+
+  ret = realloc(ret,(ret_n+2)*sizeof(m_obj_settings_t));
+  memset(&ret[ret_n],0,2*sizeof(m_obj_settings_t));
+  ret[ret_n].name = strdup(str);
+  ret[ret_n].attribs = plist;
+
+  *_ret = ret;
+  return 1;
+}
+
+
+static int parse_obj_settings_list(m_option_t* opt,char *name,
+                                  char *param, void* dst, int src) {
+  int n = 0,r;
+  char *str;
+  char *ptr, *last_ptr;
+  m_obj_settings_t *res = NULL;
+
+  // We need the objects list
+  if(!opt->priv)
+    return M_OPT_INVALID;
+
+  if (param == NULL || strlen(param) == 0)
+    return M_OPT_MISSING_PARAM;
+
+  if(!strcmp(param,"help")) {
+    m_obj_list_t* ol = opt->priv;
+    for(n = 0 ; ol->list[n] ; n++)
+      mp_msg(MSGT_VFILTER,MSGL_INFO,"  %-15s: %s\n",
+            M_ST_MB(char*,ol->list[n],ol->name_off),
+            M_ST_MB(char*,ol->list[n],ol->info_off));
+    exit(0);
+  }
+  ptr = str = strdup(param);
+
+  while(ptr[0] != '\0') {
+    last_ptr = ptr;
+    ptr = strchr(ptr,LIST_SEPARATOR);
+    if(!ptr) {
+      r = parse_obj_settings(name,last_ptr,opt->priv,dst ? &res : NULL,n);
+      if(r < 0) {
+       free(str);
+       return r;
+      }
+      n++;
+      break;
+    }
+    ptr[0] = '\0';
+    r = parse_obj_settings(name,last_ptr,opt->priv,dst ? &res : NULL,n);
+    if(r < 0) {
+      free(str);
+      return r;
+    }
+    ptr++;
+    n++;
+  }
+  free(str);
+  if(n == 0)
+    return M_OPT_INVALID;
+
+  if( ((opt->flags & M_OPT_MIN) && (n < opt->min)) || 
+      ((opt->flags & M_OPT_MAX) && (n > opt->max)) )
+    return M_OPT_OUT_OF_RANGE;
+  
+  if(dst)
+    VAL(dst) = res;
+
+  return 1;
+}
+
+static void free_obj_settings_list(void* dst) {
+  int n;
+  m_obj_settings_t *d;
+
+  if(!dst || !VAL(dst)) return;
+
+  d = VAL(dst);
+#ifndef NO_FREE
+  for(n = 0 ; d[n].name ; n++) {
+    free(d[n].name);
+    free_str_list(&(d[n].attribs));
+  }
+  free(d);
+#endif
+  VAL(dst) = NULL;
+}
+
+static void copy_obj_settings_list(m_option_t* opt,void* dst, void* src) {
+  m_obj_settings_t *d,*s;
+  int n;
+
+  if(!(dst && src))
+    return;
+
+  s = VAL(src);
+
+  if(VAL(dst))
+    free_obj_settings_list(dst);
+  if(!s) return;
+    
+    
+  
+  for(n = 0 ; s[n].name ; n++)
+    /* NOP */;
+  d = malloc((n+1)*sizeof(m_obj_settings_t));
+  for(n = 0 ; s[n].name ; n++) {
+    d[n].name = strdup(s[n].name);
+    d[n].attribs = NULL;
+    copy_str_list(NULL,&(d[n].attribs),&(s[n].attribs));
+  }
+  d[n].name = d[n].attribs = NULL;
+  VAL(dst) = d;
+}
+
+m_option_type_t m_option_type_obj_settings_list = {
+  "Object settings list",
+  "",
+  sizeof(m_obj_settings_t*),
+  M_OPT_TYPE_DYNAMIC,
+  parse_obj_settings_list,
+  NULL,
+  copy_obj_settings_list,
+  copy_obj_settings_list,
+  copy_obj_settings_list,
+  free_obj_settings_list,
+};
+
+
+
+static int parse_obj_presets(m_option_t* opt,char *name,
+                           char *param, void* dst, int src) {
+  m_obj_presets_t* obj_p = (m_obj_presets_t*)opt->priv;
+  m_struct_t *in_desc,*out_desc;
+  int s,i;
+  unsigned char* pre = obj_p->presets;
+  char* pre_name = NULL;
+
+  if(!obj_p) {
+    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: presets need a pointer to a m_obj_presets_t in the priv field\n",name);
+    return M_OPT_PARSER_ERR;
+  }
+
+  if(!param)
+    return M_OPT_MISSING_PARAM;
+
+  in_desc = obj_p->in_desc;
+  out_desc = obj_p->out_desc ? obj_p->out_desc : obj_p->in_desc;
+  s = in_desc->size;
+
+  if(!strcmp(param,"help")) {
+    mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Avaible presets for %s->%s :",out_desc->name,name);
+    for(pre = obj_p->presets;(pre_name = M_ST_MB(char*,pre,obj_p->name_off)) ; 
+       pre +=  s) 
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s",pre_name);
+    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "\n");
+    exit(0);
+  }
+
+  for(pre_name = M_ST_MB(char*,pre,obj_p->name_off) ; pre_name ;
+      pre +=  s, pre_name = M_ST_MB(char*,pre,obj_p->name_off)) {
+    if(!strcmp(pre_name,param)) break;
+  }
+  if(!pre_name) {
+    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: there no preset named %s\n"
+          "Avaible presets are :",name,param);
+    for(pre = obj_p->presets;(pre_name = M_ST_MB(char*,pre,obj_p->name_off)) ; 
+       pre +=  s) 
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s",pre_name);
+    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "\n");
+    return M_OPT_INVALID;
+  }
+
+  if(!dst) return 1;
+  
+  for(i = 0 ; in_desc->fields[i].name ; i++) {
+    m_option_t* out_opt = m_option_list_find(out_desc->fields,
+                                            in_desc->fields[i].name);
+    if(!out_opt) {
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: unable to find the target option for field %s.\nYou should report that to the developpers\n",name,in_desc->fields[i].name);
+      return M_OPT_PARSER_ERR;
+    }
+    m_option_copy(out_opt,M_ST_MB_P(dst,out_opt->p),M_ST_MB_P(pre,in_desc->fields[i].p));
+  }
+  return 1;
+}
+
+
+m_option_type_t m_option_type_obj_presets = {
+  "Object presets",
+  "",
+  0,
+  0,
+  parse_obj_presets,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
+
 #endif
index 03cb364..33a3bb3 100644 (file)
@@ -5,6 +5,7 @@
 
 typedef struct m_option_type m_option_type_t;
 typedef struct m_option m_option_t;
+struct m_struct;
 
 ///////////////////////////// Options types declarations ////////////////////////////
 
@@ -52,6 +53,30 @@ typedef struct {
 } m_span_t;
 extern m_option_type_t m_option_type_span;
 
+typedef struct {
+  void** list;
+  void* name_off;
+  void* info_off;
+  void* desc_off;
+} m_obj_list_t;
+
+typedef struct {
+  char* name;
+  char** attribs;
+} m_obj_settings_t;
+extern m_option_type_t m_option_type_obj_settings_list;
+
+// Presets are mean to be used with options struct
+
+
+typedef struct {
+  struct m_struct* in_desc;
+  struct m_struct* out_desc;
+  void* presets; // Pointer to an arry of struct defined by in_desc
+  void* name_off; // Offset of the preset name inside the in_struct
+} m_obj_presets_t;
+extern m_option_type_t m_option_type_obj_presets;
+
 // Don't be stupid keep tho old names ;-)
 #define CONF_TYPE_FLAG         (&m_option_type_flag)
 #define CONF_TYPE_INT          (&m_option_type_int)
@@ -67,7 +92,8 @@ extern m_option_type_t m_option_type_span;
 #define CONF_TYPE_POSITION     (&m_option_type_position)
 #define CONF_TYPE_IMGFMT               (&m_option_type_imgfmt)
 #define CONF_TYPE_SPAN         (&m_option_type_span)
-
+#define CONF_TYPE_OBJ_SETTINGS_LIST (&m_option_type_obj_settings_list)
+#define CONF_TYPE_OBJ_PRESETS (&m_option_type_obj_presets)
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -181,6 +207,7 @@ struct m_option {
 #define M_OPT_OUT_OF_RANGE     -4
 #define M_OPT_PARSER_ERR               -5
 
+m_option_t* m_option_list_find(m_option_t* list,char* name);
 
 inline static int
 m_option_parse(m_option_t* opt,char *name, char *param, void* dst, int src) {
index d295efe..8d5210e 100644 (file)
--- a/mplayer.c
+++ b/mplayer.c
@@ -772,13 +772,6 @@ int gui_no_filename=0;
     }
 #endif
 
-    if(vo_plugin_args && vo_plugin_args[0] && strcmp(vo_plugin_args[0],"help")==0){
-      mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_AvailableVideoOutputPlugins);
-      vf_list_plugins();
-      printf("\n");
-      exit(0);
-    }
-
     if(video_driver_list && strcmp(video_driver_list[0],"help")==0){
       list_video_out();
       exit(0);
@@ -1539,11 +1532,14 @@ inited_flags|=INITED_VO;
 }
 
 current_module="init_video_filters";
-
-sh_video->vfilter=(void*)vf_open_filter(NULL,"vo",(char *)video_out);
+{
+  char* vf_arg[] = { "_oldargs_", (char*)video_out , NULL };
+  sh_video->vfilter=(void*)vf_open_filter(NULL,"vo",vf_arg);
+}
 #ifdef HAVE_MENU
 if(use_menu) {
-  vf_menu = vf_open_plugin(libmenu_vfs,sh_video->vfilter,"menu",menu_root);
+  char* vf_arg[] = { "_oldargs_", menu_root, NULL };
+  vf_menu = vf_open_plugin(libmenu_vfs,sh_video->vfilter,"menu",vf_arg);
   if(!vf_menu) {
     mp_msg(MSGT_CPLAYER,MSGL_ERR,"Can't open libmenu video filter with root menu %s\n",menu_root);
     use_menu = 0;