summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/changes.rst4
-rw-r--r--DOCS/man/en/options.rst12
-rw-r--r--cfg-mplayer.h11
-rw-r--r--command.c460
-rw-r--r--m_config.c4
-rw-r--r--m_config.h3
-rw-r--r--m_property.c71
-rw-r--r--m_property.h41
8 files changed, 242 insertions, 364 deletions
diff --git a/DOCS/man/en/changes.rst b/DOCS/man/en/changes.rst
index ec08c7eac2..11b7242d1a 100644
--- a/DOCS/man/en/changes.rst
+++ b/DOCS/man/en/changes.rst
@@ -97,6 +97,10 @@ Command line switches
-loop 0 --loop=inf
-hardframedrop --framedrop=hard
-osdlevel --osd-level
+ -delay --audio-delay
+ -subdelay --sub-delay
+ -subpos --sub-pos
+ -forcedsubsonly --sub-forced-only
=================================== ===================================
input.conf and slave commands
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index da7ed79e03..342626d5d2 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -472,7 +472,7 @@
will stay hidden. Supported by video output drivers which use X11 or
OS X Cocoa.
---delay=<sec>
+--audio-delay=<sec>
audio delay in seconds (positive or negative float value). Negative values
delay the audio, and positive values delay the video.
@@ -624,7 +624,7 @@
there is a change in video parameters, video stream or file. This used to
be the default behavior. Currently only affects X11 VOs.
---forcedsubsonly
+--sub-forced-only
Display only forced subtitles for the DVD subtitle stream selected by e.g.
``--slang``.
@@ -659,6 +659,7 @@
Specifies the character set that will be passed to FriBiDi when decoding
non-UTF-8 subtitles (default: ISO8859-8).
+--fullscreen
--fs
Fullscreen playback (centers movie, and paints black bands around it).
@@ -1312,9 +1313,6 @@
controls how much of the image is cropped. May not work with all video
output drivers.
- *NOTE*: Values between -1 and 0 are allowed as well, but highly
- experimental and may crash or worse. Use at your own risk!
-
--panscanrange=<-19.0-99.0>
(experimental)
Change the range of the pan-and-scan functionality (default: 1). Positive
@@ -1894,7 +1892,7 @@
- ``--subcp=enca:pl:cp1250`` guess the encoding for Polish, fall back on
cp1250.
---subdelay=<sec>
+--sub-delay=<sec>
Delays subtitles by <sec> seconds. Can be negative.
--subfile=<filename>
@@ -1941,7 +1939,7 @@
*NOTE*: <rate> > movie fps speeds the subtitles up for frame-based
subtitle files and slows them down for time-based ones.
---subpos=<0-100>
+--sub-pos=<0-100>
Specify the position of subtitles on the screen. The value is the vertical
position of the subtitle in % of the screen height.
Can be useful with ``--vf=expand``.
diff --git a/cfg-mplayer.h b/cfg-mplayer.h
index dd90df21d6..db99b1da28 100644
--- a/cfg-mplayer.h
+++ b/cfg-mplayer.h
@@ -459,7 +459,7 @@ const m_option_t common_opts[] = {
OPT_FLOATRANGE("speed", playback_speed, 0, 0.01, 100.0),
// set a-v distance
- {"delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL},
+ {"audio-delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL},
// ignore header-specified delay (dwStart)
{"ignore-start", &ignore_start, CONF_TYPE_FLAG, 0, 0, 1, NULL},
@@ -512,12 +512,12 @@ const m_option_t common_opts[] = {
OPT_STRINGLIST("sub", sub_name, 0),
OPT_PATHLIST("sub-paths", sub_paths, 0),
{"subcp", &sub_cp, CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"subdelay", &sub_delay, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
+ {"sub-delay", &sub_delay, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
{"subfps", &sub_fps, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
OPT_MAKE_FLAGS("autosub", sub_auto, 0),
{"unicode", &sub_unicode, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"utf8", &sub_utf8, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- {"forcedsubsonly", &forced_subs_only, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+ {"sub-forced-only", &forced_subs_only, CONF_TYPE_FLAG, 0, 0, 1, NULL},
// specify IFO file for VOBSUB subtitle
{"ifo", &spudec_ifo, CONF_TYPE_STRING, 0, 0, 0, NULL},
// enable Closed Captioning display
@@ -529,7 +529,7 @@ const m_option_t common_opts[] = {
{"font", &font_name, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"subfont", &sub_font_name, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"ffactor", &font_factor, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 10.0, NULL},
- {"subpos", &sub_pos, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+ {"sub-pos", &sub_pos, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
{"subwidth", &sub_width_p, CONF_TYPE_INT, CONF_RANGE, 10, 100, NULL},
{"spualign", &spu_alignment, CONF_TYPE_INT, CONF_RANGE, -1, 2, NULL},
{"spuaa", &spu_aamode, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL},
@@ -618,6 +618,7 @@ const m_option_t mplayer_opts[]={
// video mode switching: (x11,xv,dga)
OPT_MAKE_FLAGS("vm", vidmode, 0),
// start in fullscreen mode:
+ OPT_MAKE_FLAGS("fullscreen", fullscreen, CONF_GLOBAL),
OPT_MAKE_FLAGS("fs", fullscreen, CONF_GLOBAL),
// set fullscreen switch method (workaround for buggy WMs)
{"fsmode-dontuse", &vo_fsmode, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL},
@@ -628,7 +629,7 @@ const m_option_t mplayer_opts[]={
{"double", &vo_doublebuffering, CONF_TYPE_FLAG, 0, 0, 1, NULL},
// wait for v-sync (gl)
{"vsync", &vo_vsync, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- {"panscan", &vo_panscan, CONF_TYPE_FLOAT, CONF_RANGE, -1.0, 1.0, NULL},
+ {"panscan", &vo_panscan, CONF_TYPE_FLOAT, CONF_RANGE, 0, 1.0, NULL},
OPT_FLOATRANGE("panscanrange", vo_panscanrange, 0, -19.0, 99.0),
OPT_CHOICE("colormatrix", requested_colorspace, 0,
({"auto", MP_CSP_AUTO},
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_opt