summaryrefslogtreecommitdiffstats
path: root/command.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-09-18 20:07:24 +0200
committerwm4 <wm4@nowhere>2012-10-12 10:10:31 +0200
commitdec53f760e12254e4baa4f7cee59010b3b10b6be (patch)
tree41edc95ce49dca2a7188bc88f9a7a9eb2964963c /command.c
parent28f43ce9a9d543fccb10aaf574282c349408946f (diff)
downloadmpv-dec53f760e12254e4baa4f7cee59010b3b10b6be.tar.bz2
mpv-dec53f760e12254e4baa4f7cee59010b3b10b6be.tar.xz
commands: add more property-option bridge uses, rename some options
Make more properties use the property-to-option bridge to reduce code size and to enforce consistency. Some options are renamed to the same as the properties (the property names are better in all cases). Do some other minor cleanups. One bigger issue was memory management of strings: M_PROPERTY_TO_STRING assumed the strings were statically allocated, and no dynamic allocations could be returned. Fix this in case the need for such properties arises in the future. Get rid of m_property_string_ro(), because it's not always clear that the "action" parameter is M_PROPERTY_SET and the string argument will be used.
Diffstat (limited to 'command.c')
-rw-r--r--command.c460
1 files changed, 203 insertions, 257 deletions
diff --git a/command.c b/command.c
index acdcee22d2..6db4310f46 100644
--- a/command.c
+++ b/command.c
@@ -114,23 +114,24 @@ static void rescale_input_coordinates(struct MPContext *mpctx, int ix, int iy,
vo->dheight, vo_fs);
}
+// Property-option bridge.
static int mp_property_generic_option(struct m_option *prop, int action,
void *arg, MPContext *mpctx)
{
char *optname = prop->priv;
- const struct m_option *opt = m_config_get_option(mpctx->mconfig,
- bstr0(optname));
- void *valptr = m_option_get_ptr(opt, &mpctx->opts);
+ struct m_config_option *opt = m_config_get_co(mpctx->mconfig,
+ bstr0(optname));
+ void *valptr = opt->data;
switch (action) {
case M_PROPERTY_GET_TYPE:
- *(const struct m_option **)arg = opt;
+ *(const struct m_option **)arg = opt->opt;
return M_PROPERTY_OK;
case M_PROPERTY_GET:
- m_option_copy(opt, arg, valptr);
+ m_option_copy(opt->opt, arg, valptr);
return M_PROPERTY_OK;
case M_PROPERTY_SET:
- m_option_copy(opt, valptr, arg);
+ m_option_copy(opt->opt, valptr, arg);
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
@@ -141,36 +142,42 @@ static int mp_property_playback_speed(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
- double orig_speed = opts->playback_speed;
- switch (action) {
- case M_PROPERTY_SET:
+ if (action == M_PROPERTY_SET) {
+ double orig_speed = opts->playback_speed;
opts->playback_speed = *(float *) arg;
// Adjust time until next frame flip for nosound mode
mpctx->time_frame *= orig_speed / opts->playback_speed;
reinit_audio_chain(mpctx);
return M_PROPERTY_OK;
}
- return m_property_float_range(prop, action, arg, &opts->playback_speed);
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// filename with path (RO)
static int mp_property_path(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return m_property_string_ro(prop, action, arg, mpctx->filename);
+ if (action == M_PROPERTY_GET) {
+ *(char **)arg = talloc_strdup(NULL, mpctx->filename);
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// filename without path (RO)
static int mp_property_filename(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- char *f;
if (!mpctx->filename)
return M_PROPERTY_UNAVAILABLE;
- f = (char *)mp_basename(mpctx->filename);
- if (!*f)
- f = mpctx->filename;
- return m_property_string_ro(prop, action, arg, f);
+ if (action == M_PROPERTY_GET) {
+ char *f = (char *)mp_basename(mpctx->filename);
+ if (!*f)
+ f = mpctx->filename;
+ *(char **)arg = talloc_strdup(NULL, f);
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Demuxer name (RO)
@@ -180,7 +187,11 @@ static int mp_property_demuxer(m_option_t *prop, int action, void *arg,
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
- return m_property_string_ro(prop, action, arg, (char *)demuxer->desc->name);
+ if (action == M_PROPERTY_GET) {
+ *(char **)arg = talloc_strdup(NULL, demuxer->desc->name);
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Position in the stream (RW)
@@ -277,21 +288,19 @@ static int mp_property_length(m_option_t *prop, int action, void *arg,
static int mp_property_percent_pos(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
- int pos;
-
if (!mpctx->num_sources)
return M_PROPERTY_UNAVAILABLE;
switch (action) {
- case M_PROPERTY_SET:
- pos = *(int *)arg;
- break;
- default:
- return m_property_int_ro(prop, action, arg, get_percent_pos(mpctx));
+ case M_PROPERTY_SET: ;
+ int pos = *(int *)arg;
+ queue_seek(mpctx, MPSEEK_FACTOR, pos / 100.0, 0);
+ return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(int *)arg = get_percent_pos(mpctx);
+ return M_PROPERTY_OK;
}
-
- queue_seek(mpctx, MPSEEK_FACTOR, pos / 100.0, 0);
- return M_PROPERTY_OK;
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Current position in seconds (RW)
@@ -305,8 +314,11 @@ static int mp_property_time_pos(m_option_t *prop, int action,
case M_PROPERTY_SET:
queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, 0);
return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(double *)arg = get_current_time(mpctx);
+ return M_PROPERTY_OK;
}
- return m_property_double_ro(prop, action, arg, get_current_time(mpctx));
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Current chapter (RW)
@@ -314,7 +326,6 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
- int step_all;
char *chapter_name = NULL;
int chapter = get_current_chapter(mpctx);
@@ -332,30 +343,27 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
*(char **) arg = chapter_name;
return M_PROPERTY_OK;
}
- case M_PROPERTY_SET:
- step_all = *(int *)arg - chapter;
+ case M_PROPERTY_SET: ;
+ int step_all = *(int *)arg - chapter;
chapter += step_all;
- break;
- default:
- return M_PROPERTY_NOT_IMPLEMENTED;
+ double next_pts = 0;
+ queue_seek(mpctx, MPSEEK_NONE, 0, 0);
+ chapter = seek_chapter(mpctx, chapter, &next_pts);
+ if (chapter >= 0) {
+ if (next_pts > -1.0)
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, next_pts, 0);
+ chapter_name = chapter_display_name(mpctx, chapter);
+ set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, opts->osd_duration,
+ "Chapter: %s", chapter_name);
+ } else if (step_all > 0)
+ mpctx->stop_play = PT_NEXT_ENTRY;
+ else
+ set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, opts->osd_duration,
+ "Chapter: (%d) %s", 0, mp_gtext("unknown"));
+ talloc_free(chapter_name);
+ return M_PROPERTY_OK;
}
-
- double next_pts = 0;
- queue_seek(mpctx, MPSEEK_NONE, 0, 0);
- chapter = seek_chapter(mpctx, chapter, &next_pts);
- if (chapter >= 0) {
- if (next_pts > -1.0)
- queue_seek(mpctx, MPSEEK_ABSOLUTE, next_pts, 0);
- chapter_name = chapter_display_name(mpctx, chapter);
- set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, opts->osd_duration,
- "Chapter: %s", chapter_name);
- } else if (step_all > 0)
- mpctx->stop_play = PT_NEXT_ENTRY;
- else
- set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, opts->osd_duration,
- "Chapter: (%d) %s", 0, mp_gtext("unknown"));
- talloc_free(chapter_name);
- return M_PROPERTY_OK;
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
static int mp_property_edition(m_option_t *prop, int action, void *arg,
@@ -372,8 +380,8 @@ static int mp_property_edition(m_option_t *prop, int action, void *arg,
switch (action) {
case M_PROPERTY_GET:
- case M_PROPERTY_PRINT:
- return m_property_int_ro(prop, action, arg, edition);
+ *(int *)arg = edition;
+ return M_PROPERTY_OK;
case M_PROPERTY_SET:
edition = *(int *)arg;
break;
@@ -457,26 +465,22 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg,
return M_PROPERTY_OK;
}
case M_PROPERTY_SET:
- angle = *(int *)arg;
- break;
+ angle = demuxer_set_angle(demuxer, *(int *)arg);
+ if (angle >= 0) {
+ struct sh_video *sh_video = demuxer->video->sh;
+ if (sh_video)
+ resync_video_stream(sh_video);
+
+ struct sh_audio *sh_audio = demuxer->audio->sh;
+ if (sh_audio)
+ resync_audio_stream(sh_audio);
+ }
+ return M_PROPERTY_OK;
case M_PROPERTY_SWITCH:
// NOTE: should cycle
return M_PROPERTY_NOT_IMPLEMENTED;
- default:
- return M_PROPERTY_NOT_IMPLEMENTED;
- }
- angle = demuxer_set_angle(demuxer, angle);
- if (angle >= 0) {
- struct sh_video *sh_video = demuxer->video->sh;
- if (sh_video)
- resync_video_stream(sh_video);
-
- struct sh_audio *sh_audio = demuxer->audio->sh;
- if (sh_audio)
- resync_audio_stream(sh_audio);
}
-
- return M_PROPERTY_OK;
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Demuxer meta data
@@ -495,16 +499,19 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg,
};
switch (action) {
- case M_PROPERTY_GET:
- *(char ***)arg = demuxer->info;
+ case M_PROPERTY_GET: {
+ char **slist = NULL;
+ m_option_copy(prop, &slist, &demuxer->info);
+ *(char ***)arg = slist;
return M_PROPERTY_OK;
+ }
case M_PROPERTY_KEY_ACTION:
ka = arg;
if (!(meta = demux_info_get(demuxer, ka->key)))
return M_PROPERTY_UNKNOWN;
switch (ka->action) {
case M_PROPERTY_GET:
- *(char **)ka->arg = meta;
+ *(char **)ka->arg = talloc_strdup(NULL, meta);
return M_PROPERTY_OK;
case M_PROPERTY_GET_TYPE:
*(const m_option_t **)ka->arg = &key_type;
@@ -527,9 +534,11 @@ static int mp_property_pause(m_option_t *prop, int action, void *arg,
unpause_player(mpctx);
}
return M_PROPERTY_OK;
- default:
- return m_property_flag(prop, action, arg, &mpctx->paused);
+ case M_PROPERTY_GET:
+ *(int *)arg = mpctx->paused;
+ return M_PROPERTY_OK;
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
@@ -545,19 +554,6 @@ static int mp_property_volume(m_option_t *prop, int action, void *arg,
case M_PROPERTY_GET:
mixer_getbothvolume(&mpctx->mixer, arg);
return M_PROPERTY_OK;
- case M_PROPERTY_PRINT: {
- float vol;
- mixer_getbothvolume(&mpctx->mixer, &vol);
- return m_property_float_range(prop, action, arg, &vol);
- }
- case M_PROPERTY_SWITCH:
- case M_PROPERTY_SET:
- break;
- default:
- return M_PROPERTY_NOT_IMPLEMENTED;
- }
-
- switch (action) {
case M_PROPERTY_SET:
mixer_setvolume(&mpctx->mixer, *(float *) arg, *(float *) arg);
return M_PROPERTY_OK;
@@ -583,10 +579,11 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg,
case M_PROPERTY_SET:
mixer_setmute(&mpctx->mixer, *(int *) arg);
return M_PROPERTY_OK;
- default:
- return m_property_flag_ro(prop, action, arg,
- mixer_getmute(&mpctx->mixer));
+ case M_PROPERTY_GET:
+ *(int *)arg = mixer_getmute(&mpctx->mixer);
+ return M_PROPERTY_OK;
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Audio delay (RW)
@@ -599,19 +596,11 @@ static int mp_property_audio_delay(m_option_t *prop, int action,
case M_PROPERTY_PRINT:
*(char **)arg = format_delay(audio_delay);
return M_PROPERTY_OK;
- case M_PROPERTY_SET: {
- int ret;
- float delay = audio_delay;
- ret = m_property_float_range(prop, action, arg, &audio_delay);
- if (ret != M_PROPERTY_OK)
- return ret;
- if (mpctx->sh_audio)
- mpctx->delay -= audio_delay - delay;
- }
+ case M_PROPERTY_SET:
+ mpctx->delay -= audio_delay - *(float *)arg;
return M_PROPERTY_OK;
- default:
- return m_property_float_range(prop, action, arg, &audio_delay);
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Audio codec tag (RO)
@@ -629,8 +618,11 @@ static int mp_property_audio_codec(m_option_t *prop, int action,
{
if (!mpctx->sh_audio || !mpctx->sh_audio->codec)
return M_PROPERTY_UNAVAILABLE;
- return m_property_string_ro(prop, action, arg,
- mpctx->sh_audio->codec->name);
+ if (action == M_PROPERTY_GET) {
+ *(char **)arg = talloc_strdup(NULL, mpctx->sh_audio->codec->name);
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Audio bitrate (RO)
@@ -643,8 +635,11 @@ static int mp_property_audio_bitrate(m_option_t *prop, int action,
case M_PROPERTY_PRINT:
*(char **)arg = format_bitrate(mpctx->sh_audio->i_bps);
return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(int *)arg = mpctx->sh_audio->i_bps;
+ return M_PROPERTY_OK;
}
- return m_property_int_ro(prop, action, arg, mpctx->sh_audio->i_bps);
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Samplerate (RO)
@@ -658,8 +653,11 @@ static int mp_property_samplerate(m_option_t *prop, int action, void *arg,
*(char **)arg = talloc_asprintf(NULL, "%d kHz",
mpctx->sh_audio->samplerate / 1000);
return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(int *)arg = mpctx->sh_audio->samplerate;
+ return M_PROPERTY_OK;
}
- return m_property_int_ro(prop, action, arg, mpctx->sh_audio->samplerate);
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Number of channels (RO)
@@ -682,8 +680,11 @@ static int mp_property_channels(m_option_t *prop, int action, void *arg,
mpctx->sh_audio->channels);
}
return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(int *)arg = mpctx->sh_audio->channels;
+ return M_PROPERTY_OK;
}
- return m_property_int_ro(prop, action, arg, mpctx->sh_audio->channels);
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Balance (RW)
@@ -824,10 +825,8 @@ static int mp_property_program(m_option_t *prop, int action, void *arg,
mp_property_do("audio", M_PROPERTY_SET, &prog.aid, mpctx);
mp_property_do("video", M_PROPERTY_SET, &prog.vid, mpctx);
return M_PROPERTY_OK;
-
- default:
- return M_PROPERTY_NOT_IMPLEMENTED;
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
@@ -839,17 +838,15 @@ static int mp_property_fullscreen(m_option_t *prop, int action, void *arg,
if (!mpctx->video_out)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_SET:
+ if (action == M_PROPERTY_SET) {
if (vo_fs == !!*(int *) arg)
return M_PROPERTY_OK;
if (mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_FULLSCREEN, 0);
mpctx->opts.fullscreen = vo_fs;
return M_PROPERTY_OK;
- default:
- return m_property_flag(prop, action, arg, &vo_fs);
}
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
static int mp_property_deinterlace(m_option_t *prop, int action,
@@ -867,20 +864,16 @@ static int mp_property_deinterlace(m_option_t *prop, int action,
vf->control(vf, VFCTRL_SET_DEINTERLACE, arg);
return M_PROPERTY_OK;
}
- int value = 0;
- vf->control(vf, VFCTRL_GET_DEINTERLACE, &value);
- return m_property_flag_ro(prop, action, arg, value);
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
static int colormatrix_property_helper(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
int r = mp_property_generic_option(prop, action, arg, mpctx);
- switch (action) {
- case M_PROPERTY_SET:
+ if (action == M_PROPERTY_SET) {
if (mpctx->sh_video)
set_video_colorspace(mpctx->sh_video);
- break;
}
return r;
}
@@ -889,8 +882,7 @@ static int mp_property_colormatrix(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
- switch (action) {
- case M_PROPERTY_PRINT: ;
+ if (action == M_PROPERTY_PRINT) {
struct mp_csp_details actual = { .format = -1 };
char *req_csp = mp_csp_names[opts->requested_colorspace];
char *real_csp = NULL;
@@ -916,9 +908,8 @@ static int mp_property_colormatrix(m_option_t *prop, int action, void *arg,
req_csp, real_csp);
*(char **)arg = res;
return M_PROPERTY_OK;
- default:;
- return colormatrix_property_helper(prop, action, arg, mpctx);
}
+ return colormatrix_property_helper(prop, action, arg, mpctx);
}
static int levels_property_helper(int offset, m_option_t *prop, int action,
@@ -929,8 +920,7 @@ static int levels_property_helper(int offset, m_option_t *prop, int action,
bstr0(optname));
int *valptr = (int *)m_option_get_ptr(opt, &mpctx->opts);
- switch (action) {
- case M_PROPERTY_PRINT: ;
+ if (action == M_PROPERTY_PRINT) {
struct mp_csp_details actual = {0};
int actual_level = -1;
char *req_level = m_option_print(opt, valptr);
@@ -956,9 +946,8 @@ static int levels_property_helper(int offset, m_option_t *prop, int action,
talloc_free(real_level);
*(char **)arg = res;
return M_PROPERTY_OK;
- default:;
- return colormatrix_property_helper(prop, action, arg, mpctx);
}
+ return colormatrix_property_helper(prop, action, arg, mpctx);
}
static int mp_property_colormatrix_input_range(m_option_t *prop, int action,
@@ -984,14 +973,10 @@ static int mp_property_panscan(m_option_t *prop, int action, void *arg,
|| vo_control(mpctx->video_out, VOCTRL_GET_PANSCAN, NULL) != VO_TRUE)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_SET:
- vo_panscan = *(float *) arg;
+ int r = mp_property_generic_option(prop, action, arg, mpctx);
+ if (action == M_PROPERTY_SET)
vo_control(mpctx->video_out, VOCTRL_SET_PANSCAN, NULL);
- return M_PROPERTY_OK;
- default:
- return m_property_float_range(prop, action, arg, &vo_panscan);
- }
+ return r;
}
/// Helper to set vo flags.
@@ -1004,16 +989,14 @@ static int mp_property_vo_flag(m_option_t *prop, int action, void *arg,
if (!mpctx->video_out)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_SET:
+ if (action == M_PROPERTY_SET) {
if (*vo_var == !!*(int *) arg)
return M_PROPERTY_OK;
if (mpctx->video_out->config_ok)
vo_control(mpctx->video_out, vo_ctrl, 0);
return M_PROPERTY_OK;
- default:
- return m_property_flag(prop, action, arg, vo_var);
}
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// Window always on top (RW)
@@ -1078,7 +1061,7 @@ static int mp_property_gamma(m_option_t *prop, int action, void *arg,
}
break;
default:
- return M_PROPERTY_NOT_IMPLEMENTED;
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
#ifdef CONFIG_TV
@@ -1097,7 +1080,7 @@ static int mp_property_gamma(m_option_t *prop, int action, void *arg,
static int mp_property_vsync(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return m_property_flag(prop, action, arg, &vo_vsync);
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// Video codec tag (RO)
@@ -1131,8 +1114,11 @@ static int mp_property_video_format(m_option_t *prop, int action,
}
*(char **)arg = meta;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(int *)arg = mpctx->sh_video->format;
+ return M_PROPERTY_OK;
}
- return m_property_int_ro(prop, action, arg, mpctx->sh_video->format);
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
/// Video codec name (RO)
@@ -1141,8 +1127,11 @@ static int mp_property_video_codec(m_option_t *prop, int action,
{
if (!mpctx->sh_video || !mpctx->sh_video->codec)
return M_PROPERTY_UNAVAILABLE;
- return m_property_string_ro(prop, action, arg,
- mpctx->sh_video->codec->name);
+ if (action == M_PROPERTY_GET) {
+ *(char **)arg = talloc_strdup(NULL, mpctx->sh_video->codec->name);
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
@@ -1152,8 +1141,7 @@ static int mp_property_video_bitrate(m_option_t *prop, int action,
{
if (!mpctx->sh_video)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_PRINT:
+ if (action == M_PROPERTY_PRINT) {
*(char **)arg = format_bitrate(mpctx->sh_video->i_bps);
return M_PROPERTY_OK;
}
@@ -1196,17 +1184,17 @@ static int mp_property_aspect(m_option_t *prop, int action, void *arg,
return m_property_float_ro(prop, action, arg, mpctx->sh_video->aspect);
}
-
-/// Text subtitle position (RW)
-static int mp_property_sub_pos(m_option_t *prop, int action, void *arg,
+// For subtitle related properties using the generic option bridge.
+// - Fail as unavailable if no video is active
+// - Trigger OSD state update when property is set
+static int property_sub_helper(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- switch (action) {
- case M_PROPERTY_SET:
+ if (!mpctx->sh_video)
+ return M_PROPERTY_UNAVAILABLE;
+ if (action == M_PROPERTY_SET)
vo_osd_changed(OSDTYPE_SUBTITLE);
- default:
- return m_property_int_range(prop, action, arg, &sub_pos);
- }
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// Selected subtitles (RW)
@@ -1227,7 +1215,7 @@ static int mp_property_sub_delay(m_option_t *prop, int action, void *arg,
*(char **)arg = format_delay(sub_delay);
return M_PROPERTY_OK;
}
- return m_property_float_range(prop, action, arg, &sub_delay);
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// Subtitle visibility (RW)
@@ -1241,48 +1229,18 @@ static int mp_property_sub_visibility(m_option_t *prop, int action,
switch (action) {
case M_PROPERTY_SET:
+ opts->sub_visibility = *(int *)arg;
vo_osd_changed(OSDTYPE_SUBTITLE);
if (vo_spudec)
vo_osd_changed(OSDTYPE_SPU);
- default:
- return m_property_flag(prop, action, arg, &opts->sub_visibility);
- }
-}
-
-#ifdef CONFIG_ASS
-/// Use margins for libass subtitles (RW)
-static int mp_property_ass_use_margins(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
-{
- struct MPOpts *opts = &mpctx->opts;
- if (!mpctx->sh_video)
- return M_PROPERTY_UNAVAILABLE;
-
- switch (action) {
- case M_PROPERTY_SET:
- vo_osd_changed(OSDTYPE_SUBTITLE);
- default:
- return m_property_flag(prop, action, arg, &opts->ass_use_margins);
- }
-}
-
-static int mp_property_ass_vsfilter_aspect_compat(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
-{
- if (!mpctx->sh_video)
- return M_PROPERTY_UNAVAILABLE;
-
- switch (action) {
- case M_PROPERTY_SET:
- vo_osd_changed(OSDTYPE_SUBTITLE);
- default:
- return m_property_flag(prop, action, arg,
- &mpctx->opts.ass_vsfilter_aspect_compat);
+ return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ *(int *)arg = opts->sub_visibility;
+ return M_PROPERTY_OK;
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
-#endif
-
/// Show only forced subtitles (RW)
static int mp_property_sub_forced_only(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
@@ -1290,15 +1248,12 @@ static int mp_property_sub_forced_only(m_option_t *prop, int action,
if (!vo_spudec)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_SET:
- m_property_flag(prop, action, arg, &forced_subs_only);
+ if (action == M_PROPERTY_SET) {
+ forced_subs_only = *(int *)arg;
spudec_set_forced_subs_only(vo_spudec, forced_subs_only);
return M_PROPERTY_OK;
- default:
- return m_property_flag(prop, action, arg, &forced_subs_only);
}
-
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// Subtitle scale (RW)
@@ -1307,20 +1262,19 @@ static int mp_property_sub_scale(m_option_t *prop, int action, void *arg,
{
struct MPOpts *opts = &mpctx->opts;
+ float *pscale = opts->ass_enabled
+ ? &opts->ass_font_scale : &text_font_scale_factor;
+
switch (action) {
case M_PROPERTY_SET:
- if (opts->ass_enabled)
- opts->ass_font_scale = *(float *) arg;
- else
- text_font_scale_factor = *(float *) arg;
+ *pscale = *(float *) arg;
vo_osd_resized();
return M_PROPERTY_OK;
- default:
- if (opts->ass_enabled)
- return m_property_float_ro(prop, action, arg, opts->ass_font_scale);
- else
- return m_property_float_ro(prop, action, arg, text_font_scale_factor);
+ case M_PROPERTY_GET:
+ *(float *)arg = *pscale;
+ return M_PROPERTY_OK;
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
@@ -1352,17 +1306,25 @@ static int mp_property_tv_color(m_option_t *prop, int action, void *arg,
#endif
+// Use option-to-property-bridge. (The property and option have the same names.)
+#define M_OPTION_PROPERTY(name) \
+ {(name), mp_property_generic_option, &m_option_type_choice, 0, 0, 0, (name)}
+
+// OPTION_PROPERTY(), but with a custom property handler. The custom handler
+// must let unknown operations fall back to mp_property_generic_option().
+#define M_OPTION_PROPERTY_CUSTOM(name, handler) \
+ {(name), (handler), &m_option_type_choice, 0, 0, 0, (name)}
+#define M_OPTION_PROPERTY_CUSTOM_(name, handler, ...) \
+ {(name), (handler), &m_option_type_choice, 0, 0, 0, (name), __VA_ARGS__}
+
/// All properties available in MPlayer.
/** \ingroup Properties
*/
static const m_option_t mp_properties[] = {
// General
- { "osd-level", mp_property_generic_option, &m_option_type_choice,
- 0, 0, 0, "osd-level" },
- { "loop", mp_property_generic_option, &m_option_type_choice,
- 0, 0, 0, "loop" },
- { "speed", mp_property_playback_speed, CONF_TYPE_FLOAT,
- M_OPT_RANGE, 0.01, 100.0, NULL },
+ M_OPTION_PROPERTY("osd-level"),
+ M_OPTION_PROPERTY("loop"),
+ M_OPTION_PROPERTY_CUSTOM("speed", mp_property_playback_speed),
{ "filename", mp_property_filename, CONF_TYPE_STRING,
0, 0, 0, NULL },
{ "path", mp_property_path, CONF_TYPE_STRING,
@@ -1400,18 +1362,15 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "pause", mp_property_pause, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
- { "pts-association-mode", mp_property_generic_option, &m_option_type_choice,
- 0, 0, 0, "pts-association-mode" },
- { "hr-seek", mp_property_generic_option, &m_option_type_choice,
- 0, 0, 0, "hr-seek" },
+ M_OPTION_PROPERTY("pts-association-mode"),
+ M_OPTION_PROPERTY("hr-seek"),
// 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 },
- { "audio-delay", mp_property_audio_delay, CONF_TYPE_FLOAT,
- M_OPT_RANGE, -100, 100, NULL },
+ M_OPTION_PROPERTY_CUSTOM("audio-delay", mp_property_audio_delay),
{ "audio-format", mp_property_audio_format, CONF_TYPE_INT,
0, 0, 0, NULL },
{ "audio-codec", mp_property_audio_codec, CONF_TYPE_STRING,
@@ -1428,38 +1387,30 @@ static const m_option_t mp_properties[] = {
M_OPT_RANGE, -1, 1, NULL },
// Video
- { "fullscreen", mp_property_fullscreen, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
+ M_OPTION_PROPERTY_CUSTOM("fullscreen", mp_property_fullscreen),
{ "deinterlace", mp_property_deinterlace, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
- { "colormatrix", mp_property_colormatrix, &m_option_type_choice,
- 0, 0, 0, "colormatrix" },
- { "colormatrix-input-range", mp_property_colormatrix_input_range, &m_option_type_choice,
- 0, 0, 0, "colormatrix-input-range" },
- { "colormatrix-output-range", mp_property_colormatrix_output_range, &m_option_type_choice,
- 0, 0, 0, "colormatrix-output-range" },
- { "ontop", mp_property_ontop, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
- { "rootwin", mp_property_rootwin, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
- { "border", mp_property_border, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
- { "framedrop", mp_property_framedrop, &m_option_type_choice,
- 0, 0, 0, "framedrop" },
- { "gamma", mp_property_gamma, CONF_TYPE_INT,
- M_OPT_RANGE, -100, 100, .offset = offsetof(struct MPOpts, vo_gamma_gamma)},
- { "brightness", mp_property_gamma, CONF_TYPE_INT,
- M_OPT_RANGE, -100, 100, .offset = offsetof(struct MPOpts, vo_gamma_brightness) },
- { "contrast", mp_property_gamma, CONF_TYPE_INT,
- M_OPT_RANGE, -100, 100, .offset = offsetof(struct MPOpts, vo_gamma_contrast) },
- { "saturation", mp_property_gamma, CONF_TYPE_INT,
- M_OPT_RANGE, -100, 100, .offset = offsetof(struct MPOpts, vo_gamma_saturation) },
- { "hue", mp_property_gamma, CONF_TYPE_INT,
- M_OPT_RANGE, -100, 100, .offset = offsetof(struct MPOpts, vo_gamma_hue) },
- { "panscan", mp_property_panscan, CONF_TYPE_FLOAT,
- M_OPT_RANGE, 0, 1, NULL },
- { "vsync", mp_property_vsync, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
+ M_OPTION_PROPERTY_CUSTOM("colormatrix", mp_property_colormatrix),
+ M_OPTION_PROPERTY_CUSTOM("colormatrix-input-range",
+ mp_property_colormatrix_input_range),
+ M_OPTION_PROPERTY_CUSTOM("colormatrix-output-range",
+ mp_property_colormatrix_output_range),
+ M_OPTION_PROPERTY_CUSTOM("ontop", mp_property_ontop),
+ M_OPTION_PROPERTY_CUSTOM("rootwin", mp_property_rootwin),
+ M_OPTION_PROPERTY_CUSTOM("border", mp_property_border),
+ M_OPTION_PROPERTY_CUSTOM("framedrop", mp_property_framedrop),
+ M_OPTION_PROPERTY_CUSTOM_("gamma", mp_property_gamma,
+ .offset = offsetof(struct MPOpts, vo_gamma_gamma)),
+ M_OPTION_PROPERTY_CUSTOM_("brightness", mp_property_gamma,
+ .offset = offsetof(struct MPOpts, vo_gamma_brightness)),
+ M_OPTION_PROPERTY_CUSTOM_("contrast", mp_property_gamma,
+ .offset = offsetof(struct MPOpts, vo_gamma_contrast)),
+ M_OPTION_PROPERTY_CUSTOM_("saturation", mp_property_gamma,
+ .offset = offsetof(struct MPOpts, vo_gamma_saturation)),
+ M_OPTION_PROPERTY_CUSTOM_("hue", mp_property_gamma,
+ .offset = offsetof(struct MPOpts, vo_gamma_hue)),
+ M_OPTION_PROPERTY_CUSTOM("panscan", mp_property_panscan),
+ M_OPTION_PROPERTY_CUSTOM_("vsync", mp_property_vsync),
{ "video-format", mp_property_video_format, CONF_TYPE_INT,
0, 0, 0, NULL },
{ "video-codec", mp_property_video_codec, CONF_TYPE_STRING,
@@ -1482,21 +1433,16 @@ static const m_option_t mp_properties[] = {
// Subs
{ "sub", mp_property_sub, CONF_TYPE_INT,
M_OPT_MIN, -1, 0, NULL },
- { "sub-delay", mp_property_sub_delay, CONF_TYPE_FLOAT,
- 0, 0, 0, NULL },
- { "sub-pos", mp_property_sub_pos, CONF_TYPE_INT,
- M_OPT_RANGE, 0, 100, NULL },
+ M_OPTION_PROPERTY_CUSTOM("sub-delay", mp_property_sub_delay),
+ M_OPTION_PROPERTY_CUSTOM("sub-pos", property_sub_helper),
{ "sub-visibility", mp_property_sub_visibility, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
- { "sub-forced-only", mp_property_sub_forced_only, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
+ M_OPTION_PROPERTY_CUSTOM("sub-forced-only", mp_property_sub_forced_only),
{ "sub-scale", mp_property_sub_scale, CONF_TYPE_FLOAT,
M_OPT_RANGE, 0, 100, NULL },
#ifdef CONFIG_ASS
- { "ass-use-margins", mp_property_ass_use_margins, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
- { "ass-vsfilter-aspect-compat", mp_property_ass_vsfilter_aspect_compat,
- CONF_TYPE_FLAG, M_OPT_RANGE, 0, 1, NULL },
+ M_OPTION_PROPERTY_CUSTOM("ass-use-margins", property_sub_helper),
+ M_OPTION_PROPERTY_CUSTOM("ass-vsfilter-aspect-compat", property_sub_helper),
#endif
#ifdef CONFIG_TV