[vlc-commits] vdpau: video surface picture copy
Rémi Denis-Courmont
git at videolan.org
Sun Jul 7 20:13:41 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jun 25 22:16:01 2013 +0300| [dd638a1a6002a177ec8f492cb87e9ec88aede946] | committer: Rémi Denis-Courmont
vdpau: video surface picture copy
This will be used for deinterlacing.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=dd638a1a6002a177ec8f492cb87e9ec88aede946
---
modules/hw/vdpau/chroma.c | 13 ++++++----
modules/hw/vdpau/picture.c | 56 +++++++++++++++++++++++++++++++++---------
modules/hw/vdpau/vlc_vdpau.h | 18 +++++++++++---
3 files changed, 68 insertions(+), 19 deletions(-)
diff --git a/modules/hw/vdpau/chroma.c b/modules/hw/vdpau/chroma.c
index bd7e512..99e9b61 100644
--- a/modules/hw/vdpau/chroma.c
+++ b/modules/hw/vdpau/chroma.c
@@ -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)
diff --git a/modules/hw/vdpau/picture.c b/modules/hw/vdpau/picture.c
index bcd4fd2..37dce53 100644
--- a/modules/hw/vdpau/picture.c
+++ b/modules/hw/vdpau/picture.c
@@ -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;
}
diff --git a/modules/hw/vdpau/vlc_vdpau.h b/modules/hw/vdpau/vlc_vdpau.h
index a1499fc..f792298 100644
--- a/modules/hw/vdpau/vlc_vdpau.h
+++ b/modules/hw/vdpau/vlc_vdpau.h
@@ -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
More information about the vlc-commits
mailing list