1
mirror of https://github.com/mpv-player/mpv synced 2024-10-30 04:46:41 +01:00
mpv/video/vdpau.h
wm4 d99f30d726 video: warn if an emulated hwdec API is used
mpv supports two hardware decoding APIs on Linux: vdpau and vaapi. Each
of these has emulation wrappers. The wrappers are usually slower and
have fewer features than their native opposites. In particular the libva
vdpau driver is practically unmaintained.

Check the vendor string and print a warning if emulation is detected.
Checking vendor strings is a very stupid thing to do, but I find the
thought of people using an emulated API for no reason worse.

Also, make --hwdec=auto never use an API that is detected as emulated.
This doesn't work quite right yet, because once one API is loaded,
vo_opengl doesn't unload it, so no hardware decoding will be used if the
first probed API (usually vdpau) is rejected. But good enough.
2014-05-28 02:08:45 +02:00

90 lines
2.8 KiB
C

#ifndef MPV_VDPAU_H
#define MPV_VDPAU_H
#include <stdbool.h>
#include <inttypes.h>
#include <pthread.h>
#include <vdpau/vdpau.h>
#include <vdpau/vdpau_x11.h>
#include "common/msg.h"
#define CHECK_VDP_ERROR(ctx, message) \
do { \
if (vdp_st != VDP_STATUS_OK) { \
MP_ERR(ctx, "%s: %s\n", message, vdp->get_error_string(vdp_st)); \
return -1; \
} \
} while (0)
#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;
struct vo_x11_state *x11;
// 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;
pthread_mutex_t 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;
// Surface pool
pthread_mutex_t pool_lock;
struct surface_entry {
VdpVideoSurface surface;
VdpOutputSurface osurface;
bool allocated;
int w, h;
VdpRGBAFormat rgb_format;
VdpChromaType chroma;
bool rgb;
bool in_use;
} video_surfaces[MAX_VIDEO_SURFACES];
};
struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log,
struct vo_x11_state *x11);
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);
bool mp_vdpau_guess_if_emulated(struct mp_vdpau_ctx *ctx);
#endif