diff --git a/sys/vdpau/gstvdp/Makefile.am b/sys/vdpau/gstvdp/Makefile.am index 44a0b9e956..c79ca55c0f 100644 --- a/sys/vdpau/gstvdp/Makefile.am +++ b/sys/vdpau/gstvdp/Makefile.am @@ -6,6 +6,7 @@ libgstvdp_@GST_MAJORMINOR@_la_SOURCES = \ gstvdpbuffer.c \ gstvdpbufferpool.c \ gstvdpvideobuffer.c \ + gstvdpvideobufferpool.c \ gstvdpoutputbuffer.c \ gstvdpvideosrcpad.c \ gstvdpoutputsrcpad.c \ @@ -19,6 +20,7 @@ libgstvdp_@GST_MAJORMINOR@include_HEADERS = \ gstvdpbuffer.h \ gstvdpbufferpool.h \ gstvdpvideobuffer.h \ + gstvdpvideobufferpool.h \ gstvdpoutputbuffer.h \ gstvdpvideosrcpad.h \ gstvdpoutputsrcpad.h \ diff --git a/sys/vdpau/gstvdp/gstvdpvideobuffer.c b/sys/vdpau/gstvdp/gstvdpvideobuffer.c index ff7fc5b947..1d1883cae1 100644 --- a/sys/vdpau/gstvdp/gstvdpvideobuffer.c +++ b/sys/vdpau/gstvdp/gstvdpvideobuffer.c @@ -32,19 +32,19 @@ GST_DEBUG_CATEGORY_INIT (gst_vdp_video_buffer_debug, "vdpvideobuffer", 0, "VDPAU GstVdpVideoBuffer * gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, - gint width, gint height) + gint width, gint height, GError ** error) { GstVdpVideoBuffer *buffer; VdpStatus status; VdpVideoSurface surface; + g_return_val_if_fail (GST_IS_VDP_DEVICE (device), NULL); + + status = device->vdp_video_surface_create (device->device, chroma_type, width, height, &surface); - if (status != VDP_STATUS_OK) { - GST_ERROR ("Couldn't create a VdpVideoSurface, error returned was: %s", - device->vdp_get_error_string (status)); - return NULL; - } + if (status != VDP_STATUS_OK) + goto create_error; buffer = (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDP_VIDEO_BUFFER); @@ -53,6 +53,12 @@ gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, buffer->surface = surface; return buffer; + +create_error: + g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ, + "Couldn't create a VdpVideoSurface, error returned from vdpau was: %s", + device->vdp_get_error_string (status)); + return NULL; } static GObjectClass *gst_vdp_video_buffer_parent_class; @@ -63,6 +69,9 @@ gst_vdp_video_buffer_finalize (GstVdpVideoBuffer * buffer) GstVdpDevice *device; VdpStatus status; + if (gst_vdp_buffer_revive (GST_VDP_BUFFER_CAST (buffer))) + return; + device = buffer->device; status = device->vdp_video_surface_destroy (buffer->surface); @@ -114,7 +123,7 @@ gst_vdp_video_buffer_get_type (void) (GInstanceInitFunc) gst_vdp_video_buffer_init, NULL }; - _gst_vdp_video_buffer_type = g_type_register_static (GST_TYPE_BUFFER, + _gst_vdp_video_buffer_type = g_type_register_static (GST_TYPE_VDP_BUFFER, "GstVdpVideoBuffer", &info, 0); } return _gst_vdp_video_buffer_type; diff --git a/sys/vdpau/gstvdp/gstvdpvideobuffer.h b/sys/vdpau/gstvdp/gstvdpvideobuffer.h index 4d14d8c53c..0699e73c9f 100644 --- a/sys/vdpau/gstvdp/gstvdpvideobuffer.h +++ b/sys/vdpau/gstvdp/gstvdpvideobuffer.h @@ -24,10 +24,9 @@ #include #include +#include "gstvdpbuffer.h" #include "gstvdpdevice.h" -#include "gstvdpvideobuffer.h" - typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; #define GST_TYPE_VDP_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) @@ -36,7 +35,7 @@ typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; #define GST_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER, GstVdpVideoBuffer)) struct _GstVdpVideoBuffer { - GstBuffer buffer; + GstVdpBuffer vdp_buffer; GstVdpDevice *device; VdpVideoSurface surface; @@ -92,8 +91,7 @@ static const GstVdpVideoBufferFormats formats[] = { GType gst_vdp_video_buffer_get_type (void); -GstVdpVideoBuffer* gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height); -void gst_vdp_video_buffer_add_reference (GstVdpVideoBuffer *buffer, GstVdpVideoBuffer *buf); +GstVdpVideoBuffer *gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height, GError **error); GstCaps *gst_vdp_video_buffer_get_caps (gboolean filter, VdpChromaType chroma_type); GstCaps *gst_vdp_video_buffer_get_allowed_caps (GstVdpDevice * device); diff --git a/sys/vdpau/gstvdp/gstvdpvideobufferpool.c b/sys/vdpau/gstvdp/gstvdpvideobufferpool.c new file mode 100644 index 0000000000..889367d987 --- /dev/null +++ b/sys/vdpau/gstvdp/gstvdpvideobufferpool.c @@ -0,0 +1,146 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * gst-plugins-bad + * Copyright (C) Carl-Anton Ingmarsson 2010 + * + * gst-plugins-bad is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gst-plugins-bad is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "gstvdpdevice.h" +#include "gstvdpvideobuffer.h" + +#include "gstvdpvideobufferpool.h" + + +struct _GstVdpVideoBufferPool +{ + GstVdpBufferPool buffer_pool; + + VdpChromaType chroma_type; + guint width, height; +}; + +G_DEFINE_TYPE (GstVdpVideoBufferPool, gst_vdp_video_buffer_pool, + GST_TYPE_VDP_BUFFER_POOL); + +GstVdpBufferPool * +gst_vdp_video_buffer_pool_new (GstVdpDevice * device) +{ + g_return_val_if_fail (GST_IS_VDP_DEVICE (device), NULL); + + return g_object_new (GST_TYPE_VDP_VIDEO_BUFFER_POOL, "device", device, NULL); +} + +static gboolean +parse_caps (const GstCaps * caps, VdpChromaType * chroma_type, gint * width, + gint * height) +{ + GstStructure *structure; + + structure = gst_caps_get_structure (caps, 0); + + if (!gst_structure_get_int (structure, "chroma-type", (gint *) chroma_type)) + return FALSE; + if (!gst_structure_get_int (structure, "width", width)) + return FALSE; + if (!gst_structure_get_int (structure, "height", height)) + return FALSE; + + return TRUE; +} + +static gboolean +gst_vdp_video_buffer_pool_check_caps (GstVdpBufferPool * bpool, + const GstCaps * caps) +{ + GstVdpVideoBufferPool *vpool = GST_VDP_VIDEO_BUFFER_POOL (bpool); + + VdpChromaType chroma_type; + gint width, height; + + if (!parse_caps (caps, &chroma_type, &width, &height)) + return FALSE; + + if (chroma_type != vpool->chroma_type || width != vpool->width || + height != vpool->height) + return FALSE; + + return TRUE; +} + +static gboolean +gst_vdp_video_buffer_pool_set_caps (GstVdpBufferPool * bpool, + const GstCaps * caps, gboolean * clear_bufs) +{ + GstVdpVideoBufferPool *vpool = GST_VDP_VIDEO_BUFFER_POOL (bpool); + + VdpChromaType chroma_type; + gint width, height; + + if (!parse_caps (caps, &chroma_type, &width, &height)) + return FALSE; + + if (chroma_type != vpool->chroma_type || width != vpool->width || + height != vpool->height) + *clear_bufs = TRUE; + else + *clear_bufs = FALSE; + + vpool->chroma_type = chroma_type; + vpool->width = width; + vpool->height = height; + + return TRUE; +} + +static GstVdpBuffer * +gst_vdp_video_buffer_pool_alloc_buffer (GstVdpBufferPool * bpool, + GError ** error) +{ + GstVdpVideoBufferPool *vpool = GST_VDP_VIDEO_BUFFER_POOL (bpool); + GstVdpDevice *device; + + device = gst_vdp_buffer_pool_get_device (bpool); + return GST_VDP_BUFFER_CAST (gst_vdp_video_buffer_new (device, + vpool->chroma_type, vpool->width, vpool->height, error)); +} + +static void +gst_vdp_video_buffer_pool_finalize (GObject * object) +{ + /* TODO: Add deinitalization code here */ + + G_OBJECT_CLASS (gst_vdp_video_buffer_pool_parent_class)->finalize (object); +} + +static void +gst_vdp_video_buffer_pool_init (GstVdpVideoBufferPool * vpool) +{ + vpool->chroma_type = -1; + vpool->width = 0; + vpool->height = 0; +} + +static void +gst_vdp_video_buffer_pool_class_init (GstVdpVideoBufferPoolClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstVdpBufferPoolClass *buffer_pool_class = GST_VDP_BUFFER_POOL_CLASS (klass); + + buffer_pool_class->alloc_buffer = gst_vdp_video_buffer_pool_alloc_buffer; + buffer_pool_class->set_caps = gst_vdp_video_buffer_pool_set_caps; + buffer_pool_class->check_caps = gst_vdp_video_buffer_pool_check_caps; + + object_class->finalize = gst_vdp_video_buffer_pool_finalize; +} diff --git a/sys/vdpau/gstvdp/gstvdpvideobufferpool.h b/sys/vdpau/gstvdp/gstvdpvideobufferpool.h new file mode 100644 index 0000000000..e22e9b939c --- /dev/null +++ b/sys/vdpau/gstvdp/gstvdpvideobufferpool.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * gst-plugins-bad + * Copyright (C) Carl-Anton Ingmarsson 2010 + * + * gst-plugins-bad is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gst-plugins-bad is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef _GST_VDP_VIDEO_BUFFERPOOL_H_ +#define _GST_VDP_VIDEO_BUFFERPOOL_H_ + +#include + +#include "gstvdpbufferpool.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDP_VIDEO_BUFFER_POOL (gst_vdp_video_buffer_pool_get_type ()) +#define GST_VDP_VIDEO_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPool)) +#define GST_VDP_VIDEO_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPoolClass)) +#define GST_IS_VDP_VIDEO_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL)) +#define GST_IS_VDP_VIDEO_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_VIDEO_BUFFER_POOL)) +#define GST_VDP_VIDEO_BUFFER_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPoolClass)) + +typedef struct _GstVdpVideoBufferPool GstVdpVideoBufferPool; +typedef struct _GstVdpVideoBufferPoolClass GstVdpVideoBufferPoolClass; + +struct _GstVdpVideoBufferPoolClass +{ + GstVdpBufferPoolClass buffer_pool_class; +}; + +GstVdpBufferPool *gst_vdp_video_buffer_pool_new (GstVdpDevice *device); + +GType gst_vdp_video_buffer_pool_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* _GST_VDP_VIDEO_BUFFER_POOL_H_ */ diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c index db2f7d9f7a..7c8444b8de 100644 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c +++ b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c @@ -182,7 +182,7 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad, GstVdpDevice *device = vdp_pad->device; *video_buf = gst_vdp_video_buffer_new (device, VDP_CHROMA_TYPE_420, - vdp_pad->width, vdp_pad->height); + vdp_pad->width, vdp_pad->height, NULL); if (!*video_buf) goto video_buf_error; diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c index 0b739b3a3d..e77b41dd6a 100644 --- a/sys/vdpau/gstvdpvideopostprocess.c +++ b/sys/vdpau/gstvdpvideopostprocess.c @@ -791,7 +791,7 @@ no_qos: GstVdpVideoBuffer *video_buf; video_buf = gst_vdp_video_buffer_new (vpp->device, vpp->chroma_type, - vpp->width, vpp->height); + vpp->width, vpp->height, NULL); if (G_UNLIKELY (!video_buf)) goto video_buf_error; @@ -884,7 +884,7 @@ gst_vdp_vpp_sink_bufferalloc (GstPad * pad, guint64 offset, guint size, *buf = GST_BUFFER (gst_vdp_video_buffer_new (vpp->device, chroma_type, width, - height)); + height, NULL)); if (*buf == NULL) goto video_buffer_error;