mirror of https://github.com/mpv-player/mpv
vaapi: make struct va_surface private
It's not really needed to be public. Other code can just use mp_image. The only disadvantage is that the other code needs to call an accessor to get the VASurfaceID.
This commit is contained in:
parent
31fc5e8563
commit
49d13f76ca
|
@ -170,7 +170,7 @@ static bool preallocate_surfaces(struct lavc_ctx *ctx, int num, int w, int h,
|
|||
|
||||
for (int n = 0; n < num; n++) {
|
||||
reserve[n] = mp_image_pool_get(p->pool, IMGFMT_VAAPI, w, h);
|
||||
out_surfaces[n] = va_surface_id_in_mp_image(reserve[n]);
|
||||
out_surfaces[n] = va_surface_id(reserve[n]);
|
||||
if (out_surfaces[n] == VA_INVALID_ID) {
|
||||
MP_ERR(p, "Could not allocate surfaces.\n");
|
||||
res = false;
|
||||
|
@ -433,9 +433,7 @@ static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img)
|
|||
{
|
||||
struct priv *p = ctx->hwdec_priv;
|
||||
|
||||
struct va_surface *surface = va_surface_in_mp_image(img);
|
||||
if (surface) {
|
||||
struct mp_image *simg = va_surface_download(surface, p->sw_pool);
|
||||
struct mp_image *simg = va_surface_download(img, p->sw_pool);
|
||||
if (simg) {
|
||||
if (!p->printed_readback_warning) {
|
||||
MP_WARN(p, "Using GPU readback. This is usually inefficient.\n");
|
||||
|
@ -444,7 +442,6 @@ static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img)
|
|||
talloc_free(img);
|
||||
return simg;
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,11 +123,12 @@ static inline int get_deint_field(struct vf_priv_s *p, int i,
|
|||
return !!(mpi->fields & MP_IMGFIELD_TOP_FIRST) ^ i ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
|
||||
}
|
||||
|
||||
static struct mp_image *render(struct vf_instance *vf, struct va_surface *in,
|
||||
static struct mp_image *render(struct vf_instance *vf, struct mp_image *in,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct vf_priv_s *p = vf->priv;
|
||||
if (!p->pipe.filters || !in)
|
||||
VASurfaceID in_id = va_surface_id(in);
|
||||
if (!p->pipe.filters || in_id == VA_INVALID_ID)
|
||||
return NULL;
|
||||
struct mp_image *img = mp_image_pool_get(p->pool, IMGFMT_VAAPI, in->w, in->h);
|
||||
if (!img)
|
||||
|
@ -135,7 +136,7 @@ static struct mp_image *render(struct vf_instance *vf, struct va_surface *in,
|
|||
enum {Begun = 1, Rendered = 2};
|
||||
int state = 0;
|
||||
do { // not a loop, just for break
|
||||
VASurfaceID id = va_surface_id_in_mp_image(img);
|
||||
VASurfaceID id = va_surface_id(img);
|
||||
if (id == VA_INVALID_ID)
|
||||
break;
|
||||
VAStatus status = vaBeginPicture(p->display, p->context, id);
|
||||
|
@ -152,7 +153,7 @@ static struct mp_image *render(struct vf_instance *vf, struct va_surface *in,
|
|||
status = vaMapBuffer(p->display, buffer, (void**)¶m);
|
||||
if (!check_error(vf, status, "vaMapBuffer()"))
|
||||
break;
|
||||
param->surface = in->id;
|
||||
param->surface = in_id;
|
||||
param->surface_region = NULL;
|
||||
param->output_region = NULL;
|
||||
param->output_background_color = 0;
|
||||
|
@ -185,10 +186,9 @@ static int process(struct vf_instance *vf, struct mp_image *in,
|
|||
const bool deint = p->do_deint && p->deint_type > 0;
|
||||
if (!update_pipeline(vf, deint) || !p->pipe.filters) // no filtering
|
||||
return 0;
|
||||
struct va_surface *surface = va_surface_in_mp_image(in);
|
||||
const unsigned int csp = va_get_colorspace_flag(p->params.colorspace);
|
||||
const unsigned int field = get_deint_field(p, 0, in);
|
||||
*out1 = render(vf, surface, field | csp);
|
||||
*out1 = render(vf, in, field | csp);
|
||||
if (!*out1) // cannot render
|
||||
return 0;
|
||||
mp_image_copy_attributes(*out1, in);
|
||||
|
@ -197,7 +197,7 @@ static int process(struct vf_instance *vf, struct mp_image *in,
|
|||
const double add = (in->pts - p->prev_pts)*0.5;
|
||||
if (p->prev_pts == MP_NOPTS_VALUE || add <= 0.0 || add > 0.5) // no pts, skip it
|
||||
return 1;
|
||||
*out2 = render(vf, surface, get_deint_field(p, 1, in) | csp);
|
||||
*out2 = render(vf, in, get_deint_field(p, 1, in) | csp);
|
||||
if (!*out2) // cannot render
|
||||
return 1;
|
||||
mp_image_copy_attributes(*out2, in);
|
||||
|
@ -211,7 +211,7 @@ static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in)
|
|||
struct mp_image *out = mp_image_pool_get(p->pool, IMGFMT_VAAPI, in->w, in->h);
|
||||
if (!out)
|
||||
return NULL;
|
||||
if (va_surface_upload_image(out, in) < 0) {
|
||||
if (va_surface_upload(out, in) < 0) {
|
||||
talloc_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -222,15 +222,15 @@ static struct mp_image *upload(struct vf_instance *vf, struct mp_image *in)
|
|||
static int filter_ext(struct vf_instance *vf, struct mp_image *in)
|
||||
{
|
||||
struct vf_priv_s *p = vf->priv;
|
||||
struct va_surface *surface = va_surface_in_mp_image(in);
|
||||
const int rt_format = surface ? surface->rt_format : VA_RT_FORMAT_YUV420;
|
||||
int rt_format = in->imgfmt == IMGFMT_VAAPI ? va_surface_rt_format(in)
|
||||
: VA_RT_FORMAT_YUV420;
|
||||
if (!p->pool || p->current_rt_format != rt_format) {
|
||||
talloc_free(p->pool);
|
||||
p->pool = mp_image_pool_new(20);
|
||||
va_pool_set_allocator(p->pool, p->va, rt_format);
|
||||
p->current_rt_format = rt_format;
|
||||
}
|
||||
if (!surface) {
|
||||
if (in->imgfmt != IMGFMT_VAAPI) {
|
||||
struct mp_image *tmp = upload(vf, in);
|
||||
talloc_free(in);
|
||||
in = tmp;
|
||||
|
|
|
@ -113,7 +113,7 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image,
|
|||
return -1;
|
||||
|
||||
status = vaCopySurfaceGLX(p->display, p->vaglx_surface,
|
||||
va_surface_id_in_mp_image(hw_image),
|
||||
va_surface_id(hw_image),
|
||||
va_get_colorspace_flag(hw_image->colorspace));
|
||||
if (!CHECK_VA_STATUS(p, "vaCopySurfaceGLX()"))
|
||||
return -1;
|
||||
|
|
|
@ -137,7 +137,7 @@ static bool alloc_swdec_surfaces(struct priv *p, int w, int h, int imgfmt)
|
|||
free_video_specific(p);
|
||||
for (int i = 0; i < MAX_OUTPUT_SURFACES; i++) {
|
||||
p->swdec_surfaces[i] = mp_image_pool_get(p->pool, IMGFMT_VAAPI, w, h);
|
||||
if (va_surface_image_alloc_imgfmt(p->swdec_surfaces[i], imgfmt) < 0)
|
||||
if (va_surface_alloc_imgfmt(p->swdec_surfaces[i], imgfmt) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -184,7 +184,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi)
|
|||
{
|
||||
VAStatus status;
|
||||
|
||||
VASurfaceID surface = va_surface_id_in_mp_image(mpi);
|
||||
VASurfaceID surface = va_surface_id(mpi);
|
||||
if (surface == VA_INVALID_ID) {
|
||||
if (!p->black_surface) {
|
||||
int w = p->image_params.w, h = p->image_params.h;
|
||||
|
@ -194,12 +194,12 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi)
|
|||
if (p->black_surface) {
|
||||
struct mp_image *img = mp_image_alloc(fmt, w, h);
|
||||
mp_image_clear(img, 0, 0, w, h);
|
||||
if (va_surface_upload_image(p->black_surface, img) < 0)
|
||||
if (va_surface_upload(p->black_surface, img) < 0)
|
||||
mp_image_unrefp(&p->black_surface);
|
||||
talloc_free(img);
|
||||
}
|
||||
}
|
||||
surface = va_surface_id_in_mp_image(p->black_surface);
|
||||
surface = va_surface_id(p->black_surface);
|
||||
}
|
||||
|
||||
int fields = mpi ? mpi->fields : 0;
|
||||
|
@ -273,7 +273,7 @@ static void draw_image(struct vo *vo, struct mp_image *mpi)
|
|||
|
||||
if (mpi->imgfmt != IMGFMT_VAAPI) {
|
||||
struct mp_image *dst = p->swdec_surfaces[p->output_surface];
|
||||
if (!dst || va_surface_upload_image(dst, mpi) < 0) {
|
||||
if (!dst || va_surface_upload(dst, mpi) < 0) {
|
||||
MP_WARN(vo, "Could not upload surface.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -286,11 +286,10 @@ static void draw_image(struct vo *vo, struct mp_image *mpi)
|
|||
|
||||
static struct mp_image *get_screenshot(struct priv *p)
|
||||
{
|
||||
struct va_surface *surface =
|
||||
va_surface_in_mp_image(p->output_surfaces[p->visible_surface]);
|
||||
if (!surface)
|
||||
struct mp_image *hwimg = p->output_surfaces[p->visible_surface];
|
||||
if (!hwimg)
|
||||
return NULL;
|
||||
struct mp_image *img = va_surface_download(surface, NULL);
|
||||
struct mp_image *img = va_surface_download(hwimg, NULL);
|
||||
if (!img)
|
||||
return NULL;
|
||||
struct mp_image_params params = p->image_params;
|
||||
|
|
|
@ -159,6 +159,13 @@ VAImageFormat *va_image_format_from_imgfmt(const struct va_image_formats *format
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct va_surface {
|
||||
VASurfaceID id; // VA_INVALID_ID if unallocated
|
||||
int w, h, rt_format; // parameters of allocated image (0/0/-1 unallocated)
|
||||
|
||||
struct va_surface_priv *p;
|
||||
};
|
||||
|
||||
typedef struct va_surface_priv {
|
||||
struct mp_vaapi_ctx *ctx;
|
||||
VADisplay display;
|
||||
|
@ -166,6 +173,24 @@ typedef struct va_surface_priv {
|
|||
bool is_derived; // is image derived by vaDeriveImage()?
|
||||
} va_surface_priv_t;
|
||||
|
||||
VASurfaceID va_surface_id(struct mp_image *mpi)
|
||||
{
|
||||
return mpi && mpi->imgfmt == IMGFMT_VAAPI ?
|
||||
(VASurfaceID)(uintptr_t)mpi->planes[3] : VA_INVALID_ID;
|
||||
}
|
||||
|
||||
static struct va_surface *va_surface_in_mp_image(struct mp_image *mpi)
|
||||
{
|
||||
return mpi && mpi->imgfmt == IMGFMT_VAAPI ?
|
||||
(struct va_surface*)mpi->planes[0] : NULL;
|
||||
}
|
||||
|
||||
int va_surface_rt_format(struct mp_image *mpi)
|
||||
{
|
||||
struct va_surface *surface = va_surface_in_mp_image(mpi);
|
||||
return surface ? surface->rt_format : 0;
|
||||
}
|
||||
|
||||
static void va_surface_destroy(struct va_surface *surface)
|
||||
{
|
||||
if (!surface)
|
||||
|
@ -262,7 +287,7 @@ static VAImage *va_surface_image_alloc(struct va_surface *surface,
|
|||
|
||||
// img must be a VAAPI surface; make sure its internal VAImage is allocated
|
||||
// to a format corresponding to imgfmt (or return an error).
|
||||
int va_surface_image_alloc_imgfmt(struct mp_image *img, int imgfmt)
|
||||
int va_surface_alloc_imgfmt(struct mp_image *img, int imgfmt)
|
||||
{
|
||||
struct va_surface *surface = va_surface_in_mp_image(img);
|
||||
if (!surface)
|
||||
|
@ -276,23 +301,6 @@ int va_surface_image_alloc_imgfmt(struct mp_image *img, int imgfmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
VASurfaceID va_surface_id_in_mp_image(const struct mp_image *mpi)
|
||||
{
|
||||
return mpi && mpi->imgfmt == IMGFMT_VAAPI ?
|
||||
(VASurfaceID)(uintptr_t)mpi->planes[3] : VA_INVALID_ID;
|
||||
}
|
||||
|
||||
struct va_surface *va_surface_in_mp_image(struct mp_image *mpi)
|
||||
{
|
||||
return mpi && mpi->imgfmt == IMGFMT_VAAPI ?
|
||||
(struct va_surface*)mpi->planes[0] : NULL;
|
||||
}
|
||||
|
||||
VASurfaceID va_surface_id(const struct va_surface *surface)
|
||||
{
|
||||
return surface ? surface->id : VA_INVALID_ID;
|
||||
}
|
||||
|
||||
bool va_image_map(struct mp_vaapi_ctx *ctx, VAImage *image, struct mp_image *mpi)
|
||||
{
|
||||
int imgfmt = va_fourcc_to_imgfmt(image->format.fourcc);
|
||||
|
@ -326,44 +334,37 @@ bool va_image_unmap(struct mp_vaapi_ctx *ctx, VAImage *image)
|
|||
return CHECK_VA_STATUS(ctx, "vaUnmapBuffer()");
|
||||
}
|
||||
|
||||
bool va_surface_upload(struct va_surface *surface, struct mp_image *mpi)
|
||||
// va_dst: copy destination, must be IMGFMT_VAAPI
|
||||
// sw_src: copy source, must be a software surface
|
||||
int va_surface_upload(struct mp_image *va_dst, struct mp_image *sw_src)
|
||||
{
|
||||
struct va_surface *surface = va_surface_in_mp_image(va_dst);
|
||||
if (!surface)
|
||||
return -1;
|
||||
va_surface_priv_t *p = surface->p;
|
||||
|
||||
VAImageFormat *format =
|
||||
va_image_format_from_imgfmt(p->ctx->image_formats, mpi->imgfmt);
|
||||
va_image_format_from_imgfmt(p->ctx->image_formats, sw_src->imgfmt);
|
||||
if (!format)
|
||||
return false;
|
||||
return -1;
|
||||
if (!va_surface_image_alloc(surface, format))
|
||||
return false;
|
||||
return -1;
|
||||
|
||||
struct mp_image img;
|
||||
if (!va_image_map(p->ctx, &p->image, &img))
|
||||
return false;
|
||||
mp_image_copy(&img, mpi);
|
||||
return -1;
|
||||
mp_image_copy(&img, sw_src);
|
||||
va_image_unmap(p->ctx, &p->image);
|
||||
|
||||
if (!p->is_derived) {
|
||||
VAStatus status = vaPutImage2(p->display, surface->id,
|
||||
p->image.image_id,
|
||||
0, 0, mpi->w, mpi->h,
|
||||
0, 0, mpi->w, mpi->h);
|
||||
0, 0, sw_src->w, sw_src->h,
|
||||
0, 0, sw_src->w, sw_src->h);
|
||||
if (!CHECK_VA_STATUS(p->ctx, "vaPutImage()"))
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// va_dst: copy destination, must be IMGFMT_VAAPI
|
||||
// sw_src: copy source, must be a software surface
|
||||
int va_surface_upload_image(struct mp_image *va_dst, struct mp_image *sw_src)
|
||||
{
|
||||
struct va_surface *surface = va_surface_in_mp_image(va_dst);
|
||||
if (!surface)
|
||||
return -1;
|
||||
if (!va_surface_upload(surface, sw_src))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -402,11 +403,12 @@ static struct mp_image *try_download(struct va_surface *surface,
|
|||
}
|
||||
|
||||
// pool is optional (used for allocating returned images).
|
||||
// Note: unlike va_surface_upload(), this will attempt to (re)create the
|
||||
// VAImage stored with the va_surface.
|
||||
struct mp_image *va_surface_download(struct va_surface *surface,
|
||||
struct mp_image *va_surface_download(struct mp_image *src,
|
||||
struct mp_image_pool *pool)
|
||||
{
|
||||
struct va_surface *surface = va_surface_in_mp_image(src);
|
||||
if (!surface)
|
||||
return NULL;
|
||||
struct mp_vaapi_ctx *ctx = surface->p->ctx;
|
||||
VAStatus status = vaSyncSurface(surface->p->display, surface->id);
|
||||
if (!CHECK_VA_STATUS(ctx, "vaSyncSurface()"))
|
||||
|
|
|
@ -81,16 +81,8 @@ struct mp_vaapi_ctx {
|
|||
struct va_image_formats *image_formats;
|
||||
};
|
||||
|
||||
struct va_surface_pool;
|
||||
struct va_image_formats;
|
||||
|
||||
struct va_surface {
|
||||
VASurfaceID id; // VA_INVALID_ID if unallocated
|
||||
int w, h, rt_format; // parameters of allocated image (0/0/-1 unallocated)
|
||||
|
||||
struct va_surface_priv *p;
|
||||
};
|
||||
|
||||
bool check_va_status(struct mp_log *log, VAStatus status, const char *msg);
|
||||
|
||||
#define CHECK_VA_STATUS(ctx, msg) check_va_status((ctx)->log, status, msg)
|
||||
|
@ -109,14 +101,12 @@ bool va_image_unmap(struct mp_vaapi_ctx *ctx, VAImage *image
|
|||
void va_pool_set_allocator(struct mp_image_pool *pool, struct mp_vaapi_ctx *ctx,
|
||||
int rt_format);
|
||||
|
||||
struct va_surface * va_surface_in_mp_image(struct mp_image *mpi);
|
||||
VASurfaceID va_surface_id(const struct va_surface *surface);
|
||||
VASurfaceID va_surface_id_in_mp_image(const struct mp_image *mpi);
|
||||
bool va_surface_upload(struct va_surface *surface, struct mp_image *mpi);
|
||||
struct mp_image * va_surface_download(struct va_surface *surface,
|
||||
VASurfaceID va_surface_id(struct mp_image *mpi);
|
||||
int va_surface_rt_format(struct mp_image *mpi);
|
||||
struct mp_image *va_surface_download(struct mp_image *src,
|
||||
struct mp_image_pool *pool);
|
||||
|
||||
int va_surface_image_alloc_imgfmt(struct mp_image *img, int imgfmt);
|
||||
int va_surface_upload_image(struct mp_image *va_dst, struct mp_image *sw_src);
|
||||
int va_surface_alloc_imgfmt(struct mp_image *img, int imgfmt);
|
||||
int va_surface_upload(struct mp_image *va_dst, struct mp_image *sw_src);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue