video: refactor hw device creation for hwdec copy modes

Lots of shit code for nothing. We probably could just use libavutil's
code for all of this. But for now go with this, since it tends to
prevent stupid terminal messages during probing (libavutil has no
mechanism to selectively suppress errors specifically during probing).

Ignores the "emulated" API flag (for avoiding vaapi/vdpau wrappers), but
it doesn't matter that much for -copy anyway.
This commit is contained in:
wm4
2017-12-01 08:01:08 +01:00
parent afd5f3227e
commit a0d9e15342
11 changed files with 218 additions and 214 deletions

View File

@@ -124,8 +124,38 @@ static void d3d11_complete_image_params(struct mp_image *img)
mp_image_setfmt(img, IMGFMT_D3D11NV12);
}
static struct AVBufferRef *d3d11_create_standalone(struct mpv_global *global,
struct mp_log *plog, struct hwcontext_create_dev_params *params)
{
ID3D11Device *device = NULL;
HRESULT hr;
d3d_load_dlls();
if (!d3d11_D3D11CreateDevice) {
mp_err(plog, "Failed to load D3D11 library\n");
return NULL;
}
hr = d3d11_D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
D3D11_CREATE_DEVICE_VIDEO_SUPPORT, NULL, 0,
D3D11_SDK_VERSION, &device, NULL, NULL);
if (FAILED(hr)) {
mp_err(plog, "Failed to create D3D11 Device: %s\n",
mp_HRESULT_to_str(hr));
return NULL;
}
AVBufferRef *avref = d3d11_wrap_device_ref(device);
ID3D11Device_Release(device);
if (!avref)
mp_err(plog, "Failed to allocate AVHWDeviceContext.\n");
return avref;
}
const struct hwcontext_fns hwcontext_fns_d3d11 = {
.av_hwdevice_type = AV_HWDEVICE_TYPE_D3D11VA,
.complete_image_params = d3d11_complete_image_params,
.refine_hwframes = d3d11_refine_hwframes,
.av_hwdevice_type = AV_HWDEVICE_TYPE_D3D11VA,
.complete_image_params = d3d11_complete_image_params,
.refine_hwframes = d3d11_refine_hwframes,
.create_dev = d3d11_create_standalone,
};

View File

@@ -33,50 +33,6 @@
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_d3d11va.h>
static void d3d11_destroy_dev(struct mp_hwdec_ctx *ctx)
{
av_buffer_unref(&ctx->av_device_ref);
ID3D11Device_Release((ID3D11Device *)ctx->ctx);
talloc_free(ctx);
}
static struct mp_hwdec_ctx *d3d11_create_dev(struct mpv_global *global,
struct mp_log *plog, bool probing)
{
ID3D11Device *device = NULL;
HRESULT hr;
d3d_load_dlls();
if (!d3d11_D3D11CreateDevice) {
mp_err(plog, "Failed to load D3D11 library\n");
return NULL;
}
hr = d3d11_D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
D3D11_CREATE_DEVICE_VIDEO_SUPPORT, NULL, 0,
D3D11_SDK_VERSION, &device, NULL, NULL);
if (FAILED(hr)) {
mp_err(plog, "Failed to create D3D11 Device: %s\n",
mp_HRESULT_to_str(hr));
return NULL;
}
struct mp_hwdec_ctx *ctx = talloc_ptrtype(NULL, ctx);
*ctx = (struct mp_hwdec_ctx) {
.type = HWDEC_D3D11VA_COPY,
.ctx = device,
.destroy = d3d11_destroy_dev,
.av_device_ref = d3d11_wrap_device_ref(device),
};
if (!ctx->av_device_ref) {
mp_err(plog, "Failed to allocate AVHWDeviceContext.\n");
d3d11_destroy_dev(ctx);
return NULL;
}
return ctx;
}
const struct vd_lavc_hwdec mp_vd_lavc_d3d11va = {
.type = HWDEC_D3D11VA,
@@ -90,7 +46,8 @@ const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy = {
.copying = true,
.image_format = IMGFMT_D3D11VA,
.generic_hwaccel = true,
.create_dev = d3d11_create_dev,
.create_standalone_dev = true,
.create_standalone_dev_type = AV_HWDEVICE_TYPE_D3D11VA,
.set_hwframes = true,
.delay_queue = HWDEC_DELAY_QUEUE_COUNT,
};

View File

@@ -88,15 +88,8 @@ fail:
return NULL;
}
static void d3d9_destroy_dev(struct mp_hwdec_ctx *ctx)
{
av_buffer_unref(&ctx->av_device_ref);
IDirect3DDevice9_Release((IDirect3DDevice9 *)ctx->ctx);
talloc_free(ctx);
}
static struct mp_hwdec_ctx *d3d9_create_dev(struct mpv_global *global,
struct mp_log *plog, bool probing)
static struct AVBufferRef *d3d9_create_standalone(struct mpv_global *global,
struct mp_log *plog, struct hwcontext_create_dev_params *params)
{
d3d_load_dlls();
if (!d3d9_dll || !dxva2_dll) {
@@ -149,23 +142,19 @@ static struct mp_hwdec_ctx *d3d9_create_dev(struct mpv_global *global,
return NULL;
}
struct mp_hwdec_ctx *ctx = talloc_ptrtype(NULL, ctx);
*ctx = (struct mp_hwdec_ctx) {
.type = HWDEC_D3D11VA_COPY,
.ctx = exdev,
.destroy = d3d9_destroy_dev,
.av_device_ref = d3d9_wrap_device_ref((IDirect3DDevice9 *)exdev),
};
if (!ctx->av_device_ref) {
AVBufferRef *avref = d3d9_wrap_device_ref((IDirect3DDevice9 *)exdev);
IDirect3DDevice9Ex_Release(exdev);
if (!avref)
mp_err(plog, "Failed to allocate AVHWDeviceContext.\n");
d3d9_destroy_dev(ctx);
return NULL;
}
return ctx;
return avref;
}
const struct hwcontext_fns hwcontext_fns_dxva2 = {
.av_hwdevice_type = AV_HWDEVICE_TYPE_DXVA2,
.create_dev = d3d9_create_standalone,
};
const struct vd_lavc_hwdec mp_vd_lavc_dxva2 = {
.type = HWDEC_DXVA2,
.image_format = IMGFMT_DXVA2,
@@ -178,7 +167,8 @@ const struct vd_lavc_hwdec mp_vd_lavc_dxva2_copy = {
.copying = true,
.image_format = IMGFMT_DXVA2,
.generic_hwaccel = true,
.create_dev = d3d9_create_dev,
.create_standalone_dev = true,
.create_standalone_dev_type = AV_HWDEVICE_TYPE_DXVA2,
.set_hwframes = true,
.delay_queue = HWDEC_DELAY_QUEUE_COUNT,
};

View File

@@ -97,10 +97,6 @@ struct vd_lavc_hwdec {
int (*init)(struct lavc_ctx *ctx);
int (*init_decoder)(struct lavc_ctx *ctx);
void (*uninit)(struct lavc_ctx *ctx);
// For copy hwdecs. If probing is true, don't log errors if unavailable.
// The returned device will be freed with mp_hwdec_ctx->destroy.
struct mp_hwdec_ctx *(*create_dev)(struct mpv_global *global,
struct mp_log *log, bool probing);
// Suffix for libavcodec decoder. If non-NULL, the codec is overridden
// with hwdec_find_decoder.
// Intuitively, this will force the corresponding wrapper decoder.

View File

@@ -200,7 +200,8 @@ static const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy = {
.image_format = IMGFMT_VAAPI,
.generic_hwaccel = true,
.set_hwframes = true,
.create_dev = va_create_standalone,
.create_standalone_dev = true,
.create_standalone_dev_type = AV_HWDEVICE_TYPE_VAAPI,
};
#endif
@@ -220,7 +221,8 @@ static const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy = {
.image_format = IMGFMT_VDPAU,
.generic_hwaccel = true,
.set_hwframes = true,
.create_dev = vdpau_create_standalone,
.create_standalone_dev = true,
.create_standalone_dev_type = AV_HWDEVICE_TYPE_VDPAU,
};
#endif
@@ -358,16 +360,27 @@ static struct mp_hwdec_ctx *hwdec_create_dev(struct dec_video *vd,
.ctx = NULL,
.destroy = standalone_dev_destroy,
};
if (av_hwdevice_ctx_create(&ctx->av_device_ref,
const struct hwcontext_fns *fns =
hwdec_get_hwcontext_fns(hwdec->create_standalone_dev_type);
if (fns && fns->create_dev) {
struct hwcontext_create_dev_params params = {
.probing = autoprobe,
};
ctx->av_device_ref = fns->create_dev(vd->global, vd->log, &params);
if (!ctx->av_device_ref) {
standalone_dev_destroy(ctx);
ctx = NULL;
}
} else {
if (av_hwdevice_ctx_create(&ctx->av_device_ref,
hwdec->create_standalone_dev_type, NULL, NULL, 0) < 0)
{
standalone_dev_destroy(ctx);
ctx = NULL;
{
standalone_dev_destroy(ctx);
ctx = NULL;
}
}
return ctx;
}
if (hwdec->create_dev)
return hwdec->create_dev(vd->global, vd->log, autoprobe);
if (vd->hwdec_devs) {
int type = hwdec->interop_type ? hwdec->interop_type : hwdec->type;
hwdec_devices_request_all(vd->hwdec_devs);
@@ -391,8 +404,7 @@ static int hwdec_probe(struct dec_video *vd, struct vd_lavc_hwdec *hwdec,
return hwdec->copying ? -1 : HWDEC_ERR_NO_CTX;
if (dev->emulated)
r = HWDEC_ERR_EMULATED;
bool owns_hwdec_dev = !!hwdec->create_dev ||
hwdec->create_standalone_dev;
bool owns_hwdec_dev = !!hwdec->create_standalone_dev;
if (owns_hwdec_dev && dev->destroy)
dev->destroy(dev);
}
@@ -594,8 +606,7 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
ctx->hwdec_dev = hwdec_create_dev(vd, ctx->hwdec, false);
if (!ctx->hwdec_dev)
goto error;
ctx->owns_hwdec_dev = !!ctx->hwdec->create_dev ||
ctx->hwdec->create_standalone_dev;
ctx->owns_hwdec_dev = ctx->hwdec->create_standalone_dev;
if (ctx->hwdec_dev->restore_device)
ctx->hwdec_dev->restore_device(ctx->hwdec_dev);
if (!ctx->hwdec->set_hwframes)

View File

@@ -107,13 +107,18 @@ char *hwdec_devices_get_names(struct mp_hwdec_devices *devs)
return res;
}
#if HAVE_D3D_HWACCEL
extern const struct hwcontext_fns hwcontext_fns_d3d11;
#endif
static const struct hwcontext_fns *const hwcontext_fns[] = {
#if HAVE_D3D_HWACCEL
&hwcontext_fns_d3d11,
#endif
#if HAVE_D3D9_HWACCEL
&hwcontext_fns_dxva2,
#endif
#if HAVE_VAAPI
&hwcontext_fns_vaapi,
#endif
#if HAVE_VDPAU
&hwcontext_fns_vdpau,
#endif
NULL,
};

View File

@@ -111,9 +111,14 @@ void *hwdec_devices_load(struct mp_hwdec_devices *devs, enum hwdec_type type);
char *hwdec_devices_get_names(struct mp_hwdec_devices *devs);
struct mp_image;
struct mpv_global;
struct hwcontext_create_dev_params {
bool probing; // if true, don't log errors if unavailable
};
// Per AV_HWDEVICE_TYPE_* functions, queryable via hwdec_get_hwcontext_fns().
// For now, all entries are strictly optional.
// All entries are strictly optional.
struct hwcontext_fns {
int av_hwdevice_type;
// Set any mp_image fields that require hwcontext specific code, such as
@@ -124,10 +129,19 @@ struct hwcontext_fns {
void (*complete_image_params)(struct mp_image *img);
// Fill in special format-specific requirements.
void (*refine_hwframes)(struct AVBufferRef *hw_frames_ctx);
// Returns a AVHWDeviceContext*. Used for copy hwdecs.
struct AVBufferRef *(*create_dev)(struct mpv_global *global,
struct mp_log *log,
struct hwcontext_create_dev_params *params);
};
// The parameter is of type enum AVHWDeviceType (as in int to avoid extensive
// recursive includes). May return NULL for unknown device types.
const struct hwcontext_fns *hwdec_get_hwcontext_fns(int av_hwdevice_type);
extern const struct hwcontext_fns hwcontext_fns_d3d11;
extern const struct hwcontext_fns hwcontext_fns_dxva2;
extern const struct hwcontext_fns hwcontext_fns_vaapi;
extern const struct hwcontext_fns hwcontext_fns_vdpau;
#endif

View File

@@ -97,36 +97,57 @@ static void va_info_callback(const char *msg)
}
#endif
static void open_lavu_vaapi_device(struct mp_vaapi_ctx *ctx)
static void free_device_ref(struct AVHWDeviceContext *hwctx)
{
ctx->av_device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
if (!ctx->av_device_ref)
return;
struct mp_vaapi_ctx *ctx = hwctx->user_opaque;
AVHWDeviceContext *hwctx = (void *)ctx->av_device_ref->data;
AVVAAPIDeviceContext *vactx = hwctx->hwctx;
if (ctx->display)
vaTerminate(ctx->display);
vactx->display = ctx->display;
if (ctx->destroy_native_ctx)
ctx->destroy_native_ctx(ctx->native_ctx);
if (av_hwdevice_ctx_init(ctx->av_device_ref) < 0)
av_buffer_unref(&ctx->av_device_ref);
#if !VA_CHECK_VERSION(1, 0, 0)
pthread_mutex_lock(&va_log_mutex);
for (int n = 0; n < num_va_mpv_clients; n++) {
if (va_mpv_clients[n] == ctx) {
MP_TARRAY_REMOVE_AT(va_mpv_clients, num_va_mpv_clients, n);
break;
}
}
if (num_va_mpv_clients == 0)
TA_FREEP(&va_mpv_clients); // avoid triggering leak detectors
pthread_mutex_unlock(&va_log_mutex);
#endif
ctx->hwctx.av_device_ref = ctx->av_device_ref;
talloc_free(ctx);
}
struct mp_vaapi_ctx *va_initialize(VADisplay *display, struct mp_log *plog,
bool probing)
{
AVBufferRef *avref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
if (!avref)
return NULL;
AVHWDeviceContext *hwctx = (void *)avref->data;
AVVAAPIDeviceContext *vactx = hwctx->hwctx;
struct mp_vaapi_ctx *res = talloc_ptrtype(NULL, res);
*res = (struct mp_vaapi_ctx) {
.log = mp_log_new(res, plog, "/vaapi"),
.display = display,
.av_device_ref = avref,
.hwctx = {
.type = HWDEC_VAAPI,
.ctx = res,
.av_device_ref = avref,
},
};
hwctx->free = free_device_ref;
hwctx->user_opaque = res;
#if VA_CHECK_VERSION(1, 0, 0)
vaSetErrorCallback(display, va_error_callback, res);
vaSetInfoCallback(display, va_info_callback, res);
@@ -152,9 +173,10 @@ struct mp_vaapi_ctx *va_initialize(VADisplay *display, struct mp_log *plog,
}
MP_VERBOSE(res, "Initialized VAAPI: version %d.%d\n", major, minor);
// For now, some code will still work even if libavutil fails on old crap
// libva drivers (such as the vdpau wraper). So don't error out on failure.
open_lavu_vaapi_device(res);
vactx->display = res->display;
if (av_hwdevice_ctx_init(res->av_device_ref) < 0)
goto error;
res->hwctx.emulated = va_guess_if_emulated(res);
@@ -169,30 +191,11 @@ error:
// Undo va_initialize, and close the VADisplay.
void va_destroy(struct mp_vaapi_ctx *ctx)
{
if (ctx) {
av_buffer_unref(&ctx->av_device_ref);
if (!ctx)
return;
if (ctx->display)
vaTerminate(ctx->display);
if (ctx->destroy_native_ctx)
ctx->destroy_native_ctx(ctx->native_ctx);
#if !VA_CHECK_VERSION(1, 0, 0)
pthread_mutex_lock(&va_log_mutex);
for (int n = 0; n < num_va_mpv_clients; n++) {
if (va_mpv_clients[n] == ctx) {
MP_TARRAY_REMOVE_AT(va_mpv_clients, num_va_mpv_clients, n);
break;
}
}
if (num_va_mpv_clients == 0)
TA_FREEP(&va_mpv_clients); // avoid triggering leak detectors
pthread_mutex_unlock(&va_log_mutex);
#endif
talloc_free(ctx);
}
AVBufferRef *ref = ctx->av_device_ref;
av_buffer_unref(&ref); // frees ctx as well
}
VASurfaceID va_surface_id(struct mp_image *mpi)
@@ -298,20 +301,16 @@ static const struct va_native_display *const native_displays[] = {
NULL
};
static void va_destroy_ctx(struct mp_hwdec_ctx *ctx)
{
va_destroy(ctx->ctx);
}
struct mp_hwdec_ctx *va_create_standalone(struct mpv_global *global,
struct mp_log *plog, bool probing)
static struct AVBufferRef *va_create_standalone(struct mpv_global *global,
struct mp_log *log, struct hwcontext_create_dev_params *params)
{
for (int n = 0; native_displays[n]; n++) {
VADisplay *display = NULL;
void *native_ctx = NULL;
native_displays[n]->create(&display, &native_ctx);
if (display) {
struct mp_vaapi_ctx *ctx = va_initialize(display, plog, probing);
struct mp_vaapi_ctx *ctx =
va_initialize(display, log, params->probing);
if (!ctx) {
vaTerminate(display);
native_displays[n]->destroy(native_ctx);
@@ -319,9 +318,13 @@ struct mp_hwdec_ctx *va_create_standalone(struct mpv_global *global,
}
ctx->native_ctx = native_ctx;
ctx->destroy_native_ctx = native_displays[n]->destroy;
ctx->hwctx.destroy = va_destroy_ctx;
return &ctx->hwctx;
return ctx->hwctx.av_device_ref;
}
}
return NULL;
}
const struct hwcontext_fns hwcontext_fns_vaapi = {
.av_hwdevice_type = AV_HWDEVICE_TYPE_VAAPI,
.create_dev = va_create_standalone,
};

View File

@@ -49,8 +49,4 @@ VASurfaceID va_surface_id(struct mp_image *mpi);
bool va_guess_if_emulated(struct mp_vaapi_ctx *ctx);
struct mpv_global;
struct mp_hwdec_ctx *va_create_standalone(struct mpv_global *global,
struct mp_log *plog, bool probing);
#endif

View File

@@ -337,60 +337,9 @@ static void recheck_preemption(struct mp_hwdec_ctx *hwctx)
mp_vdpau_handle_preemption(ctx, NULL);
}
static bool open_lavu_vdpau_device(struct mp_vdpau_ctx *ctx)
static void free_device_ref(struct AVHWDeviceContext *hwctx)
{
ctx->av_device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VDPAU);
if (!ctx->av_device_ref)
return false;
AVHWDeviceContext *hwctx = (void *)ctx->av_device_ref->data;
AVVDPAUDeviceContext *vdctx = hwctx->hwctx;
vdctx->device = ctx->vdp_device;
vdctx->get_proc_address = ctx->get_proc_address;
if (av_hwdevice_ctx_init(ctx->av_device_ref) < 0)
av_buffer_unref(&ctx->av_device_ref);
ctx->hwctx.av_device_ref = ctx->av_device_ref;
return !!ctx->av_device_ref;
}
struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log, Display *x11,
bool probing)
{
struct mp_vdpau_ctx *ctx = talloc_ptrtype(NULL, ctx);
*ctx = (struct mp_vdpau_ctx) {
.log = log,
.x11 = x11,
.preemption_counter = 1,
.hwctx = {
.type = HWDEC_VDPAU,
.ctx = ctx,
.restore_device = recheck_preemption,
},
};
mpthread_mutex_init_recursive(&ctx->preempt_lock);
pthread_mutex_init(&ctx->pool_lock, NULL);
mark_vdpau_objects_uninitialized(ctx);
if (win_x11_init_vdpau_procs(ctx, probing) < 0) {
mp_vdpau_destroy(ctx);
return NULL;
}
if (!open_lavu_vdpau_device(ctx)) {
mp_vdpau_destroy(ctx);
return NULL;
}
return ctx;
}
void mp_vdpau_destroy(struct mp_vdpau_ctx *ctx)
{
if (!ctx)
return;
struct mp_vdpau_ctx *ctx = hwctx->user_opaque;
struct vdp_functions *vdp = &ctx->vdp;
VdpStatus vdp_st;
@@ -408,8 +357,6 @@ void mp_vdpau_destroy(struct mp_vdpau_ctx *ctx)
}
}
av_buffer_unref(&ctx->av_device_ref);
if (ctx->preemption_obj != VDP_INVALID_HANDLE) {
vdp_st = vdp->output_surface_destroy(ctx->preemption_obj);
CHECK_VDP_WARNING(ctx, "Error when calling vdp_output_surface_destroy");
@@ -420,11 +367,70 @@ void mp_vdpau_destroy(struct mp_vdpau_ctx *ctx)
CHECK_VDP_WARNING(ctx, "Error when calling vdp_device_destroy");
}
if (ctx->close_display)
XCloseDisplay(ctx->x11);
pthread_mutex_destroy(&ctx->pool_lock);
pthread_mutex_destroy(&ctx->preempt_lock);
talloc_free(ctx);
}
struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log, Display *x11,
bool probing)
{
AVBufferRef *avref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VDPAU);
if (!avref)
return NULL;
AVHWDeviceContext *hwctx = (void *)avref->data;
AVVDPAUDeviceContext *vdctx = hwctx->hwctx;
struct mp_vdpau_ctx *ctx = talloc_ptrtype(NULL, ctx);
*ctx = (struct mp_vdpau_ctx) {
.log = log,
.x11 = x11,
.preemption_counter = 1,
.av_device_ref = avref,
.hwctx = {
.type = HWDEC_VDPAU,
.ctx = ctx,
.restore_device = recheck_preemption,
.av_device_ref = avref,
},
};
mpthread_mutex_init_recursive(&ctx->preempt_lock);
pthread_mutex_init(&ctx->pool_lock, NULL);
hwctx->free = free_device_ref;
hwctx->user_opaque = ctx;
mark_vdpau_objects_uninitialized(ctx);
if (win_x11_init_vdpau_procs(ctx, probing) < 0) {
mp_vdpau_destroy(ctx);
return NULL;
}
vdctx->device = ctx->vdp_device;
vdctx->get_proc_address = ctx->get_proc_address;
if (av_hwdevice_ctx_init(ctx->av_device_ref) < 0) {
mp_vdpau_destroy(ctx);
return NULL;
}
return ctx;
}
void mp_vdpau_destroy(struct mp_vdpau_ctx *ctx)
{
if (!ctx)
return;
AVBufferRef *ref = ctx->av_device_ref;
av_buffer_unref(&ref); // frees ctx as well
}
bool mp_vdpau_get_format(int imgfmt, VdpChromaType *out_chroma_type,
VdpYCbCrFormat *out_pixel_format)
{
@@ -531,16 +537,8 @@ bool mp_vdpau_guess_if_emulated(struct mp_vdpau_ctx *ctx)
return vdp_st == VDP_STATUS_OK && info && strstr(info, "VAAPI");
}
static void vdpau_destroy_standalone(struct mp_hwdec_ctx *ctx)
{
struct mp_vdpau_ctx *vdp = ctx->ctx;
Display *display = vdp->x11;
mp_vdpau_destroy(vdp);
XCloseDisplay(display);
}
struct mp_hwdec_ctx *vdpau_create_standalone(struct mpv_global *global,
struct mp_log *plog, bool probing)
static struct AVBufferRef *vdpau_create_standalone(struct mpv_global *global,
struct mp_log *log, struct hwcontext_create_dev_params *params)
{
XInitThreads();
@@ -548,13 +546,20 @@ struct mp_hwdec_ctx *vdpau_create_standalone(struct mpv_global *global,
if (!display)
return NULL;
struct mp_vdpau_ctx *vdp = mp_vdpau_create_device_x11(plog, display, probing);
struct mp_vdpau_ctx *vdp =
mp_vdpau_create_device_x11(log, display, params->probing);
if (!vdp) {
XCloseDisplay(display);
return NULL;
}
vdp->hwctx.emulated = mp_vdpau_guess_if_emulated(vdp);
vdp->hwctx.destroy = vdpau_destroy_standalone;
return &vdp->hwctx;
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,
};

View File

@@ -51,6 +51,7 @@ struct vdp_functions {
struct mp_vdpau_ctx {
struct mp_log *log;
Display *x11;
bool close_display;
struct mp_hwdec_ctx hwctx;
struct AVBufferRef *av_device_ref;
@@ -90,10 +91,6 @@ struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log, Display *x11
bool probing);
void mp_vdpau_destroy(struct mp_vdpau_ctx *ctx);
struct mpv_global;
struct mp_hwdec_ctx *vdpau_create_standalone(struct mpv_global *global,
struct mp_log *plog, bool probing);
int mp_vdpau_handle_preemption(struct mp_vdpau_ctx *ctx, uint64_t *counter);
struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,