video: add a "hwdec" property to enable or disable hw decoding at runtime

This commit is contained in:
wm4 2014-04-23 01:17:28 +02:00
parent c7ab0019a3
commit 8a74638dc7
5 changed files with 54 additions and 0 deletions

View File

@ -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``.

View File

@ -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 },

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}