summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-12-02 04:27:02 +0100
committerwm4 <wm4@nowhere>2017-12-02 04:53:51 +0100
commit23a9efd124042e7c97f8317bcd8ae5903d039ef7 (patch)
tree8af4a34bd494abe51608d3648de612d5af920314
parent0780d3832997056b581cdecb29e605132fae9417 (diff)
downloadmpv-23a9efd124042e7c97f8317bcd8ae5903d039ef7.tar.bz2
mpv-23a9efd124042e7c97f8317bcd8ae5903d039ef7.tar.xz
vd_lavc, vdpau, vaapi: restore emulated API avoidance
This code is for trying to avoid using an emulation layer when using auto probing, so that we end up using the actual API the drivers provide. It was destroyed in the recent refactor.
-rw-r--r--video/decode/vd_lavc.c11
-rw-r--r--video/hwdec.h2
-rw-r--r--video/vaapi.c14
-rw-r--r--video/vdpau.c22
-rw-r--r--video/vdpau.h2
5 files changed, 48 insertions, 3 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 5e9b30d453..aac9f81839 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -458,6 +458,17 @@ static void select_and_set_hwdec(struct dec_video *vd)
MP_VERBOSE(vd, "Could not create device.\n");
continue;
}
+
+ const struct hwcontext_fns *fns =
+ hwdec_get_hwcontext_fns(hwdec->lavc_device);
+ if (fns && fns->is_emulated && fns->is_emulated(ctx->hwdec_dev)) {
+ if (hwdec_auto) {
+ MP_VERBOSE(vd, "Not using emulated API.\n");
+ av_buffer_unref(&ctx->hwdec_dev);
+ continue;
+ }
+ MP_WARN(vd, "Using emulated hardware decoding API.\n");
+ }
}
ctx->use_hwdec = true;
diff --git a/video/hwdec.h b/video/hwdec.h
index 34dd52e08b..2c0f19b606 100644
--- a/video/hwdec.h
+++ b/video/hwdec.h
@@ -119,6 +119,8 @@ struct hwcontext_fns {
struct AVBufferRef *(*create_dev)(struct mpv_global *global,
struct mp_log *log,
struct hwcontext_create_dev_params *params);
+ // Return whether this is using some sort of sub-optimal emulation layer.
+ bool (*is_emulated)(struct AVBufferRef *hw_device_ctx);
};
// The parameter is of type enum AVHWDeviceType (as in int to avoid extensive
diff --git a/video/vaapi.c b/video/vaapi.c
index a6607b4aeb..00052cec39 100644
--- a/video/vaapi.c
+++ b/video/vaapi.c
@@ -204,12 +204,21 @@ VASurfaceID va_surface_id(struct mp_image *mpi)
(VASurfaceID)(uintptr_t)mpi->planes[3] : VA_INVALID_ID;
}
-bool va_guess_if_emulated(struct mp_vaapi_ctx *ctx)
+static bool is_emulated(struct AVBufferRef *hw_device_ctx)
{
- const char *s = vaQueryVendorString(ctx->display);
+ AVHWDeviceContext *hwctx = (void *)hw_device_ctx->data;
+ AVVAAPIDeviceContext *vactx = hwctx->hwctx;
+
+ const char *s = vaQueryVendorString(vactx->display);
return s && strstr(s, "VDPAU backend");
}
+
+bool va_guess_if_emulated(struct mp_vaapi_ctx *ctx)
+{
+ return is_emulated(ctx->av_device_ref);
+}
+
struct va_native_display {
void (*create)(VADisplay **out_display, void **out_native_ctx);
void (*destroy)(void *native_ctx);
@@ -327,4 +336,5 @@ static struct AVBufferRef *va_create_standalone(struct mpv_global *global,
const struct hwcontext_fns hwcontext_fns_vaapi = {
.av_hwdevice_type = AV_HWDEVICE_TYPE_VAAPI,
.create_dev = va_create_standalone,
+ .is_emulated = is_emulated,
};
diff --git a/video/vdpau.c b/video/vdpau.c
index 1785702fdb..d751849ec3 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -537,6 +537,26 @@ bool mp_vdpau_guess_if_emulated(struct mp_vdpau_ctx *ctx)
return vdp_st == VDP_STATUS_OK && info && strstr(info, "VAAPI");
}
+// (This clearly works only for contexts wrapped by our code.)
+struct mp_vdpau_ctx *mp_vdpau_get_ctx_from_av(AVBufferRef *hw_device_ctx)
+{
+ AVHWDeviceContext *hwctx = (void *)hw_device_ctx->data;
+
+ if (hwctx->free != free_device_ref)
+ return NULL; // not ours
+
+ return hwctx->user_opaque;
+}
+
+static bool is_emulated(struct AVBufferRef *hw_device_ctx)
+{
+ struct mp_vdpau_ctx *ctx = mp_vdpau_get_ctx_from_av(hw_device_ctx);
+ if (!ctx)
+ return false;
+
+ return mp_vdpau_guess_if_emulated(ctx);
+}
+
static struct AVBufferRef *vdpau_create_standalone(struct mpv_global *global,
struct mp_log *log, struct hwcontext_create_dev_params *params)
{
@@ -555,11 +575,11 @@ static struct AVBufferRef *vdpau_create_standalone(struct mpv_global *global,
vdp->hwctx.emulated = mp_vdpau_guess_if_emulated(vdp);
vdp->close_display = true;
- mp_warn(log, "idk\n");
return vdp->hwctx.av_device_ref;
}
const struct hwcontext_fns hwcontext_fns_vdpau = {
.av_hwdevice_type = AV_HWDEVICE_TYPE_VDPAU,
.create_dev = vdpau_create_standalone,
+ .is_emulated = is_emulated,
};
diff --git a/video/vdpau.h b/video/vdpau.h
index 118db8cbfe..b0f402c3f2 100644
--- a/video/vdpau.h
+++ b/video/vdpau.h
@@ -103,6 +103,8 @@ bool mp_vdpau_get_rgb_format(int imgfmt, VdpRGBAFormat *out_rgba_format);
struct mp_image *mp_vdpau_upload_video_surface(struct mp_vdpau_ctx *ctx,
struct mp_image *mpi);
+struct mp_vdpau_ctx *mp_vdpau_get_ctx_from_av(struct AVBufferRef *hw_device_ctx);
+
bool mp_vdpau_guess_if_emulated(struct mp_vdpau_ctx *ctx);
#endif