summaryrefslogtreecommitdiffstats
path: root/video/vdpau.h
diff options
context:
space:
mode:
Diffstat (limited to 'video/vdpau.h')
-rw-r--r--video/vdpau.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/video/vdpau.h b/video/vdpau.h
new file mode 100644
index 0000000..a30f478
--- /dev/null
+++ b/video/vdpau.h
@@ -0,0 +1,109 @@
+#ifndef MPV_VDPAU_H
+#define MPV_VDPAU_H
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include <vdpau/vdpau.h>
+#include <vdpau/vdpau_x11.h>
+
+#include "common/msg.h"
+#include "hwdec.h"
+#include "osdep/threads.h"
+
+#include "config.h"
+#if !HAVE_GPL
+#error GPL only
+#endif
+
+#define CHECK_VDP_ERROR_ST(ctx, message, statement) \
+ do { \
+ if (vdp_st != VDP_STATUS_OK) { \
+ MP_ERR(ctx, "%s: %s\n", message, vdp->get_error_string(vdp_st)); \
+ statement \
+ } \
+ } while (0)
+
+#define CHECK_VDP_ERROR(ctx, message) \
+ CHECK_VDP_ERROR_ST(ctx, message, return -1;)
+
+#define CHECK_VDP_ERROR_NORETURN(ctx, message) \
+ CHECK_VDP_ERROR_ST(ctx, message, ;)
+
+#define CHECK_VDP_WARNING(ctx, message) \
+ do { \
+ if (vdp_st != VDP_STATUS_OK) \
+ MP_WARN(ctx, "%s: %s\n", message, vdp->get_error_string(vdp_st)); \
+ } while (0)
+
+struct vdp_functions {
+#define VDP_FUNCTION(vdp_type, _, mp_name) vdp_type *mp_name;
+#include "video/vdpau_functions.inc"
+#undef VDP_FUNCTION
+};
+
+
+#define MAX_VIDEO_SURFACES 50
+
+// Shared state. Objects created from different VdpDevices are often (always?)
+// incompatible to each other, so all code must use a shared VdpDevice.
+struct mp_vdpau_ctx {
+ struct mp_log *log;
+ Display *x11;
+ bool close_display;
+
+ struct mp_hwdec_ctx hwctx;
+ struct AVBufferRef *av_device_ref;
+
+ // These are mostly immutable, except on preemption. We don't really care
+ // to synchronize the preemption case fully correctly, because it's an
+ // extremely obscure corner case, and basically a vdpau API design bug.
+ // What we do will sort-of work anyway (no memory errors are possible).
+ struct vdp_functions vdp;
+ VdpGetProcAddress *get_proc_address;
+ VdpDevice vdp_device;
+
+ mp_mutex preempt_lock;
+ bool is_preempted; // set to true during unavailability
+ uint64_t preemption_counter; // incremented after _restoring_
+ bool preemption_user_notified;
+ double last_preemption_retry_fail;
+ VdpOutputSurface preemption_obj; // dummy for reliable preempt. check
+
+ // Surface pool
+ mp_mutex pool_lock;
+ int64_t age_counter;
+ struct surface_entry {
+ VdpVideoSurface surface;
+ VdpOutputSurface osurface;
+ bool allocated;
+ int w, h;
+ VdpRGBAFormat rgb_format;
+ VdpChromaType chroma;
+ bool rgb;
+ bool in_use;
+ int64_t age;
+ } video_surfaces[MAX_VIDEO_SURFACES];
+};
+
+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);
+
+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,
+ VdpChromaType chroma, int w, int h);
+
+bool mp_vdpau_get_format(int imgfmt, VdpChromaType *out_chroma_type,
+ VdpYCbCrFormat *out_pixel_format);
+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