Commit dd638a1a authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

vdpau: video surface picture copy

This will be used for deinterlacing.
parent 65b88181
......@@ -125,7 +125,8 @@ error:
static picture_t *VideoExport(filter_t *filter, picture_t *src, picture_t *dst)
{
filter_sys_t *sys = filter->p_sys;
vlc_vdp_video_t *psys = src->context;
vlc_vdp_video_field_t *field = src->context;
vlc_vdp_video_frame_t *psys = field->frame;
VdpStatus err;
VdpVideoSurface surface = psys->surface;
void *planes[3];
......@@ -228,14 +229,16 @@ error:
static picture_t *VideoPassthrough(filter_t *filter, picture_t *src)
{
filter_sys_t *sys = filter->p_sys;
vlc_vdp_video_t *psys = src->context;
vlc_vdp_video_field_t *field = src->context;
if (unlikely(psys == NULL))
if (unlikely(field == NULL))
{
msg_Err(filter, "corrupt VDPAU video surface");
return NULL;
}
vlc_vdp_video_frame_t *psys = field->frame;
/* Corner case: different VDPAU instances decoding and rendering */
if (psys->vdp != sys->vdp)
{
......@@ -258,8 +261,8 @@ static picture_t *VideoPassthrough(filter_t *filter, picture_t *src)
static inline VdpVideoSurface picture_GetVideoSurface(const picture_t *pic)
{
vlc_vdp_video_t *psys = pic->context;
return psys->surface;
vlc_vdp_video_field_t *field = pic->context;
return field->frame->surface;
}
static picture_t *MixerRender(filter_t *filter, picture_t *src)
......
......@@ -33,31 +33,65 @@
static void SurfaceDestroy(void *opaque)
{
vlc_vdp_video_t *ctx = opaque;
vlc_vdp_video_field_t *field = opaque;
vlc_vdp_video_frame_t *frame = field->frame;
VdpStatus err;
err = vdp_video_surface_destroy(ctx->vdp, ctx->surface);
/* Destroy field-specific infos */
free(field);
if (atomic_fetch_sub(&frame->refs, 1) != 1)
return;
/* Destroy frame (video surface) */
err = vdp_video_surface_destroy(frame->vdp, frame->surface);
if (err != VDP_STATUS_OK)
fprintf(stderr, "video surface destruction failure: %s\n",
vdp_get_error_string(ctx->vdp, err));
vdp_release_x11(ctx->vdp);
free(ctx);
vdp_get_error_string(frame->vdp, err));
vdp_release_x11(frame->vdp);
free(frame);
}
VdpStatus vlc_vdp_video_attach(vdp_t *vdp, VdpVideoSurface surface,
picture_t *pic)
{
vlc_vdp_video_t *ctx = malloc(sizeof (*ctx));
if (unlikely(ctx == NULL))
vlc_vdp_video_field_t *field = malloc(sizeof (*field));
vlc_vdp_video_frame_t *frame = malloc(sizeof (*frame));
if (unlikely(field == NULL || frame == NULL))
{
free(frame);
free(field);
vdp_video_surface_destroy(vdp, surface);
return VDP_STATUS_RESOURCES;
}
ctx->destroy = SurfaceDestroy;
ctx->surface = surface;
ctx->vdp = vdp_hold_x11(vdp, &ctx->device);
assert(pic->context == NULL);
pic->context = ctx;
pic->context = field;
field->destroy = SurfaceDestroy;
field->frame = frame;
atomic_init(&frame->refs, 1);
frame->surface = surface;
frame->vdp = vdp_hold_x11(vdp, &frame->device);
return VDP_STATUS_OK;
}
VdpStatus vlc_vdp_video_copy(picture_t *restrict dst, picture_t *restrict src)
{
vlc_vdp_video_field_t *fold = src->context;
vlc_vdp_video_frame_t *frame = fold->frame;
vlc_vdp_video_field_t *fnew = malloc(sizeof (*fnew));
if (unlikely(fnew == NULL))
return VDP_STATUS_RESOURCES;
assert(dst->context == NULL);
dst->context = fnew;
fnew->destroy = SurfaceDestroy;
fnew->frame = frame;
atomic_fetch_add(&frame->refs, 1);
return VDP_STATUS_OK;
}
......@@ -207,6 +207,7 @@ void vdp_release_x11(vdp_t *);
# include <stdbool.h>
# include <vlc_common.h>
# include <vlc_fourcc.h>
# include <vlc_atomic.h>
/** Converts VLC YUV format to VDPAU chroma type and YCbCr format */
static inline
......@@ -245,13 +246,19 @@ struct picture_sys_t
vdp_t *vdp;
};
typedef struct vlc_vdp_video
typedef struct vlc_vdp_video_frame
{
void (*destroy)(void *); /* must be first @ref picture_Release() */
VdpVideoSurface surface;
VdpDevice device;
vdp_t *vdp;
} vlc_vdp_video_t;
atomic_uintptr_t refs;
} vlc_vdp_video_frame_t;
typedef struct vlc_vdp_video_field
{
void (*destroy)(void *); /* must be first @ref picture_Release() */
vlc_vdp_video_frame_t *frame;
} vlc_vdp_video_field_t;
/**
* Attaches a VDPAU video surface as context of a VLC picture.
......@@ -259,4 +266,9 @@ typedef struct vlc_vdp_video
* it will be destroyed at the same time as the picture it was attached to.
*/
VdpStatus vlc_vdp_video_attach(vdp_t *, VdpVideoSurface, picture_t *);
/**
* Copies the VDPAU video surface from a VLC picture into another VLC picture.
*/
VdpStatus vlc_vdp_video_copy(picture_t *dst, picture_t *src);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment