mirror of https://github.com/mpv-player/mpv
Add the new property API and implement a couple properties.
Move the volume and mute command to the command to property bridge. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@17912 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
87323740ed
commit
7ccf483026
1
Makefile
1
Makefile
|
@ -56,6 +56,7 @@ SRCS_MENCODER = mencoder.c \
|
|||
xvid_vbr.c \
|
||||
|
||||
SRCS_MPLAYER = mplayer.c \
|
||||
m_property.c \
|
||||
mp_msg.c \
|
||||
$(SRCS_COMMON) \
|
||||
mixer.c \
|
||||
|
|
|
@ -383,6 +383,7 @@ m_option_t mplayer_opts[]={
|
|||
{"term-osd", &term_osd, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"noterm-osd", &term_osd, CONF_TYPE_FLAG, 0, 0, 0, NULL},
|
||||
{"term-osd-esc", &term_osd_esc, CONF_TYPE_STRING, 0, 0, 1, NULL},
|
||||
{"playing-msg", &playing_msg, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
|
||||
{"slave", &slave_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL},
|
||||
{"idle", &player_idle_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL},
|
||||
|
|
|
@ -227,7 +227,17 @@ static char help_text[]=
|
|||
#define MSGTR_OSDSubBottom "bottom"
|
||||
#define MSGTR_OSDSubCenter "center"
|
||||
#define MSGTR_OSDSubTop "top"
|
||||
#define MSGTR_OSDMute "Mute: %s"
|
||||
|
||||
// property values
|
||||
#define MSGTR_Enabled "enabled"
|
||||
#define MSGTR_EnabledEdl "enabled (edl)"
|
||||
#define MSGTR_Disabled "disabled"
|
||||
|
||||
// osd bar names
|
||||
#define MSGTR_Volume "Volume"
|
||||
|
||||
// property state
|
||||
#define MSGTR_MuteStatus "Mute: %s"
|
||||
|
||||
// mencoder.c:
|
||||
|
||||
|
|
|
@ -66,9 +66,9 @@ static mp_cmd_t mp_cmds[] = {
|
|||
{ MP_CMD_SUB_STEP, "sub_step",1, { { MP_CMD_ARG_INT,{0} }, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_OSD, "osd",0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
|
||||
{ MP_CMD_OSD_SHOW_TEXT, "osd_show_text", 1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
|
||||
{ MP_CMD_VOLUME, "volume", 1, { { MP_CMD_ARG_INT,{0} }, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_VOLUME, "volume", 1, { { MP_CMD_ARG_FLOAT,{0} }, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_MIXER_USEMASTER, "use_master", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_MUTE, "mute", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_MUTE, "mute", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
|
||||
{ MP_CMD_CONTRAST, "contrast",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_GAMMA, "gamma", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_BRIGHTNESS, "brightness",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
|
@ -144,6 +144,8 @@ static mp_cmd_t mp_cmds[] = {
|
|||
{ MP_CMD_GET_VO_FULLSCREEN, "get_vo_fullscreen", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_GET_SUB_VISIBILITY, "get_sub_visibility", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_KEYDOWN_EVENTS, "key_down_event", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_SET_PROPERTY, "set_property", 2, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
|
||||
{ MP_CMD_GET_PROPERTY, "get_property", 1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
|
||||
|
||||
{ 0, NULL, 0, {} }
|
||||
};
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
#define MP_CMD_SUB_REMOVE 65
|
||||
#define MP_CMD_KEYDOWN_EVENTS 66
|
||||
#define MP_CMD_VO_BORDER 67
|
||||
#define MP_CMD_SET_PROPERTY 68
|
||||
#define MP_CMD_GET_PROPERTY 69
|
||||
|
||||
#define MP_CMD_GUI_EVENTS 5000
|
||||
#define MP_CMD_GUI_LOADFILE 5001
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "m_option.h"
|
||||
#include "m_property.h"
|
||||
#include "help_mp.h"
|
||||
|
||||
#define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5))
|
||||
|
||||
int m_property_do(m_option_t* prop, int action, void* arg) {
|
||||
if(!prop) return M_PROPERTY_UNKNOWN;
|
||||
return ((m_property_ctrl_f)prop->p)(prop,action,arg);
|
||||
}
|
||||
|
||||
|
||||
char* m_property_print(m_option_t* prop) {
|
||||
m_property_ctrl_f ctrl;
|
||||
void* val;
|
||||
char* ret;
|
||||
|
||||
if(!prop) return NULL;
|
||||
|
||||
ctrl = prop->p;
|
||||
// look if the property have it's own print func
|
||||
if(ctrl(prop,M_PROPERTY_PRINT,&ret) >= 0)
|
||||
return ret;
|
||||
// fallback on the default print for this type
|
||||
val = calloc(1,prop->type->size);
|
||||
if(ctrl(prop,M_PROPERTY_GET,val) <= 0) {
|
||||
free(val);
|
||||
return NULL;
|
||||
}
|
||||
ret = m_option_print(prop,val);
|
||||
free(val);
|
||||
return ret == (char*)-1 ? NULL : ret;
|
||||
}
|
||||
|
||||
int m_property_parse(m_option_t* prop, char* txt) {
|
||||
m_property_ctrl_f ctrl;
|
||||
void* val;
|
||||
int r;
|
||||
|
||||
if(!prop) return M_PROPERTY_UNKNOWN;
|
||||
|
||||
ctrl = prop->p;
|
||||
// try the property own parsing func
|
||||
if((r = ctrl(prop,M_PROPERTY_PARSE,txt)) != M_PROPERTY_NOT_IMPLEMENTED)
|
||||
return r;
|
||||
// fallback on the default
|
||||
val = calloc(1,prop->type->size);
|
||||
if((r = m_option_parse(prop,prop->name,txt,val,M_CONFIG_FILE)) <= 0) {
|
||||
free(val);
|
||||
return r;
|
||||
}
|
||||
r = ctrl(prop,M_PROPERTY_SET,val);
|
||||
m_option_free(prop,val);
|
||||
free(val);
|
||||
return r;
|
||||
}
|
||||
|
||||
char* m_properties_expand_string(m_option_t* prop_list,char* str) {
|
||||
int l,fr=0,pos=0,size=strlen(str)+512;
|
||||
char *p = NULL,*e,*ret = malloc(size), num_val;
|
||||
int skip = 0, lvl = 0, skip_lvl = 0;
|
||||
|
||||
while(str[0]) {
|
||||
if(str[0] == '\\') {
|
||||
int sl = 1;
|
||||
switch(str[1]) {
|
||||
case 'e':
|
||||
p = "\x1b", l = 1; break;
|
||||
case 'n':
|
||||
p = "\n", l = 1; break;
|
||||
case 'r':
|
||||
p = "\r", l = 1; break;
|
||||
case 't':
|
||||
p = "\t", l = 1; break;
|
||||
case 'x':
|
||||
if(str[2]) {
|
||||
char num[3] = { str[2], str[3], 0 };
|
||||
char* end = num;
|
||||
num_val = strtol(num,&end,16);
|
||||
sl = end-num;
|
||||
l = 1;
|
||||
p = &num_val;
|
||||
} else
|
||||
l = 0;
|
||||
break;
|
||||
default:
|
||||
p = str+1, l = 1;
|
||||
}
|
||||
str+=1+sl;
|
||||
} else if(lvl > 0 && str[0] == ')') {
|
||||
if(skip && lvl <= skip_lvl) skip = 0;
|
||||
lvl--, str++, l = 0;
|
||||
} else if(str[0] == '$' && str[1] == '{' && (e = strchr(str+2,'}'))) {
|
||||
int pl = e-str-2;
|
||||
char pname[pl+1];
|
||||
m_option_t* prop;
|
||||
memcpy(pname,str+2,pl);
|
||||
pname[pl] = 0;
|
||||
if((prop = m_option_list_find(prop_list,pname)) &&
|
||||
(p = m_property_print(prop)))
|
||||
l = strlen(p), fr = 1;
|
||||
else
|
||||
l = 0;
|
||||
str = e+1;
|
||||
} else if(str[0] == '?' && str[1] == '(' && (e = strchr(str+2,':'))) {
|
||||
int pl = e-str-2;
|
||||
char pname[pl+1];
|
||||
m_option_t* prop;
|
||||
lvl++;
|
||||
if(!skip) {
|
||||
memcpy(pname,str+2,pl);
|
||||
pname[pl] = 0;
|
||||
if(!(prop = m_option_list_find(prop_list,pname)) ||
|
||||
m_property_do(prop,M_PROPERTY_GET,NULL) < 0)
|
||||
skip = 1, skip_lvl = lvl;
|
||||
}
|
||||
str = e+1, l = 0;
|
||||
} else
|
||||
p = str, l = 1, str++;
|
||||
|
||||
if(skip || l <= 0) continue;
|
||||
|
||||
if(pos+l+1 > size) {
|
||||
size = pos+l+512;
|
||||
ret = realloc(ret,size);
|
||||
}
|
||||
memcpy(ret+pos,p,l);
|
||||
pos += l;
|
||||
if(fr) free(p), fr = 0;
|
||||
}
|
||||
|
||||
ret[pos] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Some generic property implementations
|
||||
|
||||
int m_property_int_ro(m_option_t* prop,int action,
|
||||
void* arg,int var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_GET:
|
||||
if(!arg) return 0;
|
||||
*(int*)arg = var;
|
||||
return 1;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int m_property_int_range(m_option_t* prop,int action,
|
||||
void* arg,int* var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_SET:
|
||||
if(!arg) return 0;
|
||||
M_PROPERTY_CLAMP(prop,*(int*)arg);
|
||||
*var = *(int*)arg;
|
||||
return 1;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
*var += (arg ? *(int*)arg : 1) *
|
||||
(action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
M_PROPERTY_CLAMP(prop,*var);
|
||||
return 1;
|
||||
}
|
||||
return m_property_int_ro(prop,action,arg,*var);
|
||||
}
|
||||
|
||||
int m_property_choice(m_option_t* prop,int action,
|
||||
void* arg,int* var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
*var += action == M_PROPERTY_STEP_UP ? 1 : prop->max;
|
||||
*var %= (int)prop->max+1;
|
||||
return 1;
|
||||
}
|
||||
return m_property_int_range(prop,action,arg,var);
|
||||
}
|
||||
|
||||
int m_property_flag(m_option_t* prop,int action,
|
||||
void* arg,int* var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
*var = *var == prop->min ? prop->max : prop->min;
|
||||
return 1;
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
*(char**)arg = strdup((*var > prop->min) ? MSGTR_Enabled : MSGTR_Disabled);
|
||||
return 1;
|
||||
}
|
||||
return m_property_int_range(prop,action,arg,var);
|
||||
}
|
||||
|
||||
int m_property_float_ro(m_option_t* prop,int action,
|
||||
void* arg,float var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_GET:
|
||||
if(!arg) return 0;
|
||||
*(float*)arg = var;
|
||||
return 1;
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
*(char**)arg = malloc(20);
|
||||
sprintf(*(char**)arg,"%.2f",var);
|
||||
return 1;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int m_property_float_range(m_option_t* prop,int action,
|
||||
void* arg,float* var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_SET:
|
||||
if(!arg) return 0;
|
||||
M_PROPERTY_CLAMP(prop,*(float*)arg);
|
||||
*var = *(float*)arg;
|
||||
return 1;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
*var += (arg ? *(float*)arg : 0.1) *
|
||||
(action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
M_PROPERTY_CLAMP(prop,*var);
|
||||
return 1;
|
||||
}
|
||||
return m_property_float_ro(prop,action,arg,*var);
|
||||
}
|
||||
|
||||
int m_property_delay(m_option_t* prop,int action,
|
||||
void* arg,float* var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
*(char**)arg = malloc(20);
|
||||
sprintf(*(char**)arg,"%d ms",ROUND((*var)*1000));
|
||||
return 1;
|
||||
default:
|
||||
return m_property_float_range(prop,action,arg,var);
|
||||
}
|
||||
}
|
||||
|
||||
int m_property_double_ro(m_option_t* prop,int action,
|
||||
void* arg,double var) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_GET:
|
||||
if(!arg) return 0;
|
||||
*(double*)arg = var;
|
||||
return 1;
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
*(char**)arg = malloc(20);
|
||||
sprintf(*(char**)arg,"%.2f",var);
|
||||
return 1;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int m_property_string_ro(m_option_t* prop,int action,void* arg,char* str) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_GET:
|
||||
if(!arg) return 0;
|
||||
*(char**)arg = str;
|
||||
return 1;
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
*(char**)arg = str ? strdup(str) : NULL;
|
||||
return 1;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
// Get the current value
|
||||
#define M_PROPERTY_GET 0
|
||||
// Get a string representing the current value
|
||||
#define M_PROPERTY_PRINT 1
|
||||
// Set a new value
|
||||
#define M_PROPERTY_SET 2
|
||||
// Set a new value from a string
|
||||
#define M_PROPERTY_PARSE 3
|
||||
// Increment the property
|
||||
#define M_PROPERTY_STEP_UP 4
|
||||
// Decrement the property
|
||||
#define M_PROPERTY_STEP_DOWN 5
|
||||
|
||||
// Return values for the control function
|
||||
#define M_PROPERTY_OK 1
|
||||
#define M_PROPERTY_ERROR 0
|
||||
// Returned when the property can't be used, for ex something about
|
||||
// the subs while playing audio only
|
||||
#define M_PROPERTY_UNAVAILABLE -1
|
||||
// Returned if the requested action is not implemented
|
||||
#define M_PROPERTY_NOT_IMPLEMENTED -2
|
||||
// Returned when asking for a property that doesn't exist
|
||||
#define M_PROPERTY_UNKNOWN -3
|
||||
// Returned when the action can't be done (like setting the volume when edl mute)
|
||||
#define M_PROPERTY_DISABLED -4
|
||||
|
||||
typedef int(*m_property_ctrl_f)(m_option_t* prop,int action,void* arg);
|
||||
|
||||
int m_property_do(m_option_t* prop, int action, void* arg);
|
||||
|
||||
char* m_property_print(m_option_t* prop);
|
||||
|
||||
int m_property_parse(m_option_t* prop, char* txt);
|
||||
|
||||
char* m_properties_expand_string(m_option_t* prop_list,char* str);
|
||||
|
||||
#define M_PROPERTY_CLAMP(prop,val) do { \
|
||||
if(((prop)->flags & M_OPT_MIN) && (val) < (prop)->min) \
|
||||
(val) = (prop)->min; \
|
||||
else if(((prop)->flags & M_OPT_MAX) && (val) > (prop)->max) \
|
||||
(val) = (prop)->max; \
|
||||
} while(0)
|
||||
|
||||
// Implement get
|
||||
int m_property_int_ro(m_option_t* prop,int action,
|
||||
void* arg,int var);
|
||||
|
||||
// Implement set, get and step up/down
|
||||
int m_property_int_range(m_option_t* prop,int action,
|
||||
void* arg,int* var);
|
||||
|
||||
// Same but cycle
|
||||
int m_property_choice(m_option_t* prop,int action,
|
||||
void* arg,int* var);
|
||||
|
||||
// Switch betwen min and max
|
||||
int m_property_flag(m_option_t* prop,int action,
|
||||
void* arg,int* var);
|
||||
|
||||
// Implement get, print
|
||||
int m_property_float_ro(m_option_t* prop,int action,
|
||||
void* arg,float var);
|
||||
|
||||
// Implement set, get and step up/down
|
||||
int m_property_float_range(m_option_t* prop,int action,
|
||||
void* arg,float* var);
|
||||
|
||||
// float with a print function which print the time in ms
|
||||
int m_property_delay(m_option_t* prop,int action,
|
||||
void* arg,float* var);
|
||||
|
||||
// Implement get, print
|
||||
int m_property_double_ro(m_option_t* prop,int action,
|
||||
void* arg,double var);
|
||||
|
||||
// get/print the string
|
||||
int m_property_string_ro(m_option_t* prop,int action,void* arg, char* str);
|
360
mplayer.c
360
mplayer.c
|
@ -42,6 +42,7 @@ extern int mp_input_win32_slave_cmd_func(int fd,char* dest,int size);
|
|||
|
||||
#include "m_option.h"
|
||||
#include "m_config.h"
|
||||
#include "m_property.h"
|
||||
|
||||
#include "cfg-mplayer-def.h"
|
||||
|
||||
|
@ -238,6 +239,7 @@ static int osd_duration = 1000;
|
|||
|
||||
static int term_osd = 1;
|
||||
static char* term_osd_esc = "\x1b[A\r\x1b[K";
|
||||
static char* playing_msg = NULL;
|
||||
// seek:
|
||||
static char *seek_to_sec=NULL;
|
||||
static off_t seek_to_byte=0;
|
||||
|
@ -1056,7 +1058,9 @@ static void log_sub(void){
|
|||
#define OSD_MSG_OSD_STATUS 4
|
||||
#define OSD_MSG_BAR 5
|
||||
#define OSD_MSG_PAUSE 6
|
||||
#define OSD_MSG_MUTE 7
|
||||
// Base id for the messages generated from the commmand to property bridge
|
||||
#define OSD_MSG_PROPERTY 0x100
|
||||
|
||||
|
||||
// These will later be implemented via properties and removed
|
||||
#define OSD_MSG_AV_DELAY 100
|
||||
|
@ -1302,6 +1306,288 @@ static void update_osd_msg(void) {
|
|||
}
|
||||
|
||||
|
||||
// General properties
|
||||
|
||||
static int mp_property_osdlevel(m_option_t* prop,int action,void* arg) {
|
||||
return m_property_choice(prop,action,arg,&osd_level);
|
||||
}
|
||||
|
||||
static int mp_property_playback_speed(m_option_t* prop,int action,void* arg) {
|
||||
switch(action) {
|
||||
case M_PROPERTY_SET:
|
||||
if(!arg) return 0;
|
||||
M_PROPERTY_CLAMP(prop,*(float*)arg);
|
||||
playback_speed = *(float*)arg;
|
||||
build_afilter_chain(sh_audio, &ao_data);
|
||||
return 1;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
playback_speed += (arg ? *(float*)arg : 0.1) *
|
||||
(action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
M_PROPERTY_CLAMP(prop,playback_speed);
|
||||
build_afilter_chain(sh_audio, &ao_data);
|
||||
return 1;
|
||||
}
|
||||
return m_property_float_range(prop,action,arg,&playback_speed);
|
||||
}
|
||||
|
||||
static int mp_property_path(m_option_t* prop,int action,void* arg) {
|
||||
return m_property_string_ro(prop,action,arg,filename);
|
||||
}
|
||||
|
||||
static int mp_property_filename(m_option_t* prop,int action,void* arg) {
|
||||
char* f;
|
||||
if(!filename) return M_PROPERTY_UNAVAILABLE;
|
||||
if(((f = strrchr(filename,'/')) || (f = strrchr(filename,'\\'))) && f[1])
|
||||
f++;
|
||||
else
|
||||
f = filename;
|
||||
return m_property_string_ro(prop,action,arg,f);
|
||||
}
|
||||
|
||||
|
||||
static int mp_property_demuxer(m_option_t* prop,int action,void* arg) {
|
||||
if(!demuxer) return M_PROPERTY_UNAVAILABLE;
|
||||
return m_property_string_ro(prop,action,arg,(char*)demuxer->desc->name);
|
||||
}
|
||||
|
||||
static int mp_property_length(m_option_t* prop,int action,void* arg) {
|
||||
double len;
|
||||
|
||||
if(!demuxer ||
|
||||
!(int)(len = demuxer_get_time_length(demuxer)))
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch(action) {
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
else {
|
||||
int h, m, s = len;
|
||||
h = s/3600;
|
||||
s -= h*3600;
|
||||
m = s/60;
|
||||
s -= m*60;
|
||||
*(char**)arg = malloc(20);
|
||||
if(h > 0) sprintf(*(char**)arg,"%d:%02d:%02d",h,m,s);
|
||||
else if(m > 0) sprintf(*(char**)arg,"%d:%02d",m,s);
|
||||
else sprintf(*(char**)arg,"%d",s);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return m_property_double_ro(prop,action,arg,len);
|
||||
}
|
||||
|
||||
// Audio properties
|
||||
|
||||
static int mp_property_volume(m_option_t* prop,int action,void* arg) {
|
||||
|
||||
if(!sh_audio) return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch(action) {
|
||||
case M_PROPERTY_GET:
|
||||
if(!arg) return 0;
|
||||
mixer_getbothvolume(&mixer,arg);
|
||||
return 1;
|
||||
case M_PROPERTY_PRINT:{
|
||||
float vol;
|
||||
if(!arg) return 0;
|
||||
mixer_getbothvolume(&mixer,&vol);
|
||||
return m_property_float_range(prop,action,arg,&vol);
|
||||
}
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
case M_PROPERTY_SET:
|
||||
break;
|
||||
default:
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#ifdef USE_EDL
|
||||
if (edl_muted) return M_PROPERTY_DISABLED;
|
||||
user_muted = 0;
|
||||
#endif
|
||||
|
||||
switch(action) {
|
||||
case M_PROPERTY_SET:
|
||||
if(!arg) return 0;
|
||||
M_PROPERTY_CLAMP(prop,*(float*)arg);
|
||||
mixer_setvolume(&mixer,*(float*)arg,*(float*)arg);
|
||||
return 1;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
if(arg && *(float*)arg <= 0)
|
||||
mixer_decvolume(&mixer);
|
||||
else
|
||||
mixer_incvolume(&mixer);
|
||||
return 1;
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
if(arg && *(float*)arg <= 0)
|
||||
mixer_incvolume(&mixer);
|
||||
else
|
||||
mixer_decvolume(&mixer);
|
||||
return 1;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
static int mp_property_mute(m_option_t* prop,int action,void* arg) {
|
||||
|
||||
if(!sh_audio) return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch(action) {
|
||||
case M_PROPERTY_SET:
|
||||
#ifdef USE_EDL
|
||||
if(edl_muted) return M_PROPERTY_DISABLED;
|
||||
#endif
|
||||
if(!arg) return 0;
|
||||
if((!!*(int*)arg) != mixer.muted)
|
||||
mixer_mute(&mixer);
|
||||
return 1;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
#ifdef USE_EDL
|
||||
if(edl_muted) return M_PROPERTY_DISABLED;
|
||||
#endif
|
||||
mixer_mute(&mixer);
|
||||
return 1;
|
||||
case M_PROPERTY_PRINT:
|
||||
if(!arg) return 0;
|
||||
#ifdef USE_EDL
|
||||
if(edl_muted) {
|
||||
*(char**)arg = strdup(MSGTR_EnabledEdl);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return m_property_flag(prop,action,arg,&mixer.muted);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static m_option_t mp_properties[] = {
|
||||
// General
|
||||
{ "osdlevel", mp_property_osdlevel, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, 0, 3, NULL },
|
||||
{ "speed", mp_property_playback_speed, CONF_TYPE_FLOAT,
|
||||
M_OPT_RANGE, 0.01, 100.0, NULL },
|
||||
{ "filename", mp_property_filename, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "path", mp_property_path, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "demuxer", mp_property_demuxer, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "length", mp_property_length, CONF_TYPE_DOUBLE,
|
||||
0, 0, 0, NULL },
|
||||
|
||||
// Audio
|
||||
{ "volume", mp_property_volume, CONF_TYPE_FLOAT,
|
||||
M_OPT_RANGE, 0, 100, NULL },
|
||||
{ "mute", mp_property_mute, CONF_TYPE_FLAG,
|
||||
M_OPT_RANGE, 0, 1, NULL },
|
||||
{ NULL, NULL, NULL, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
m_option_t* mp_property_find(char* name) {
|
||||
return m_option_list_find(mp_properties,name);
|
||||
}
|
||||
|
||||
int mp_property_do(char* name,int action, void* val) {
|
||||
m_option_t* p = mp_property_find(name);
|
||||
if(!p) return M_PROPERTY_UNAVAILABLE;
|
||||
return m_property_do(p,action,val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* \brief Commands to property bridge.
|
||||
*
|
||||
* It is used to handle most commands that just set a property
|
||||
* and optionaly display something on the OSD.
|
||||
* Two kinds of commands are handled: adjust or toggle.
|
||||
*
|
||||
* Adjust commands take 1 or 2 paramter: <value> <abs>
|
||||
* If <abs> is none zero the property is set to the given value
|
||||
* otherwise it is adjusted.
|
||||
*
|
||||
* Toggle commands take 0 or 1 parameter. With no parameter
|
||||
* or a value less than the property minimum it just step the
|
||||
* property to it's next value. Otherwise it set it to the given
|
||||
* value.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char* name; // property name
|
||||
int cmd; // cmd id
|
||||
int toggle; // set/adjust or toggle command
|
||||
int osd_progbar; // progbar type
|
||||
int osd_id; // osd msg id if it must be shared
|
||||
char* osd_msg; // osd msg template
|
||||
} set_prop_cmd[] = {
|
||||
// audio
|
||||
{ "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume },
|
||||
{ "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus },
|
||||
|
||||
{ NULL, 0, 0, 0, -1, NULL }
|
||||
};
|
||||
|
||||
static int set_property_command(mp_cmd_t* cmd) {
|
||||
int i,r;
|
||||
m_option_t* prop;
|
||||
|
||||
// look for the command
|
||||
for(i = 0 ; set_prop_cmd[i].name ; i++)
|
||||
if(set_prop_cmd[i].cmd == cmd->id) break;
|
||||
if(!set_prop_cmd[i].name) return 0;
|
||||
|
||||
// get the property
|
||||
prop = mp_property_find(set_prop_cmd[i].name);
|
||||
if(!prop) return 0;
|
||||
|
||||
// toggle command
|
||||
if(set_prop_cmd[i].toggle) {
|
||||
// set to value
|
||||
if(cmd->nargs > 0 && cmd->args[0].v.i >= prop->min)
|
||||
r = m_property_do(prop,M_PROPERTY_SET,&cmd->args[0].v.i);
|
||||
else
|
||||
r = m_property_do(prop,M_PROPERTY_STEP_UP,NULL);
|
||||
} else if(cmd->args[1].v.i) //set
|
||||
r = m_property_do(prop,M_PROPERTY_SET,&cmd->args[0].v);
|
||||
else // adjust
|
||||
r = m_property_do(prop,M_PROPERTY_STEP_UP,&cmd->args[0].v);
|
||||
|
||||
if(r <= 0) return 1;
|
||||
|
||||
if(set_prop_cmd[i].osd_progbar) {
|
||||
if(prop->type == CONF_TYPE_INT) {
|
||||
if(m_property_do(prop,M_PROPERTY_GET,&r) > 0)
|
||||
set_osd_bar(set_prop_cmd[i].osd_progbar,
|
||||
set_prop_cmd[i].osd_msg,
|
||||
prop->min,prop->max,r);
|
||||
} else if(prop->type == CONF_TYPE_FLOAT) {
|
||||
float f;
|
||||
if(m_property_do(prop,M_PROPERTY_GET,&f) > 0)
|
||||
set_osd_bar(set_prop_cmd[i].osd_progbar,set_prop_cmd[i].osd_msg,
|
||||
prop->min,prop->max,f);
|
||||
} else
|
||||
mp_msg(MSGT_CPLAYER,MSGL_ERR, "Property use an unsupported type.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(set_prop_cmd[i].osd_msg) {
|
||||
char* val = m_property_print(prop);
|
||||
if(val) {
|
||||
set_osd_msg(set_prop_cmd[i].osd_id >= 0 ? set_prop_cmd[i].osd_id :
|
||||
OSD_MSG_PROPERTY+i,1,osd_duration,
|
||||
set_prop_cmd[i].osd_msg,val);
|
||||
free(val);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc,char* argv[]){
|
||||
|
||||
|
||||
|
@ -2421,6 +2707,13 @@ current_module="init_vo";
|
|||
main:
|
||||
current_module="main";
|
||||
|
||||
if(playing_msg) {
|
||||
char* msg = m_properties_expand_string(mp_properties,playing_msg);
|
||||
mp_msg(MSGT_CPLAYER,MSGL_INFO,"%s",msg);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
|
||||
// Disable the term osd in verbose mode
|
||||
if(verbose) term_osd = 0;
|
||||
fflush(stdout);
|
||||
|
@ -3115,6 +3408,7 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
|
|||
mp_cmd_t* cmd;
|
||||
int brk_cmd = 0;
|
||||
while( !brk_cmd && (cmd = mp_input_get_cmd(0,0,0)) != NULL) {
|
||||
if(!set_property_command(cmd))
|
||||
switch(cmd->id) {
|
||||
case MP_CMD_SEEK : {
|
||||
float v;
|
||||
|
@ -3141,6 +3435,35 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
|
|||
}
|
||||
brk_cmd = 1;
|
||||
} break;
|
||||
case MP_CMD_SET_PROPERTY: {
|
||||
m_option_t* prop = mp_property_find(cmd->args[0].v.s);
|
||||
if(!prop) mp_msg(MSGT_CPLAYER,MSGL_WARN,"Unkown property: '%s'\n",cmd->args[0].v.s);
|
||||
else if(m_property_parse(prop,cmd->args[1].v.s) <= 0)
|
||||
mp_msg(MSGT_CPLAYER,MSGL_WARN,"Failed to set property '%s' to '%s'.\n",
|
||||
cmd->args[0].v.s,cmd->args[1].v.s);
|
||||
|
||||
} break;
|
||||
case MP_CMD_GET_PROPERTY: {
|
||||
m_option_t* prop;
|
||||
void* val;
|
||||
prop = mp_property_find(cmd->args[0].v.s);
|
||||
if(!prop) mp_msg(MSGT_CPLAYER,MSGL_WARN,"Unkown property: '%s'\n",cmd->args[0].v.s);
|
||||
// use m_option_print directly to get easily parsable values
|
||||
val = calloc(1,prop->type->size);
|
||||
if(m_property_do(prop,M_PROPERTY_GET,val) <= 0) {
|
||||
mp_msg(MSGT_CPLAYER,MSGL_WARN,"Failed to get value of property '%s'.\n",
|
||||
cmd->args[0].v.s);
|
||||
break;
|
||||
}
|
||||
tmp = m_option_print(prop,val);
|
||||
if(!tmp || tmp == (char*)-1) {
|
||||
mp_msg(MSGT_CPLAYER,MSGL_WARN,"Failed to print value of property '%s'.\n",
|
||||
cmd->args[0].v.s);
|
||||
break;
|
||||
}
|
||||
mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_%s=%s\n",cmd->args[0].v.s,tmp);
|
||||
free(tmp);
|
||||
} break;
|
||||
#ifdef USE_EDL
|
||||
case MP_CMD_EDL_MARK:
|
||||
if( edl_fd ) {
|
||||
|
@ -3292,41 +3615,6 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
|
|||
case MP_CMD_OSD_SHOW_TEXT : {
|
||||
set_osd_msg(OSD_MSG_TEXT,1,osd_duration,"%64s",cmd->args[0].v.s);
|
||||
} break;
|
||||
case MP_CMD_VOLUME : {
|
||||
int v = cmd->args[0].v.i;
|
||||
|
||||
// start change for absolute volume value
|
||||
int abs = (cmd->nargs > 1) ? cmd->args[1].v.i : 0;
|
||||
|
||||
#ifdef USE_EDL
|
||||
if (edl_muted) break;
|
||||
user_muted = 0;
|
||||
#endif
|
||||
if( abs )
|
||||
{
|
||||
mixer_setvolume(&mixer, (float)v, (float)v );
|
||||
} else {
|
||||
if(v > 0)
|
||||
mixer_incvolume(&mixer);
|
||||
else
|
||||
mixer_decvolume(&mixer);
|
||||
}
|
||||
|
||||
if(1){
|
||||
float vol;
|
||||
mixer_getbothvolume(&mixer, &vol);
|
||||
set_osd_bar(OSD_VOLUME,"Volume",0,100,vol);
|
||||
}
|
||||
} break;
|
||||
case MP_CMD_MUTE:
|
||||
#ifdef USE_EDL
|
||||
user_muted = !user_muted;
|
||||
if ((edl_muted | user_muted) != mixer.muted)
|
||||
#endif
|
||||
mixer_mute(&mixer);
|
||||
set_osd_msg(OSD_MSG_MUTE,1,osd_duration, MSGTR_OSDMute,
|
||||
mixer.muted ? MSGTR_OSDenabled : MSGTR_OSDdisabled);
|
||||
break;
|
||||
case MP_CMD_LOADFILE : {
|
||||
play_tree_t* e = play_tree_new();
|
||||
play_tree_add_file(e,cmd->args[0].v.s);
|
||||
|
|
Loading…
Reference in New Issue