diff options
author | wm4 <wm4@nowhere> | 2012-11-05 17:02:04 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2012-11-12 20:06:14 +0100 |
commit | d4bdd0473d6f43132257c9fb3848d829755167a3 (patch) | |
tree | 8021c2f7da1841393c8c832105e20cd527826d6c /command.c | |
parent | bd48deba77bd5582c5829d6fe73a7d2571088aba (diff) | |
download | mpv-d4bdd0473d6f43132257c9fb3848d829755167a3.tar.bz2 mpv-d4bdd0473d6f43132257c9fb3848d829755167a3.tar.xz |
Rename directories, move files (step 1 of 2) (does not compile)
Tis drops the silly lib prefixes, and attempts to organize the tree in
a more logical way. Make the top-level directory less cluttered as
well.
Renames the following directories:
libaf -> audio/filter
libao2 -> audio/out
libvo -> video/out
libmpdemux -> demux
Split libmpcodecs:
vf* -> video/filter
vd*, dec_video.* -> video/decode
mp_image*, img_format*, ... -> video/
ad*, dec_audio.* -> audio/decode
libaf/format.* is moved to audio/ - this is similar to how mp_image.*
is located in video/.
Move most top-level .c/.h files to core. (talloc.c/.h is left on top-
level, because it's external.) Park some of the more annoying files
in compat/. Some of these are relicts from the time mplayer used
ffmpeg internals.
sub/ is not split, because it's too much of a mess (subtitle code is
mixed with OSD display and rendering).
Maybe the organization of core is not ideal: it mixes playback core
(like mplayer.c) and utility helpers (like bstr.c/h). Should the need
arise, the playback core will be moved somewhere else, while core
contains all helper and common code.
Diffstat (limited to 'command.c')
-rw-r--r-- | command.c | 2323 |
1 files changed, 0 insertions, 2323 deletions
diff --git a/command.c b/command.c deleted file mode 100644 index 14f24ac50e..0000000000 --- a/command.c +++ /dev/null @@ -1,2323 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdlib.h> -#include <inttypes.h> -#include <unistd.h> -#include <string.h> -#include <stdbool.h> -#include <assert.h> - -#include "config.h" -#include "talloc.h" -#include "command.h" -#include "input/input.h" -#include "stream/stream.h" -#include "libmpdemux/demuxer.h" -#include "libmpdemux/stheader.h" -#include "codec-cfg.h" -#include "mplayer.h" -#include "playlist.h" -#include "playlist_parser.h" -#include "sub/sub.h" -#include "sub/dec_sub.h" -#include "m_option.h" -#include "m_property.h" -#include "m_config.h" -#include "libmpcodecs/vf.h" -#include "libmpcodecs/vd.h" -#include "mp_osd.h" -#include "libvo/video_out.h" -#include "libvo/csputils.h" -#include "playlist.h" -#include "libao2/audio_out.h" -#include "mpcommon.h" -#include "mixer.h" -#include "libmpcodecs/dec_video.h" -#include "libmpcodecs/dec_audio.h" -#include "osdep/strsep.h" -#include "sub/vobsub.h" -#include "sub/spudec.h" -#include "path.h" -#include "sub/ass_mp.h" -#include "stream/tv.h" -#include "stream/stream_radio.h" -#include "stream/pvr.h" -#ifdef CONFIG_DVBIN -#include "stream/dvbin.h" -#endif -#ifdef CONFIG_DVDREAD -#include "stream/stream_dvd.h" -#endif -#include "m_struct.h" -#include "screenshot.h" - -#include "mp_core.h" -#include "mp_fifo.h" -#include "libavutil/avstring.h" - -static char *format_bitrate(int rate) -{ - return talloc_asprintf(NULL, "%d kbps", rate * 8 / 1000); -} - -static char *format_delay(double time) -{ - return talloc_asprintf(NULL, "%d ms", ROUND(time * 1000)); -} - -static void rescale_input_coordinates(struct MPContext *mpctx, int ix, int iy, - double *dx, double *dy) -{ - struct MPOpts *opts = &mpctx->opts; - struct vo *vo = mpctx->video_out; - //remove the borders, if any, and rescale to the range [0,1],[0,1] - if (vo_fs) { //we are in full-screen mode - if (opts->vo_screenwidth > vo->dwidth) - // there are borders along the x axis - ix -= (opts->vo_screenwidth - vo->dwidth) / 2; - if (opts->vo_screenheight > vo->dheight) - // there are borders along the y axis (usual way) - iy -= (opts->vo_screenheight - vo->dheight) / 2; - - if (ix < 0 || ix > vo->dwidth) { - *dx = *dy = -1.0; - return; - } //we are on one of the borders - if (iy < 0 || iy > vo->dheight) { - *dx = *dy = -1.0; - return; - } //we are on one of the borders - } - - *dx = (double) ix / (double) vo->dwidth; - *dy = (double) iy / (double) vo->dheight; - - mp_msg(MSGT_CPLAYER, MSGL_V, - "\r\nrescaled coordinates: %.3f, %.3f, screen (%d x %d), vodisplay: (%d, %d), fullscreen: %d\r\n", - *dx, *dy, opts->vo_screenwidth, opts->vo_screenheight, vo->dwidth, - 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; - struct m_config_option *opt = m_config_get_co(mpctx->mconfig, - bstr0(optname)); - void *valptr = opt->data; - - switch (action) { - case M_PROPERTY_GET_TYPE: - *(struct m_option *)arg = *(opt->opt); - return M_PROPERTY_OK; - case M_PROPERTY_GET: - m_option_copy(opt->opt, arg, valptr); - return M_PROPERTY_OK; - case M_PROPERTY_SET: - m_option_copy(opt->opt, valptr, arg); - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Playback speed (RW) -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: { - 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; - } - case M_PROPERTY_PRINT: - *(char **)arg = talloc_asprintf(NULL, "x %6.2f", orig_speed); - return M_PROPERTY_OK; - } - 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) -{ - if (!mpctx->filename) - return M_PROPERTY_UNAVAILABLE; - return m_property_strdup_ro(prop, action, arg, mpctx->filename); -} - -static int mp_property_filename(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - if (!mpctx->filename) - return M_PROPERTY_UNAVAILABLE; - char *f = (char *)mp_basename(mpctx->filename); - return m_property_strdup_ro(prop, action, arg, (*f) ? f : mpctx->filename); -} - -static int mp_property_media_title(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - char *name = NULL; - if (mpctx->resolve_result) - name = mpctx->resolve_result->title; - if (name && name[0]) { - return m_property_strdup_ro(prop, action, arg, name); - } else { - return mp_property_filename(prop, action, arg, mpctx); - } -} - -static int mp_property_stream_path(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct stream *stream = mpctx->stream; - if (!stream || !stream->url) - return M_PROPERTY_UNAVAILABLE; - return m_property_strdup_ro(prop, action, arg, stream->url); -} - -/// Demuxer name (RO) -static int mp_property_demuxer(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - return m_property_strdup_ro(prop, action, arg, demuxer->desc->name); -} - -/// Position in the stream (RW) -static int mp_property_stream_pos(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct stream *stream = mpctx->stream; - if (!stream) - return M_PROPERTY_UNAVAILABLE; - switch (action) { - case M_PROPERTY_GET: - *(int64_t *) arg = stream_tell(stream); - return M_PROPERTY_OK; - case M_PROPERTY_SET: - stream_seek(stream, *(int64_t *) arg); - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Stream start offset (RO) -static int mp_property_stream_start(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - struct stream *stream = mpctx->stream; - if (!stream) - return M_PROPERTY_UNAVAILABLE; - return m_property_int64_ro(prop, action, arg, stream->start_pos); -} - -/// Stream end offset (RO) -static int mp_property_stream_end(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct stream *stream = mpctx->stream; - if (!stream) - return M_PROPERTY_UNAVAILABLE; - return m_property_int64_ro(prop, action, arg, stream->end_pos); -} - -/// Stream length (RO) -static int mp_property_stream_length(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - struct stream *stream = mpctx->stream; - if (!stream) - return M_PROPERTY_UNAVAILABLE; - return m_property_int64_ro(prop, action, arg, - stream->end_pos - stream->start_pos); -} - -/// Current stream position in seconds (RO) -static int mp_property_stream_time_pos(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - struct demuxer *demuxer = mpctx->demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - double pts = demuxer->stream_pts; - if (pts == MP_NOPTS_VALUE) - return M_PROPERTY_UNAVAILABLE; - - return m_property_double_ro(prop, action, arg, pts); -} - - -/// Media length in seconds (RO) -static int mp_property_length(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - double len; - - if (!(int) (len = get_time_length(mpctx))) - return M_PROPERTY_UNAVAILABLE; - - return m_property_double_ro(prop, action, arg, len); -} - -/// Current position in percent (RW) -static int mp_property_percent_pos(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!mpctx->num_sources) - return M_PROPERTY_UNAVAILABLE; - - switch (action) { - 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; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Current position in seconds (RW) -static int mp_property_time_pos(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!mpctx->num_sources) - return M_PROPERTY_UNAVAILABLE; - - switch (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_NOT_IMPLEMENTED; -} - -/// Current chapter (RW) -static int mp_property_chapter(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - int chapter = get_current_chapter(mpctx); - if (chapter < -1) - return M_PROPERTY_UNAVAILABLE; - - switch (action) { - case M_PROPERTY_GET: - *(int *) arg = chapter; - return M_PROPERTY_OK; - case M_PROPERTY_PRINT: { - char *chapter_name = chapter_display_name(mpctx, chapter); - if (!chapter_name) - return M_PROPERTY_UNAVAILABLE; - *(char **) arg = chapter_name; - return M_PROPERTY_OK; - } - case M_PROPERTY_SET: ; - int step_all = *(int *)arg - chapter; - chapter += step_all; - 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); - } else if (step_all > 0) - mpctx->stop_play = PT_NEXT_ENTRY; - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -static int mp_property_edition(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct MPOpts *opts = &mpctx->opts; - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - if (demuxer->num_editions <= 0) - return M_PROPERTY_UNAVAILABLE; - - int edition = demuxer->edition; - - switch (action) { - case M_PROPERTY_GET: - *(int *)arg = edition; - return M_PROPERTY_OK; - case M_PROPERTY_SET: { - edition = *(int *)arg; - if (edition != demuxer->edition) { - opts->edition_id = edition; - mpctx->stop_play = PT_RESTART; - } - return M_PROPERTY_OK; - } - case M_PROPERTY_GET_TYPE: { - struct m_option opt = { - .name = prop->name, - .type = CONF_TYPE_INT, - .flags = CONF_RANGE, - .min = 0, - .max = demuxer->num_editions - 1, - }; - *(struct m_option *)arg = opt; - return M_PROPERTY_OK; - } - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Number of titles in file -static int mp_property_titles(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - int num_titles = 0; - stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_TITLES, &num_titles); - return m_property_int_ro(prop, action, arg, num_titles); -} - -/// Number of chapters in file -static int mp_property_chapters(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - if (!mpctx->num_sources) - return M_PROPERTY_UNAVAILABLE; - int count = get_chapter_count(mpctx); - return m_property_int_ro(prop, action, arg, count); -} - -static int mp_property_editions(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - if (demuxer->num_editions <= 0) - return M_PROPERTY_UNAVAILABLE; - return m_property_int_ro(prop, action, arg, demuxer->num_editions); -} - -/// Current dvd angle (RW) -static int mp_property_angle(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct demuxer *demuxer = mpctx->master_demuxer; - int angle = -1; - int angles; - - if (demuxer) - angle = demuxer_get_current_angle(demuxer); - if (angle < 0) - return M_PROPERTY_UNAVAILABLE; - angles = demuxer_angles_count(demuxer); - if (angles <= 1) - return M_PROPERTY_UNAVAILABLE; - - switch (action) { - case M_PROPERTY_GET: - *(int *) arg = angle; - return M_PROPERTY_OK; - case M_PROPERTY_PRINT: { - *(char **) arg = talloc_asprintf(NULL, "%d/%d", angle, angles); - return M_PROPERTY_OK; - } - case M_PROPERTY_SET: - 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; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Demuxer meta data -static int mp_property_metadata(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - - static const m_option_t key_type = - { - "metadata", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL - }; - - switch (action) { - 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: { - struct m_property_action_arg *ka = arg; - char *meta = demux_info_get(demuxer, ka->key); - if (!meta) - return M_PROPERTY_UNKNOWN; - switch (ka->action) { - case M_PROPERTY_GET: - *(char **)ka->arg = talloc_strdup(NULL, meta); - return M_PROPERTY_OK; - case M_PROPERTY_GET_TYPE: - *(struct m_option *)ka->arg = key_type; - return M_PROPERTY_OK; - } - } - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -static int mp_property_pause(m_option_t *prop, int action, void *arg, - void *ctx) -{ - MPContext *mpctx = ctx; - - switch (action) { - case M_PROPERTY_SET: - if (*(int *)arg) { - pause_player(mpctx); - } else { - unpause_player(mpctx); - } - return M_PROPERTY_OK; - case M_PROPERTY_GET: - *(int *)arg = mpctx->paused; - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - - -/// Volume (RW) -static int mp_property_volume(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - - switch (action) { - case M_PROPERTY_GET: - mixer_getbothvolume(&mpctx->mixer, arg); - return M_PROPERTY_OK; - case M_PROPERTY_SET: - mixer_setvolume(&mpctx->mixer, *(float *) arg, *(float *) arg); - return M_PROPERTY_OK; - case M_PROPERTY_SWITCH: { - struct m_property_switch_arg *sarg = arg; - if (sarg->inc <= 0) - mixer_decvolume(&mpctx->mixer); - else - mixer_incvolume(&mpctx->mixer); - return M_PROPERTY_OK; - } - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Mute (RW) -static int mp_property_mute(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - - switch (action) { - case M_PROPERTY_SET: - mixer_setmute(&mpctx->mixer, *(int *) arg); - return M_PROPERTY_OK; - case M_PROPERTY_GET: - *(int *)arg = mixer_getmute(&mpctx->mixer); - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -/// Audio delay (RW) -static int mp_property_audio_delay(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!(mpctx->sh_audio && mpctx->sh_video)) - return M_PROPERTY_UNAVAILABLE; - float delay = audio_delay; - switch (action) { - case M_PROPERTY_PRINT: - *(char **)arg = format_delay(delay); - return M_PROPERTY_OK; - case M_PROPERTY_SET: - audio_delay = *(float *)arg; - mpctx->delay -= audio_delay - delay; - return M_PROPERTY_OK; - } - return mp_property_generic_option(prop, action, arg, mpctx); -} - -/// Audio codec tag (RO) -static int mp_property_audio_format(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - return m_property_int_ro(prop, action, arg, mpctx->sh_audio->format); -} - -/// Audio codec name (RO) -static int mp_property_audio_codec(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!mpctx->sh_audio || !mpctx->sh_audio->codec) - return M_PROPERTY_UNAVAILABLE; - 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) -static int mp_property_audio_bitrate(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - switch (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_NOT_IMPLEMENTED; -} - -/// Samplerate (RO) -static int mp_property_samplerate(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - switch (action) { - case M_PROPERTY_PRINT: - *(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_NOT_IMPLEMENTED; -} - -/// Number of channels (RO) -static int mp_property_channels(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - if (!mpctx->sh_audio) - return M_PROPERTY_UNAVAILABLE; - switch (action) { - case M_PROPERTY_PRINT: - switch (mpctx->sh_audio->channels) { - case 1: - *(char **) arg = talloc_strdup(NULL, "mono"); - break; - case 2: - *(char **) arg = talloc_strdup(NULL, "stereo"); - break; - default: - *(char **) arg = talloc_asprintf(NULL, "%d channels", - 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_NOT_IMPLEMENTED; -} - -/// Balance (RW) -static int mp_property_balance(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - float bal; - - switch (action) { - case M_PROPERTY_GET: - mixer_getbalance(&mpctx->mixer, arg); - return M_PROPERTY_OK; - case M_PROPERTY_PRINT: { - char **str = arg; - mixer_getbalance(&mpctx->mixer, &bal); - if (bal == 0.f) - *str = talloc_strdup(NULL, "center"); - else if (bal == -1.f) - *str = talloc_strdup(NULL, "left only"); - else if (bal == 1.f) - *str = talloc_strdup(NULL, "right only"); - else { - unsigned right = (bal + 1.f) / 2.f * 100.f; - *str = talloc_asprintf(NULL, "left %d%%, right %d%%", - 100 - right, right); - } - return M_PROPERTY_OK; - } - case M_PROPERTY_SET: - mixer_setbalance(&mpctx->mixer, *(float *)arg); - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - -static struct track* track_next(struct MPContext *mpctx, enum stream_type type, - int direction, struct track *track) -{ - assert(direction == -1 || direction == +1); - struct track *prev = NULL, *next = NULL; - bool seen = track == NULL; - for (int n = 0; n < mpctx->num_tracks; n++) { - struct track *cur = mpctx->tracks[n]; - if (cur->type == type) { - if (cur == track) { - seen = true; - } else { - if (seen && !next) { - next = cur; - } else if (!seen || !track) { - prev = cur; - } - } - } - } - return direction > 0 ? next : prev; -} - -static int property_switch_track(m_option_t *prop, int action, void *arg, - MPContext *mpctx, enum stream_type type) -{ - if (!mpctx->num_sources) - return M_PROPERTY_UNAVAILABLE; - struct track *track = mpctx->current_track[type]; - - switch (action) { - case M_PROPERTY_GET: - *(int *) arg = track ? track->user_tid : -1; - return M_PROPERTY_OK; - case M_PROPERTY_PRINT: - if (!track) - *(char **) arg = talloc_strdup(NULL, mp_gtext("disabled")); - else { - char *lang = track->lang; - if (!lang) - lang = mp_gtext("unknown"); - - if (track->title) - *(char **)arg = talloc_asprintf(NULL, "(%d) %s (\"%s\")", - track->user_tid, lang, track->title); - else - *(char **)arg = talloc_asprintf(NULL, "(%d) %s", - track->user_tid, lang); - } - return M_PROPERTY_OK; - - case M_PROPERTY_SWITCH: { - struct m_property_switch_arg *sarg = arg; - mp_switch_track(mpctx, type, - track_next(mpctx, type, sarg->inc >= 0 ? +1 : -1, track)); - return M_PROPERTY_OK; - } - case M_PROPERTY_SET: - mp_switch_track(mpctx, type, mp_track_by_tid(mpctx, type, *(int *)arg)); - return M_PROPERTY_OK; - default: - return M_PROPERTY_NOT_IMPLEMENTED; - } -} - -/// Selected audio id (RW) -static int mp_property_audio(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - return property_switch_track(prop, action, arg, mpctx, STREAM_AUDIO); -} - -/// Selected video id (RW) -static int mp_property_video(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - return property_switch_track(prop, action, arg, mpctx, STREAM_VIDEO); -} - -static struct track *find_track_by_demuxer_id(MPContext *mpctx, - enum stream_type type, - int demuxer_id) -{ - for (int n = 0; n < mpctx->num_tracks; n++) { - struct track *track = mpctx->tracks[n]; - if (track->type == type && track->demuxer_id == demuxer_id) - return track; - } - return NULL; -} - -static int mp_property_program(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - demux_program_t prog; - - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - - switch (action) { - case M_PROPERTY_SWITCH: - case M_PROPERTY_SET: - if (action == M_PROPERTY_SET && arg) - prog.progid = *((int *) arg); - else - prog.progid = -1; - if (demux_control(demuxer, DEMUXER_CTRL_IDENTIFY_PROGRAM, &prog) == - DEMUXER_CTRL_NOTIMPL) - return M_PROPERTY_ERROR; - - if (prog.aid < 0 && prog.vid < 0) { - mp_msg(MSGT_CPLAYER, MSGL_ERR, - "Selected program contains no audio or video streams!\n"); - return M_PROPERTY_ERROR; - } - mp_switch_track(mpctx, STREAM_AUDIO, - find_track_by_demuxer_id(mpctx, STREAM_AUDIO, prog.aid)); - mp_switch_track(mpctx, STREAM_VIDEO, - find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.vid)); - return M_PROPERTY_OK; - } - return M_PROPERTY_NOT_IMPLEMENTED; -} - - -/// Fullscreen state (RW) -static int mp_property_fullscreen(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - - if (!mpctx->video_out) - return M_PROPERTY_UNAVAILABLE; - - 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; - } - return mp_property_generic_option(prop, action, arg, mpctx); -} - -static int mp_property_deinterlace(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (!mpctx->sh_video || !mpctx->sh_video->vfilter) - return M_PROPERTY_UNAVAILABLE; - vf_instance_t *vf = mpctx->sh_video->vfilter; - int enabled = 0; - if (vf->control(vf, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK) - return M_PROPERTY_UNAVAILABLE; - switch (action) { - case M_PROPERTY_GET: - *(int *)arg = !!enabled; - return M_PROPERTY_OK; - case M_PROPERTY_SET: - vf->control(vf, VFCTRL_SET_DEINTERLACE, arg); - return M_PROPERTY_OK; - } - 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); - if (action == M_PROPERTY_SET) { - if (mpctx->sh_video) - set_video_colorspace(mpctx->sh_video); - } - return r; -} - -static int mp_property_colormatrix(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - if (action != M_PROPERTY_PRINT) - return colormatrix_property_helper(prop, action, arg, mpctx); - - struct MPOpts *opts = &mpctx->opts; - struct mp_csp_details actual = { .format = -1 }; - char *req_csp = mp_csp_names[opts->requested_colorspace]; - char *real_csp = NULL; - if (mpctx->sh_video) { - struct vf_instance *vf = mpctx->sh_video->vfilter; - if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, &actual) == true) { - real_csp = mp_csp_names[actual.format]; - } else { - real_csp = "Unknown"; - } - } - char *res; - if (opts->requested_colorspace == MP_CSP_AUTO && real_csp) { - // Caveat: doesn't handle the case when the autodetected colorspace - // is different from the actual colorspace as used by the - // VO - the OSD will display the VO colorspace without - // indication that it doesn't match the requested colorspace. - res = talloc_asprintf(NULL, "Auto (%s)", real_csp); - } else if (opts->requested_colorspace == actual.format || !real_csp) { - res = talloc_strdup(NULL, req_csp); - } else - res = talloc_asprintf(NULL, mp_gtext("%s, but %s used"), - req_csp, real_csp); - *(char **)arg = res; - return M_PROPERTY_OK; -} - -static int levels_property_helper(int offset, m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - if (action != M_PROPERTY_PRINT) - return colormatrix_property_helper(prop, action, arg, mpctx); - - struct m_option opt = {0}; - mp_property_generic_option(prop, M_PROPERTY_GET_TYPE, &opt, mpctx); - assert(opt.type); - - int requested = 0; - mp_property_generic_option(prop, M_PROPERTY_GET, &requested, mpctx); - - struct mp_csp_details actual = {0}; - int actual_level = -1; - char *req_level = m_option_print(&opt, &requested); - char *real_level = NULL; - if (mpctx->sh_video) { - struct vf_instance *vf = mpctx->sh_video->vfilter; - if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, &actual) == true) { - actual_level = *(enum mp_csp_levels *)(((char *)&actual) + offset); - real_level = m_option_print(&opt, &actual_level); - } else { - real_level = talloc_strdup(NULL, "Unknown"); - } - } - char *res; - if (requested == MP_CSP_LEVELS_AUTO && real_level) { - res = talloc_asprintf(NULL, "Auto (%s)", real_level); - } else if (requested == actual_level || !real_level) { - res = talloc_strdup(NULL, real_level); - } else - res = talloc_asprintf(NULL, mp_gtext("%s, but %s used"), - req_level, real_level); - talloc_free(req_level); - talloc_free(real_level); - *(char **)arg = res; - return M_PROPERTY_OK; -} - -static int mp_property_colormatrix_input_range(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - return levels_property_helper(offsetof(struct mp_csp_details, levels_in), - prop, action, arg, mpctx); -} - -static int mp_property_colormatrix_output_range(m_option_t *prop, int action, - void *arg, MPContext *mpctx) -{ - return levels_property_helper(offsetof(struct mp_csp_details, levels_out), - prop, action, arg, mpctx); -} - -/// Panscan (RW) -static int mp_property_panscan(m_option_t *prop, int action, void *arg, - MPContext *mpctx) -{ - - if (!mpctx->video_out - || vo_control(mpctx->video_out, VOCTRL_GET_PANSCAN, NULL) != VO_TRUE) - return M_PROPERTY_UNAVAILABLE; - - 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 r; -} - -/// Helper to set vo flags. -/** \ingroup PropertyImplHelper - */ -static int mp_property_vo_flag(m_option_t *prop, int action, void *arg, - int vo_ctrl, int *vo_var, MPContext *mpctx) -{ - - if (!mpctx->video_out) - return M_PROPERTY_UNAVAILABLE; - - 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_ |