summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-04-23 01:17:28 +0200
committerwm4 <wm4@nowhere>2014-04-23 01:58:12 +0200
commit8a74638dc743007f6d5d6bb3a672167fce353480 (patch)
treeebfe93c575a3d801cb21cd565da29e6f1d5bd41f
parentc7ab0019a388ceabda38e0d7ba5eb289f30e24af (diff)
downloadmpv-8a74638dc743007f6d5d6bb3a672167fce353480.tar.bz2
mpv-8a74638dc743007f6d5d6bb3a672167fce353480.tar.xz
video: add a "hwdec" property to enable or disable hw decoding at runtime
-rw-r--r--DOCS/man/en/input.rst10
-rw-r--r--player/command.c33
-rw-r--r--video/decode/lavc.h1
-rw-r--r--video/decode/vd.h1
-rw-r--r--video/decode/vd_lavc.c9
5 files changed, 54 insertions, 0 deletions
diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst
index dadf8a1901..8c5a021329 100644
--- a/DOCS/man/en/input.rst
+++ b/DOCS/man/en/input.rst
@@ -879,6 +879,16 @@ Property list
``hue`` (RW)
See ``--hue``.
+``hwdec`` (RW)
+ Return the current hardware decoder that is used. This uses the same values
+ as the ``--hwdec`` option. If software decoding is active, this returns
+ ``no``. You can write this property. Then the ``--hwdec`` option is set to
+ the new value, and video decoding will be reinitialized (internally, the
+ player will perform a seek to refresh the video properly).
+
+ Note that you don't know the success of the operation immediately after
+ writing this property. It happens with a delay as video is reinitialized.
+
``panscan`` (RW)
See ``--panscan``.
diff --git a/player/command.c b/player/command.c
index 0cc1edde81..fd08c667c8 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1473,6 +1473,38 @@ static int mp_property_program(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static int mp_property_hwdec(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ struct MPOpts *opts = mpctx->opts;
+ struct dec_video *vd = mpctx->d_video;
+ if (!vd)
+ return M_PROPERTY_UNAVAILABLE;
+
+ int current = 0;
+ video_vd_control(vd, VDCTRL_GET_HWDEC, &current);
+
+ switch (action) {
+ case M_PROPERTY_GET:
+ *(int *)arg = current;
+ return M_PROPERTY_OK;
+ case M_PROPERTY_SET: {
+ int new = *(int *)arg;
+ if (current == new)
+ return M_PROPERTY_OK;
+ if (!(mpctx->initialized_flags & INITIALIZED_VCODEC))
+ return M_PROPERTY_ERROR;
+ double last_pts = mpctx->last_vo_pts;
+ uninit_player(mpctx, INITIALIZED_VCODEC);
+ opts->hwdec_api = new;
+ reinit_video_chain(mpctx);
+ if (last_pts != MP_NOPTS_VALUE)
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, last_pts, 1, true);
+ return M_PROPERTY_OK;
+ }
+ }
+ return mp_property_generic_option(prop, action, arg, mpctx);
+}
/// Fullscreen state (RW)
static int mp_property_fullscreen(m_option_t *prop,
@@ -2348,6 +2380,7 @@ static const m_option_t mp_properties[] = {
M_OPTION_PROPERTY_CUSTOM("vid", mp_property_video),
{ "program", mp_property_program, CONF_TYPE_INT,
CONF_RANGE, -1, 65535, NULL },
+ M_OPTION_PROPERTY_CUSTOM("hwdec", mp_property_hwdec),
{ "osd-width", mp_property_osd_w, CONF_TYPE_INT },
{ "osd-height", mp_property_osd_h, CONF_TYPE_INT },
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 16d3251725..d67292c4fd 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -26,6 +26,7 @@ typedef struct lavc_ctx {
AVCodecContext *avctx;
AVFrame *pic;
struct vd_lavc_hwdec *hwdec;
+ int selected_hwdec;
enum AVPixelFormat pix_fmt;
int best_csp;
enum AVDiscard skip_frame;
diff --git a/video/decode/vd.h b/video/decode/vd.h
index 35c2739aa8..28ace3cc04 100644
--- a/video/decode/vd.h
+++ b/video/decode/vd.h
@@ -45,6 +45,7 @@ enum vd_ctrl {
VDCTRL_RESET = 1, // reset decode state after seeking
VDCTRL_QUERY_UNSEEN_FRAMES, // current decoder lag
VDCTRL_FORCE_HWDEC_FALLBACK, // force software decoding fallback
+ VDCTRL_GET_HWDEC,
};
#endif /* MPLAYER_VD_H */
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 4935913d73..57b391a6a2 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -225,6 +225,8 @@ static int init(struct dec_video *vd, const char *decoder)
ctx->log = vd->log;
ctx->opts = vd->opts;
+ ctx->selected_hwdec = vd->opts->hwdec_api;
+
if (bstr_endswith0(bstr0(decoder), "_vdpau")) {
MP_WARN(vd, "VDPAU decoder '%s' was requested. "
"This way of enabling hardware\ndecoding is not supported "
@@ -646,6 +648,13 @@ static int control(struct dec_video *vd, int cmd, void *arg)
delay += avctx->thread_count - 1;
*(int *)arg = delay;
return CONTROL_TRUE;
+ case VDCTRL_GET_HWDEC: {
+ int hwdec = ctx->selected_hwdec;
+ if (!ctx->software_fallback_decoder)
+ hwdec = 0;
+ *(int *)arg = hwdec;
+ return CONTROL_TRUE;
+ }
case VDCTRL_FORCE_HWDEC_FALLBACK:
return force_fallback(vd);
}