diff options
Diffstat (limited to 'video/vdpau.h')
-rw-r--r-- | video/vdpau.h | 109 |
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 |