mirror of
https://github.com/mpv-player/mpv
synced 2024-08-08 13:25:45 +02:00
vdpau: move RGB surface management out of the VO
Integrate it with the existing surface allocator in vdpau.c. The changes are a bit violent, because the vdpau API is so non-orthogonal: compared to video surfaces, output surfaces use a different ID type, different format types, and different API functions. Also, introduce IMGFMT_VDPAU_OUTPUT for VdpOutputSurfaces wrapped in mp_image, rather than hacking it. This is a bit cleaner.
This commit is contained in:
parent
dbed21cde4
commit
7b7e15a460
@ -42,6 +42,8 @@ struct mp_imgfmt_entry {
|
||||
};
|
||||
|
||||
static const struct mp_imgfmt_entry mp_imgfmt_list[] = {
|
||||
// not in ffmpeg
|
||||
FMT("vdpau_output", IMGFMT_VDPAU_OUTPUT)
|
||||
// these formats are pretty common, and the "le"/"be" suffixes enforced
|
||||
// by FFmpeg are annoying
|
||||
FMT("yuv420p10", IMGFMT_420P10)
|
||||
@ -128,12 +130,26 @@ const char *mp_imgfmt_to_name(int fmt)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static struct mp_imgfmt_desc mp_only_imgfmt_desc(int mpfmt)
|
||||
{
|
||||
switch (mpfmt) {
|
||||
case IMGFMT_VDPAU_OUTPUT:
|
||||
return (struct mp_imgfmt_desc) {
|
||||
.id = mpfmt,
|
||||
.avformat = AV_PIX_FMT_NONE,
|
||||
.name = mp_imgfmt_to_name(mpfmt),
|
||||
.flags = MP_IMGFLAG_BE | MP_IMGFLAG_LE | MP_IMGFLAG_RGB,
|
||||
};
|
||||
}
|
||||
return (struct mp_imgfmt_desc) {0};
|
||||
}
|
||||
|
||||
struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
{
|
||||
enum AVPixelFormat fmt = imgfmt2pixfmt(mpfmt);
|
||||
const AVPixFmtDescriptor *pd = av_pix_fmt_desc_get(fmt);
|
||||
if (!pd || fmt == AV_PIX_FMT_NONE)
|
||||
return (struct mp_imgfmt_desc) {0};
|
||||
return mp_only_imgfmt_desc(mpfmt);
|
||||
|
||||
struct mp_imgfmt_desc desc = {
|
||||
.id = mpfmt,
|
||||
|
@ -252,7 +252,8 @@ enum mp_imgfmt {
|
||||
|
||||
// Hardware accelerated formats. Plane data points to special data
|
||||
// structures, instead of pixel data.
|
||||
IMGFMT_VDPAU,
|
||||
IMGFMT_VDPAU, // VdpVideoSurface
|
||||
IMGFMT_VDPAU_OUTPUT, // VdpOutputSurface
|
||||
IMGFMT_VDA,
|
||||
IMGFMT_VAAPI,
|
||||
|
||||
@ -330,7 +331,8 @@ static inline bool IMGFMT_IS_RGB(int fmt)
|
||||
#define IMGFMT_RGB_DEPTH(fmt) (mp_imgfmt_get_desc(fmt).plane_bits)
|
||||
|
||||
#define IMGFMT_IS_HWACCEL(fmt) \
|
||||
((fmt) == IMGFMT_VDPAU || (fmt) == IMGFMT_VAAPI || (fmt) == IMGFMT_VDA)
|
||||
((fmt) == IMGFMT_VDPAU || (fmt) == IMGFMT_VDPAU_OUTPUT || \
|
||||
(fmt) == IMGFMT_VAAPI || (fmt) == IMGFMT_VDA)
|
||||
|
||||
int mp_imgfmt_from_name(bstr name, bool allow_hwaccel);
|
||||
const char *mp_imgfmt_to_name(int fmt);
|
||||
|
@ -60,7 +60,6 @@
|
||||
|
||||
/* number of video and output surfaces */
|
||||
#define MAX_OUTPUT_SURFACES 15
|
||||
#define NUM_BUFFERED_VIDEO 5
|
||||
|
||||
/* Pixelformat used for output surfaces */
|
||||
#define OUTPUT_RGBA_FORMAT VDP_RGBA_FORMAT_B8G8R8A8
|
||||
@ -83,8 +82,6 @@ struct vdpctx {
|
||||
VdpOutputSurface output_surfaces[MAX_OUTPUT_SURFACES];
|
||||
VdpOutputSurface screenshot_surface;
|
||||
int num_output_surfaces;
|
||||
VdpOutputSurface rgb_surfaces[NUM_BUFFERED_VIDEO];
|
||||
bool rgb_surfaces_used[NUM_BUFFERED_VIDEO];
|
||||
VdpOutputSurface black_pixel;
|
||||
|
||||
struct mp_image *current_image;
|
||||
@ -177,7 +174,7 @@ static int render_video_to_output_surface(struct vo *vo,
|
||||
"vdp_presentation_queue_block_until_surface_idle");
|
||||
|
||||
if (vc->rgb_mode) {
|
||||
VdpOutputSurface surface = (uintptr_t)mpi->planes[0];
|
||||
VdpOutputSurface surface = (uintptr_t)mpi->planes[3];
|
||||
int flags = VDP_OUTPUT_SURFACE_RENDER_ROTATE_0;
|
||||
vdp_st = vdp->output_surface_render_output_surface(output_surface,
|
||||
NULL, vc->black_pixel,
|
||||
@ -373,15 +370,6 @@ static void free_video_specific(struct vo *vo)
|
||||
}
|
||||
vc->screenshot_surface = VDP_INVALID_HANDLE;
|
||||
|
||||
for (int n = 0; n < NUM_BUFFERED_VIDEO; n++) {
|
||||
assert(!vc->rgb_surfaces_used[n]);
|
||||
if (vc->rgb_surfaces[n] != VDP_INVALID_HANDLE) {
|
||||
vdp_st = vdp->output_surface_destroy(vc->rgb_surfaces[n]);
|
||||
CHECK_VDP_WARNING(vo, "Error when calling vdp_output_surface_destroy");
|
||||
}
|
||||
vc->rgb_surfaces[n] = VDP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (vc->black_pixel != VDP_INVALID_HANDLE) {
|
||||
vdp_st = vdp->output_surface_destroy(vc->black_pixel);
|
||||
CHECK_VDP_WARNING(vo, "Error when calling vdp_output_surface_destroy");
|
||||
@ -389,14 +377,6 @@ static void free_video_specific(struct vo *vo)
|
||||
vc->black_pixel = VDP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
static int get_rgb_format(int imgfmt)
|
||||
{
|
||||
switch (imgfmt) {
|
||||
case IMGFMT_BGR32: return VDP_RGBA_FORMAT_B8G8R8A8;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int initialize_vdpau_objects(struct vo *vo)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
@ -412,17 +392,6 @@ static int initialize_vdpau_objects(struct vo *vo)
|
||||
if (win_x11_init_vdpau_flip_queue(vo) < 0)
|
||||
return -1;
|
||||
|
||||
if (vc->rgb_mode) {
|
||||
int format = get_rgb_format(vc->image_format);
|
||||
for (int n = 0; n < NUM_BUFFERED_VIDEO; n++) {
|
||||
vdp_st = vdp->output_surface_create(vc->vdp_device,
|
||||
format,
|
||||
vc->vid_width, vc->vid_height,
|
||||
&vc->rgb_surfaces[n]);
|
||||
CHECK_VDP_ERROR(vo, "Allocating RGB surface");
|
||||
}
|
||||
}
|
||||
|
||||
if (vc->black_pixel == VDP_INVALID_HANDLE) {
|
||||
vdp_st = vdp->output_surface_create(vc->vdp_device, OUTPUT_RGBA_FORMAT,
|
||||
1, 1, &vc->black_pixel);
|
||||
@ -443,8 +412,6 @@ static void mark_vdpau_objects_uninitialized(struct vo *vo)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
|
||||
for (int i = 0; i < NUM_BUFFERED_VIDEO; i++)
|
||||
vc->rgb_surfaces[i] = VDP_INVALID_HANDLE;
|
||||
forget_frames(vo, false);
|
||||
vc->black_pixel = VDP_INVALID_HANDLE;
|
||||
vc->video_mixer->video_mixer = VDP_INVALID_HANDLE;
|
||||
@ -502,7 +469,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
|
||||
vc->vid_width = params->w;
|
||||
vc->vid_height = params->h;
|
||||
|
||||
vc->rgb_mode = get_rgb_format(params->imgfmt) >= 0;
|
||||
vc->rgb_mode = mp_vdpau_get_rgb_format(params->imgfmt, NULL);
|
||||
|
||||
free_video_specific(vo);
|
||||
|
||||
@ -872,33 +839,6 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
|
||||
vc->surface_num = WRAP_ADD(vc->surface_num, 1, vc->num_output_surfaces);
|
||||
}
|
||||
|
||||
static void free_rgb_surface(void *ptr)
|
||||
{
|
||||
bool *entry = ptr;
|
||||
*entry = false;
|
||||
}
|
||||
|
||||
static struct mp_image *get_rgb_surface(struct vo *vo)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
|
||||
assert(vc->rgb_mode);
|
||||
|
||||
for (int n = 0; n < NUM_BUFFERED_VIDEO; n++) {
|
||||
bool *used = &vc->rgb_surfaces_used[n];
|
||||
if (!*used) {
|
||||
*used = true;
|
||||
struct mp_image mpi = {0};
|
||||
mp_image_setfmt(&mpi, IMGFMT_VDPAU); // not really, but keep csp flags
|
||||
mpi.planes[0] = (void *)(uintptr_t)vc->rgb_surfaces[n];
|
||||
return mp_image_new_custom_ref(&mpi, used, free_rgb_surface);
|
||||
}
|
||||
}
|
||||
|
||||
MP_ERR(vo, "no surfaces available in get_rgb_surface\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void draw_image(struct vo *vo, struct mp_image *mpi)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
@ -912,29 +852,10 @@ static void draw_image(struct vo *vo, struct mp_image *mpi)
|
||||
static struct mp_image *filter_image(struct vo *vo, struct mp_image *mpi)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
struct vdp_functions *vdp = vc->vdp;
|
||||
struct mp_image *reserved_mpi = NULL;
|
||||
VdpStatus vdp_st;
|
||||
|
||||
check_preemption(vo);
|
||||
|
||||
if (vc->rgb_mode) {
|
||||
reserved_mpi = get_rgb_surface(vo);
|
||||
if (!reserved_mpi)
|
||||
goto end;
|
||||
VdpOutputSurface rgb_surface = (uintptr_t)reserved_mpi->planes[0];
|
||||
if (rgb_surface != VDP_INVALID_HANDLE) {
|
||||
vdp_st = vdp->output_surface_put_bits_native(rgb_surface,
|
||||
&(const void *){mpi->planes[0]},
|
||||
&(uint32_t){mpi->stride[0]},
|
||||
NULL);
|
||||
CHECK_VDP_WARNING(vo, "Error when calling "
|
||||
"output_surface_put_bits_native");
|
||||
}
|
||||
} else {
|
||||
reserved_mpi = mp_vdpau_upload_video_surface(vc->mpvdp, mpi);
|
||||
}
|
||||
|
||||
struct mp_image *reserved_mpi = mp_vdpau_upload_video_surface(vc->mpvdp, mpi);
|
||||
if (!reserved_mpi)
|
||||
goto end;
|
||||
|
||||
@ -1014,8 +935,7 @@ static int query_format(struct vo *vo, uint32_t format)
|
||||
int flags = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
|
||||
if (mp_vdpau_get_format(format, NULL, NULL))
|
||||
return flags;
|
||||
int rgb_format = get_rgb_format(format);
|
||||
if (!vc->force_yuv && rgb_format >= 0)
|
||||
if (!vc->force_yuv && mp_vdpau_get_rgb_format(format, NULL))
|
||||
return flags;
|
||||
return 0;
|
||||
}
|
||||
|
119
video/vdpau.c
119
video/vdpau.c
@ -28,8 +28,11 @@
|
||||
|
||||
static void mark_vdpau_objects_uninitialized(struct mp_vdpau_ctx *ctx)
|
||||
{
|
||||
for (int i = 0; i < MAX_VIDEO_SURFACES; i++)
|
||||
for (int i = 0; i < MAX_VIDEO_SURFACES; i++) {
|
||||
ctx->video_surfaces[i].surface = VDP_INVALID_HANDLE;
|
||||
ctx->video_surfaces[i].osurface = VDP_INVALID_HANDLE;
|
||||
ctx->video_surfaces[i].allocated = false;
|
||||
}
|
||||
ctx->vdp_device = VDP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@ -181,30 +184,45 @@ static struct mp_image *create_ref(struct mp_vdpau_ctx *ctx, int index)
|
||||
struct mp_image *res =
|
||||
mp_image_new_custom_ref(&(struct mp_image){0}, ref,
|
||||
release_decoder_surface);
|
||||
mp_image_setfmt(res, IMGFMT_VDPAU);
|
||||
mp_image_setfmt(res, e->rgb ? IMGFMT_VDPAU_OUTPUT : IMGFMT_VDPAU);
|
||||
mp_image_set_size(res, e->w, e->h);
|
||||
res->planes[0] = (void *)"dummy"; // must be non-NULL, otherwise arbitrary
|
||||
res->planes[3] = (void *)(intptr_t)e->surface;
|
||||
res->planes[3] = (void *)(intptr_t)(e->rgb ? e->osurface : e->surface);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
VdpChromaType chroma, int w, int h)
|
||||
static struct mp_image *mp_vdpau_get_surface(struct mp_vdpau_ctx *ctx,
|
||||
VdpChromaType chroma,
|
||||
VdpRGBAFormat rgb_format,
|
||||
bool rgb, int w, int h)
|
||||
{
|
||||
struct vdp_functions *vdp = &ctx->vdp;
|
||||
int surface_index = -1;
|
||||
VdpStatus vdp_st;
|
||||
|
||||
if (rgb) {
|
||||
chroma = (VdpChromaType)-1;
|
||||
} else {
|
||||
rgb_format = (VdpChromaType)-1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&ctx->pool_lock);
|
||||
|
||||
// Destroy all unused surfaces that don't have matching parameters
|
||||
for (int n = 0; n < MAX_VIDEO_SURFACES; n++) {
|
||||
struct surface_entry *e = &ctx->video_surfaces[n];
|
||||
if (!e->in_use && e->surface != VDP_INVALID_HANDLE) {
|
||||
if (e->chroma != chroma || e->w != w || e->h != h) {
|
||||
vdp_st = vdp->video_surface_destroy(e->surface);
|
||||
CHECK_VDP_WARNING(ctx, "Error when calling vdp_video_surface_destroy");
|
||||
e->surface = VDP_INVALID_HANDLE;
|
||||
if (!e->in_use && e->allocated) {
|
||||
if (e->w != w || e->h != h || e->rgb != rgb ||
|
||||
e->chroma != chroma || e->rgb_format != rgb_format)
|
||||
{
|
||||
if (e->rgb) {
|
||||
vdp_st = vdp->output_surface_destroy(e->osurface);
|
||||
} else {
|
||||
vdp_st = vdp->video_surface_destroy(e->surface);
|
||||
}
|
||||
CHECK_VDP_WARNING(ctx, "Error when destroying surface");
|
||||
e->surface = e->osurface = VDP_INVALID_HANDLE;
|
||||
e->allocated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,9 +230,11 @@ struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
// Try to find an existing unused surface
|
||||
for (int n = 0; n < MAX_VIDEO_SURFACES; n++) {
|
||||
struct surface_entry *e = &ctx->video_surfaces[n];
|
||||
if (!e->in_use && e->surface != VDP_INVALID_HANDLE) {
|
||||
if (!e->in_use && e->allocated) {
|
||||
assert(e->w == w && e->h == h);
|
||||
assert(e->chroma == chroma);
|
||||
assert(e->rgb_format == rgb_format);
|
||||
assert(e->rgb == rgb);
|
||||
surface_index = n;
|
||||
goto done;
|
||||
}
|
||||
@ -225,12 +245,23 @@ struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
struct surface_entry *e = &ctx->video_surfaces[n];
|
||||
if (!e->in_use) {
|
||||
assert(e->surface == VDP_INVALID_HANDLE);
|
||||
assert(e->osurface == VDP_INVALID_HANDLE);
|
||||
assert(!e->allocated);
|
||||
e->chroma = chroma;
|
||||
e->rgb_format = rgb_format;
|
||||
e->rgb = rgb;
|
||||
e->w = w;
|
||||
e->h = h;
|
||||
vdp_st = vdp->video_surface_create(ctx->vdp_device, chroma,
|
||||
w, h, &e->surface);
|
||||
CHECK_VDP_WARNING(ctx, "Error when calling vdp_video_surface_create");
|
||||
if (rgb) {
|
||||
vdp_st = vdp->output_surface_create(ctx->vdp_device, rgb_format,
|
||||
w, h, &e->osurface);
|
||||
e->allocated = e->osurface != VDP_INVALID_HANDLE;
|
||||
} else {
|
||||
vdp_st = vdp->video_surface_create(ctx->vdp_device, chroma,
|
||||
w, h, &e->surface);
|
||||
e->allocated = e->surface != VDP_INVALID_HANDLE;
|
||||
}
|
||||
CHECK_VDP_WARNING(ctx, "Error when allocating surface");
|
||||
surface_index = n;
|
||||
goto done;
|
||||
}
|
||||
@ -248,6 +279,12 @@ done: ;
|
||||
return mpi;
|
||||
}
|
||||
|
||||
struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
VdpChromaType chroma, int w, int h)
|
||||
{
|
||||
return mp_vdpau_get_surface(ctx, chroma, 0, false, w, h);
|
||||
}
|
||||
|
||||
struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log,
|
||||
struct vo_x11_state *x11)
|
||||
{
|
||||
@ -281,6 +318,10 @@ void mp_vdpau_destroy(struct mp_vdpau_ctx *ctx)
|
||||
vdp_st = vdp->video_surface_destroy(ctx->video_surfaces[i].surface);
|
||||
CHECK_VDP_WARNING(ctx, "Error when calling vdp_video_surface_destroy");
|
||||
}
|
||||
if (ctx->video_surfaces[i].osurface != VDP_INVALID_HANDLE) {
|
||||
vdp_st = vdp->output_surface_destroy(ctx->video_surfaces[i].osurface);
|
||||
CHECK_VDP_WARNING(ctx, "Error when calling vdp_output_surface_destroy");
|
||||
}
|
||||
}
|
||||
|
||||
if (vdp->device_destroy && ctx->vdp_device != VDP_INVALID_HANDLE) {
|
||||
@ -327,6 +368,22 @@ bool mp_vdpau_get_format(int imgfmt, VdpChromaType *out_chroma_type,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mp_vdpau_get_rgb_format(int imgfmt, VdpRGBAFormat *out_rgba_format)
|
||||
{
|
||||
VdpRGBAFormat format = (VdpRGBAFormat)-1;
|
||||
|
||||
switch (imgfmt) {
|
||||
case IMGFMT_BGR32:
|
||||
format = VDP_RGBA_FORMAT_B8G8R8A8; break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out_rgba_format)
|
||||
*out_rgba_format = format;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use mp_vdpau_get_video_surface, and upload mpi to it. Return NULL on failure.
|
||||
// If the image is already a vdpau video surface, just return a reference.
|
||||
struct mp_image *mp_vdpau_upload_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
@ -335,26 +392,36 @@ struct mp_image *mp_vdpau_upload_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
struct vdp_functions *vdp = &ctx->vdp;
|
||||
VdpStatus vdp_st;
|
||||
|
||||
if (mpi->imgfmt == IMGFMT_VDPAU)
|
||||
if (mpi->imgfmt == IMGFMT_VDPAU || mpi->imgfmt == IMGFMT_VDPAU_OUTPUT)
|
||||
return mp_image_new_ref(mpi);
|
||||
|
||||
VdpChromaType chroma_type;
|
||||
VdpYCbCrFormat pixel_format;
|
||||
if (!mp_vdpau_get_format(mpi->imgfmt, &chroma_type, &pixel_format))
|
||||
VdpChromaType chroma = (VdpChromaType)-1;
|
||||
VdpYCbCrFormat ycbcr = (VdpYCbCrFormat)-1;
|
||||
VdpRGBAFormat rgbafmt = (VdpRGBAFormat)-1;
|
||||
bool rgb = !mp_vdpau_get_format(mpi->imgfmt, &chroma, &ycbcr);
|
||||
if (rgb && !mp_vdpau_get_rgb_format(mpi->imgfmt, &rgbafmt))
|
||||
return NULL;
|
||||
|
||||
struct mp_image *hwmpi =
|
||||
mp_vdpau_get_video_surface(ctx, chroma_type, mpi->w, mpi->h);
|
||||
mp_vdpau_get_surface(ctx, chroma, rgbafmt, rgb, mpi->w, mpi->h);
|
||||
if (!hwmpi)
|
||||
return NULL;
|
||||
|
||||
VdpVideoSurface surface = (intptr_t)hwmpi->planes[3];
|
||||
const void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
|
||||
if (mpi->imgfmt == IMGFMT_NV12)
|
||||
destdata[1] = destdata[2];
|
||||
vdp_st = vdp->video_surface_put_bits_y_cb_cr(surface,
|
||||
pixel_format, destdata, mpi->stride);
|
||||
CHECK_VDP_WARNING(ctx, "Error when calling vdp_video_surface_put_bits_y_cb_cr");
|
||||
if (hwmpi->imgfmt == IMGFMT_VDPAU) {
|
||||
VdpVideoSurface surface = (intptr_t)hwmpi->planes[3];
|
||||
const void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
|
||||
if (mpi->imgfmt == IMGFMT_NV12)
|
||||
destdata[1] = destdata[2];
|
||||
vdp_st = vdp->video_surface_put_bits_y_cb_cr(surface,
|
||||
ycbcr, destdata, mpi->stride);
|
||||
} else {
|
||||
VdpOutputSurface rgb_surface = (intptr_t)hwmpi->planes[3];
|
||||
vdp_st = vdp->output_surface_put_bits_native(rgb_surface,
|
||||
&(const void *){mpi->planes[0]},
|
||||
&(uint32_t){mpi->stride[0]},
|
||||
NULL);
|
||||
}
|
||||
CHECK_VDP_WARNING(ctx, "Error when uploading surface");
|
||||
|
||||
mp_image_copy_attributes(hwmpi, mpi);
|
||||
return hwmpi;
|
||||
|
@ -58,8 +58,12 @@ struct mp_vdpau_ctx {
|
||||
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];
|
||||
};
|
||||
@ -75,6 +79,7 @@ struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user