📄 m_option.c
字号:
"String list", "A list of strings separated by ','\n" "Option with a name ending in an * permits using the following suffix: \n" "\t-add: Add the given parameters at the end of the list.\n" "\t-pre: Add the given parameters at the begining of the list.\n" "\t-del: Remove the entry at the given indices.\n" "\t-clr: Clear the list.\n" "e.g: -vf-add flip,mirror -vf-del 2,5\n", sizeof(char**), M_OPT_TYPE_DYNAMIC | M_OPT_TYPE_ALLOW_WILDCARD, parse_str_list, print_str_list, copy_str_list, copy_str_list, copy_str_list, free_str_list}; /////////////////// Func based options// A chained list to save the various calls for func_param and func_fulltypedef struct m_func_save m_func_save_t;struct m_func_save { m_func_save_t* next; char* name; char* param;};#undef VAL#define VAL(x) (*(m_func_save_t**)(x))static void free_func_pf(void* src) { m_func_save_t *s,*n; if(!src) return; s = VAL(src); while(s) { n = s->next; free(s->name); if(s->param) free(s->param); free(s); s = n; } VAL(src) = NULL;}// Parser for func_param and func_fullstatic int parse_func_pf(m_option_t* opt,char *name, char *param, void* dst, int src) { m_func_save_t *s,*p; if(!dst) return 1; s = (m_func_save_t*)calloc(1,sizeof(m_func_save_t)); s->name = strdup(name); s->param = param ? strdup(param) : NULL; p = VAL(dst); if(p) { for( ; p->next != NULL ; p = p->next) /**/; p->next = s; } else VAL(dst) = s; return 1;}static void copy_func_pf(m_option_t* opt,void* dst, void* src) { m_func_save_t *d = NULL, *s,* last = NULL; if(!(dst && src)) return; s = VAL(src); if(VAL(dst)) free_func_pf(dst); while(s) { d = (m_func_save_t*)malloc(sizeof(m_func_save_t)); d->name = strdup(s->name); d->param = s->param ? strdup(s->param) : NULL; if(last) last->next = d; else VAL(dst) = d; last = d; s = s->next; } }/////////////////// Func_paramstatic void set_func_param(m_option_t* opt, void* dst, void* src) { m_func_save_t* s; if(!src) return; s = VAL(src); if(!s) return; // Revert if needed if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,opt->name); for( ; s != NULL ; s = s->next) ((m_opt_func_param_t) opt->p)(opt,s->param);}m_option_type_t m_option_type_func_param = { "Func param", "", sizeof(m_func_save_t*), M_OPT_TYPE_INDIRECT, parse_func_pf, NULL, NULL, // Nothing to do on save set_func_param, copy_func_pf, free_func_pf};/////////////////// Func_fullstatic void set_func_full(m_option_t* opt, void* dst, void* src) { m_func_save_t* s; if(!src) return; for(s = VAL(src) ; s ; s = s->next) { // Revert if needed if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,s->name); ((m_opt_func_full_t) opt->p)(opt,s->name,s->param); }}m_option_type_t m_option_type_func_full = { "Func full", "", sizeof(m_func_save_t*), M_OPT_TYPE_ALLOW_WILDCARD|M_OPT_TYPE_INDIRECT, parse_func_pf, NULL, NULL, // Nothing to do on save set_func_full, copy_func_pf, free_func_pf};/////////////// Func#undef VAL#define VAL(x) (*(int*)(x))static int parse_func(m_option_t* opt,char *name, char *param, void* dst, int src) { if(dst) VAL(dst) += 1; return 0;}static void set_func(m_option_t* opt,void* dst, void* src) { int i; if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,opt->name); for(i = 0 ; i < VAL(src) ; i++) ((m_opt_func_t) opt->p)(opt);}m_option_type_t m_option_type_func = { "Func", "", sizeof(int), M_OPT_TYPE_INDIRECT, parse_func, NULL, NULL, // Nothing to do on save set_func, NULL, NULL};/////////////////// Printstatic int parse_print(m_option_t* opt,char *name, char *param, void* dst, int src) { if(opt->type->flags&M_OPT_TYPE_INDIRECT) mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s", *(char **) opt->p); else mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s", (char *) opt->p); if(opt->priv == NULL) return M_OPT_EXIT; return 1;}m_option_type_t m_option_type_print = { "Print", "", 0, 0, parse_print, NULL, NULL, NULL, NULL, NULL};m_option_type_t m_option_type_print_indirect = { "Print", "", 0, M_OPT_TYPE_INDIRECT, parse_print, NULL, NULL, NULL, NULL, NULL};/////////////////////// Subconfig#undef VAL#define VAL(x) (*(char***)(x))static int parse_subconf(m_option_t* opt,char *name, char *param, void* dst, int src) { char *subparam; char *subopt; int nr = 0,i,r; m_option_t *subopts; char *token; char *p; char** lst = NULL; if (param == NULL || strlen(param) == 0) return M_OPT_MISSING_PARAM; subparam = malloc(strlen(param)+1); subopt = malloc(strlen(param)+1); p = strdup(param); // In case that param is a static string (cf man strtok) subopts = opt->p; token = strtok(p, (char *)&(":")); while(token) { int sscanf_ret; /* clear out */ subopt[0] = subparam[0] = 0; sscanf_ret = sscanf(token, "%[^=]=%[^:]", subopt, subparam); mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "token: '%s', subopt='%s', subparam='%s' (ret: %d)\n", token, subopt, subparam, sscanf_ret); switch(sscanf_ret) { 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: Unknown suboption %s\n",name,subopt); return M_OPT_UNKNOWN; } 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); lst[2*nr+1] = subparam[0] == 0 ? NULL : strdup(subparam); memset(&lst[2*(nr+1)],0,2*sizeof(char*)); nr++; } break; default: mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid subconfig argument! ('%s')\n", token); return M_OPT_INVALID; } token = strtok(NULL, (char *)&(":")); } free(subparam); free(subopt); free(p); if(dst) VAL(dst) = lst; return 1;}m_option_type_t m_option_type_subconfig = { "Subconfig", "The syntax is -option opt1=foo:flag:opt2=blah", sizeof(int), M_OPT_TYPE_HAS_CHILD, parse_subconf, NULL, NULL, NULL, NULL, NULL};#include "libmpcodecs/img_format.h"/* FIXME: snyc with img_format.h */static struct { char* name; unsigned int fmt;} mp_imgfmt_list[] = { {"444p", IMGFMT_444P}, {"422p", IMGFMT_422P}, {"411p", IMGFMT_411P}, {"yuy2", IMGFMT_YUY2}, {"uyvy", IMGFMT_UYVY}, {"yvu9", IMGFMT_YVU9}, {"if09", IMGFMT_IF09}, {"yv12", IMGFMT_YV12}, {"i420", IMGFMT_I420}, {"iyuv", IMGFMT_IYUV}, {"clpl", IMGFMT_CLPL}, {"hm12", IMGFMT_HM12}, {"y800", IMGFMT_Y800}, {"y8", IMGFMT_Y8}, {"nv12", IMGFMT_NV12}, {"nv21", IMGFMT_NV21}, {"bgr24", IMGFMT_BGR24}, {"bgr32", IMGFMT_BGR32}, {"bgr16", IMGFMT_BGR16}, {"bgr15", IMGFMT_BGR15}, {"bgr8", IMGFMT_BGR8}, {"bgr4", IMGFMT_BGR4}, {"bg4b", IMGFMT_BG4B}, {"bgr1", IMGFMT_BGR1}, {"rgb24", IMGFMT_RGB24}, {"rgb32", IMGFMT_RGB32}, {"rgb16", IMGFMT_RGB16}, {"rgb15", IMGFMT_RGB15}, {"rgb8", IMGFMT_RGB8}, {"rgb4", IMGFMT_RGB4}, {"rg4b", IMGFMT_RG4B}, {"rgb1", IMGFMT_RGB1}, {"rgba", IMGFMT_RGBA}, {"argb", IMGFMT_ARGB}, {"bgra", IMGFMT_BGRA}, {"abgr", IMGFMT_ABGR}, { NULL, 0 }};static int parse_imgfmt(m_option_t* opt,char *name, char *param, void* dst, int src) { uint32_t fmt = 0; int i; if (param == NULL || strlen(param) == 0) return M_OPT_MISSING_PARAM; if(!strcmp(param,"help")) { mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available formats:"); for(i = 0 ; mp_imgfmt_list[i].name ; i++) mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %s",mp_imgfmt_list[i].name); mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); return M_OPT_EXIT; } if (sscanf(param, "0x%x", &fmt) != 1) { for(i = 0 ; mp_imgfmt_list[i].name ; i++) { if(!strcasecmp(param,mp_imgfmt_list[i].name)) { fmt=mp_imgfmt_list[i].fmt; break; } } if(!mp_imgfmt_list[i].name) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: unknown format name: '%s'\n",name,param); return M_OPT_INVALID; } } if(dst) *((uint32_t*)dst) = fmt; return 1;}m_option_type_t m_option_type_imgfmt = { "Image format", "Please report any missing colorspaces.", sizeof(uint32_t), 0, parse_imgfmt, NULL, copy_opt, copy_opt, NULL, NULL};#include "libaf/af_format.h"/* FIXME: snyc with af_format.h */static struct { char* name; unsigned int fmt;} mp_afmt_list[] = { // SPECIAL {"mulaw", AF_FORMAT_MU_LAW}, {"alaw", AF_FORMAT_A_LAW}, {"mpeg2", AF_FORMAT_MPEG2}, {"ac3", AF_FORMAT_AC3}, {"imaadpcm", AF_FORMAT_IMA_ADPCM}, // ORIDNARY {"u8", AF_FORMAT_U8}, {"s8", AF_FORMAT_S8}, {"u16le", AF_FORMAT_U16_LE}, {"u16be", AF_FORMAT_U16_BE}, {"u16ne", AF_FORMAT_U16_NE}, {"s16le", AF_FORMAT_S16_LE}, {"s16be", AF_FORMAT_S16_BE}, {"s16ne", AF_FORMAT_S16_NE}, {"u24le", AF_FORMAT_U24_LE}, {"u24be", AF_FORMAT_U24_BE}, {"u24ne", AF_FORMAT_U24_NE}, {"s24le", AF_FORMAT_S24_LE}, {"s24be", AF_FORMAT_S24_BE}, {"s24ne", AF_FORMAT_S24_NE}, {"u32le", AF_FORMAT_U32_LE}, {"u32be", AF_FORMAT_U32_BE}, {"u32ne", AF_FORMAT_U32_NE}, {"s32le", AF_FORMAT_S32_LE}, {"s32be", AF_FORMAT_S32_BE}, {"s32ne", AF_FORMAT_S32_NE}, {"floatle", AF_FORMAT_FLOAT_LE}, {"floatbe", AF_FORMAT_FLOAT_BE}, {"floatne", AF_FORMAT_FLOAT_NE}, { NULL, 0 }};static int parse_afmt(m_option_t* opt,char *name, char *param, void* dst, int src) { uint32_t fmt = 0; int i; if (param == NULL || strlen(param) == 0) return M_OPT_MISSING_PARAM; if(!strcmp(param,"help")) { mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available formats:"); for(i = 0 ; mp_afmt_list[i].name ; i++) mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %s",mp_afmt_list[i].name); mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); return M_OPT_EXIT; } if (sscanf(param, "0x%x", &fmt) != 1) { for(i = 0 ; mp_afmt_list[i].name ; i++) { if(!strcasecmp(param,mp_afmt_list[i].name)) { fmt=mp_afmt_list[i].fmt; break; } } if(!mp_afmt_list[i].name) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: unknown format name: '%s'\n",name,param); return M_OPT_INVALID; } } if(dst) *((uint32_t*)dst) = fmt; return 1;}m_option_type_t m_option_type_afmt = { "Audio format", "Please report any missing formats.", sizeof(uint32_t), 0, parse_afmt, NULL, copy_opt, copy_opt, NULL, NULL};//// Objects (i.e. 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_UNKNOWN; } 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 has only %d params, so you can't give more than %d unnamed params.\n", opt_name,obj_name,oldmax,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 separator, 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); return M_OPT_EXIT; } 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"); return M_OPT_EXIT; } 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,separator); if(!ptr) { r = get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,NULL); n++; break; } if(ptr == last_ptr) { // Empty field, count it and go on nold++; last_ptr = ptr+1; continue; } ptr[0] = '\0'; r = get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,NULL); ptr[0] = separator; 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,separator); if(!ptr) { get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,&ret[n*2]); n++; break; } if(ptr == last_ptr) { // Empty field, count it and go on last_ptr = ptr+1; nold++; continue; } ptr[0] = '\0'; get_obj_param(opt_name,name,desc,last_ptr,&nold,nopts,&ret[n*2]); n++; last_ptr = ptr+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -