diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2010-07-30 11:27:27 +0200 |
---|---|---|
committer | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2010-07-30 11:33:13 +0200 |
commit | aa193a7b4391f98367c9d0f27b220cdd6bcb8db7 (patch) | |
tree | 290342e09f07c2f587ff5fbad9e7a1e03bafb15c /sys/vdpau | |
parent | 57175ece9e629520c89112571bcea8c99b3cd581 (diff) |
vdpauvideopostprocess: use GstVdp[Video|Output]BufferPool to cache our buffers
This way we'll reuse the GstVdp[Video|Output]Buffers if they're of the same
size and chroma-type/rgba-format.
Also remove gst_vdp_output_src_pad_negotiate and set a "setcaps" function on
GstVdpOutputSrcPad instead, leaving negotiation to GstVdpVideoPostProcess.
Diffstat (limited to 'sys/vdpau')
-rw-r--r-- | sys/vdpau/gstvdp/gstvdpoutputsrcpad.c | 143 | ||||
-rw-r--r-- | sys/vdpau/gstvdp/gstvdpoutputsrcpad.h | 2 | ||||
-rw-r--r-- | sys/vdpau/gstvdpvideopostprocess.c | 116 | ||||
-rw-r--r-- | sys/vdpau/gstvdpvideopostprocess.h | 2 |
4 files changed, 107 insertions, 156 deletions
diff --git a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c index 9813f68ef..078f325e6 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c +++ b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c @@ -20,6 +20,7 @@ #include "gstvdputils.h" #include "gstvdpvideobuffer.h" +#include "gstvdpoutputbufferpool.h" #include "gstvdpoutputsrcpad.h" @@ -46,11 +47,13 @@ struct _GstVdpOutputSrcPad GstCaps *caps; - GstCaps *input_caps; + GstCaps *output_caps; GstVdpOutputSrcPadFormat output_format; VdpRGBAFormat rgba_format; gint width, height; + GstVdpBufferPool *bpool; + /* properties */ GstVdpDevice *device; }; @@ -126,57 +129,20 @@ gst_vdp_output_src_pad_create_buffer (GstVdpOutputSrcPad * vdp_pad, { GstFlowReturn ret; GstBuffer *neg_buf; - GstStructure *structure; /* negotiate */ ret = gst_pad_alloc_buffer_and_set_caps (GST_PAD_CAST (vdp_pad), GST_BUFFER_OFFSET_NONE, 0, GST_PAD_CAPS (vdp_pad), &neg_buf); - - if (ret == GST_FLOW_OK) { - gint new_width, new_height; - - structure = gst_caps_get_structure (GST_BUFFER_CAPS (neg_buf), 0); - if (!gst_structure_get_int (structure, "width", &new_width) || - !gst_structure_get_int (structure, "height", &new_height)) - goto invalid_caps; - - if (new_width != vdp_pad->width || new_height != vdp_pad->height) { - GST_DEBUG_OBJECT (vdp_pad, "new dimensions: %dx%d", new_width, - new_height); - - vdp_pad->width = new_width; - vdp_pad->height = new_height; - - gst_caps_set_simple (vdp_pad->input_caps, - "width", G_TYPE_INT, new_width, - "height", G_TYPE_INT, new_height, NULL); - } - + if (ret == GST_FLOW_OK) gst_buffer_unref (neg_buf); - } - *output_buf = gst_vdp_output_buffer_new (vdp_pad->device, - vdp_pad->rgba_format, vdp_pad->width, vdp_pad->height, NULL); + *output_buf = + (GstVdpOutputBuffer *) gst_vdp_buffer_pool_get_buffer (vdp_pad->bpool, + error); if (!*output_buf) - goto output_buf_error; - - gst_buffer_set_caps (GST_BUFFER_CAST (*output_buf), vdp_pad->input_caps); + return GST_FLOW_ERROR; return GST_FLOW_OK; - -invalid_caps: - gst_buffer_unref (neg_buf); - - g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED, - "Sink element allocated buffer with invalid caps"); - return GST_FLOW_ERROR; - -output_buf_error: - gst_buffer_unref (neg_buf); - g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ, - "Couldn't create a GstVdpOutputBuffer"); - return GST_FLOW_ERROR; - } static GstFlowReturn @@ -185,7 +151,7 @@ gst_vdp_output_src_pad_alloc_with_caps (GstVdpOutputSrcPad * vdp_pad, { GstFlowReturn ret; - ret = gst_pad_alloc_buffer ((GstPad *) vdp_pad, 0, 0, caps, + ret = gst_pad_alloc_buffer_and_set_caps ((GstPad *) vdp_pad, 0, 0, caps, (GstBuffer **) output_buf); if (ret != GST_FLOW_OK) return ret; @@ -244,41 +210,35 @@ gst_vdp_output_src_pad_alloc_buffer (GstVdpOutputSrcPad * vdp_pad, } -gboolean -gst_vdp_output_src_pad_negotiate_output (GstVdpOutputSrcPad * vdp_pad, - GstCaps * video_caps) +static gboolean +gst_vdp_output_src_pad_setcaps (GstPad * pad, GstCaps * caps) { - GstCaps *allowed_caps, *output_caps, *src_caps; + GstVdpOutputSrcPad *vdp_pad = GST_VDP_OUTPUT_SRC_PAD (pad); const GstStructure *structure; - g_return_val_if_fail (GST_IS_VDP_OUTPUT_SRC_PAD (vdp_pad), FALSE); - g_return_val_if_fail (GST_IS_CAPS (video_caps), FALSE); + structure = gst_caps_get_structure (caps, 0); - allowed_caps = gst_pad_get_allowed_caps (GST_PAD_CAST (vdp_pad)); - if (G_UNLIKELY (!allowed_caps)) - goto allowed_caps_error; - if (G_UNLIKELY (gst_caps_is_empty (allowed_caps))) { - gst_caps_unref (allowed_caps); - goto allowed_caps_error; - } - GST_DEBUG ("allowed_caps: %" GST_PTR_FORMAT, allowed_caps); - - output_caps = gst_vdp_video_to_output_caps (video_caps); - src_caps = gst_caps_intersect (output_caps, allowed_caps); - gst_caps_unref (output_caps); - gst_caps_unref (allowed_caps); + if (!gst_structure_get_int (structure, "width", &vdp_pad->width)) + return FALSE; + if (!gst_structure_get_int (structure, "height", &vdp_pad->height)) + return FALSE; - if (gst_caps_is_empty (src_caps)) - goto not_negotiated; + if (gst_structure_has_name (structure, "video/x-raw-rgb")) { + if (!gst_vdp_caps_to_rgba_format (caps, &vdp_pad->rgba_format)) + return FALSE; - gst_pad_fixate_caps (GST_PAD_CAST (vdp_pad), src_caps); + /* create buffer pool if we dont't have one */ + if (!vdp_pad->bpool) + vdp_pad->bpool = gst_vdp_output_buffer_pool_new (vdp_pad->device); - GST_DEBUG ("src_caps: %" GST_PTR_FORMAT, src_caps); + if (vdp_pad->output_caps) + gst_caps_unref (vdp_pad->output_caps); - structure = gst_caps_get_structure (src_caps, 0); - if (gst_structure_has_name (structure, "video/x-raw-rgb")) { - if (!gst_vdp_caps_to_rgba_format (src_caps, &vdp_pad->rgba_format)) - return FALSE; + vdp_pad->output_caps = gst_caps_new_simple ("video/x-vdpau-output", + "rgba-format", G_TYPE_INT, vdp_pad->rgba_format, + "width", G_TYPE_INT, vdp_pad->width, "height", G_TYPE_INT, + vdp_pad->height, NULL); + gst_vdp_buffer_pool_set_caps (vdp_pad->bpool, vdp_pad->output_caps); vdp_pad->output_format = GST_VDP_OUTPUT_SRC_PAD_FORMAT_RGB; } else if (gst_structure_has_name (structure, "video/x-vdpau-output")) { @@ -286,29 +246,17 @@ gst_vdp_output_src_pad_negotiate_output (GstVdpOutputSrcPad * vdp_pad, (gint *) & vdp_pad->rgba_format)) return FALSE; + /* don't need the buffer pool */ + if (vdp_pad->bpool) { + gst_object_unref (vdp_pad->bpool); + vdp_pad->bpool = NULL; + } + vdp_pad->output_format = GST_VDP_OUTPUT_SRC_PAD_FORMAT_VDPAU; } else return FALSE; - if (!gst_structure_get_int (structure, "width", &vdp_pad->width)) - return FALSE; - if (!gst_structure_get_int (structure, "height", &vdp_pad->height)) - return FALSE; - - if (gst_pad_set_caps (GST_PAD (vdp_pad), src_caps)) { - vdp_pad->input_caps = gst_caps_copy (video_caps); - return TRUE; - } - return FALSE; - -allowed_caps_error: - GST_ERROR_OBJECT (vdp_pad, "Got invalid allowed caps"); - return FALSE; - -not_negotiated: - gst_caps_unref (src_caps); - GST_ERROR_OBJECT (vdp_pad, "Couldn't find suitable output format"); - return FALSE; + return TRUE; } static GstCaps * @@ -337,8 +285,16 @@ gst_vdp_output_src_pad_activate_push (GstPad * pad, gboolean active) gst_caps_unref (vdp_pad->caps); vdp_pad->caps = NULL; + if (vdp_pad->output_caps) + gst_caps_unref (vdp_pad->output_caps); + vdp_pad->output_caps = NULL; + + if (vdp_pad->bpool) + g_object_unref (vdp_pad->bpool); + vdp_pad->bpool = NULL; + if (vdp_pad->device) - gst_object_unref (vdp_pad->device); + g_object_unref (vdp_pad->device); vdp_pad->device = NULL; } @@ -413,11 +369,14 @@ gst_vdp_output_src_pad_init (GstVdpOutputSrcPad * vdp_pad) GstPad *pad = GST_PAD (vdp_pad); vdp_pad->caps = NULL; - + vdp_pad->output_caps = NULL; + vdp_pad->bpool = NULL; vdp_pad->device = NULL; gst_pad_set_getcaps_function (pad, GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_getcaps)); + gst_pad_set_setcaps_function (pad, + GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_setcaps)); gst_pad_set_activatepush_function (pad, GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_activate_push)); } diff --git a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h index be3f3ec68..02981a31c 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h +++ b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h @@ -43,8 +43,6 @@ GstFlowReturn gst_vdp_output_src_pad_alloc_buffer (GstVdpOutputSrcPad *vdp_pad, GstFlowReturn gst_vdp_output_src_pad_get_device (GstVdpOutputSrcPad *vdp_pad, GstVdpDevice **device, GError **error); -gboolean gst_vdp_output_src_pad_negotiate_output (GstVdpOutputSrcPad *vdp_pad, GstCaps *video_caps); - GstVdpOutputSrcPad *gst_vdp_output_src_pad_new (GstPadTemplate *templ, const gchar *name); GType gst_vdp_output_src_pad_get_type (void); diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c index e77b41dd6..8311f28ce 100644 --- a/sys/vdpau/gstvdpvideopostprocess.c +++ b/sys/vdpau/gstvdpvideopostprocess.c @@ -474,6 +474,8 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) GstCaps *video_caps = NULL; gboolean res = FALSE; + GstCaps *allowed_caps, *output_caps, *src_caps; + /* check if the input is non native */ structure = gst_caps_get_structure (caps, 0); if (gst_structure_has_name (structure, "video/x-raw-yuv")) { @@ -483,9 +485,20 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) video_caps = gst_vdp_video_buffer_parse_yuv_caps (caps); if (!video_caps) goto done; + + if (!vpp->vpool) + vpp->vpool = gst_vdp_video_buffer_pool_new (vpp->device); + + gst_vdp_buffer_pool_set_caps (vpp->vpool, video_caps); + } else { vpp->native_input = TRUE; video_caps = gst_caps_copy (caps); + + if (vpp->vpool) { + g_object_unref (vpp->vpool); + vpp->vpool = NULL; + } } @@ -522,9 +535,29 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) gst_structure_remove_field (structure, "interlaced"); } - res = - gst_vdp_output_src_pad_negotiate_output (GST_VDP_OUTPUT_SRC_PAD - (vpp->srcpad), video_caps); + allowed_caps = gst_pad_get_allowed_caps (vpp->srcpad); + if (G_UNLIKELY (!allowed_caps)) + goto allowed_caps_error; + if (G_UNLIKELY (gst_caps_is_empty (allowed_caps))) { + gst_caps_unref (allowed_caps); + goto allowed_caps_error; + } + GST_DEBUG ("allowed_caps: %" GST_PTR_FORMAT, allowed_caps); + + output_caps = gst_vdp_video_to_output_caps (video_caps); + src_caps = gst_caps_intersect (output_caps, allowed_caps); + gst_caps_unref (allowed_caps); + gst_caps_unref (output_caps); + + if (gst_caps_is_empty (src_caps)) + goto not_negotiated; + + gst_pad_fixate_caps (vpp->srcpad, src_caps); + + GST_DEBUG ("src_caps: %" GST_PTR_FORMAT, src_caps); + + res = gst_pad_set_caps (vpp->srcpad, src_caps); + gst_caps_unref (src_caps); done: gst_object_unref (vpp); @@ -532,6 +565,15 @@ done: gst_caps_unref (video_caps); return res; + +allowed_caps_error: + GST_ERROR_OBJECT (vpp, "Got invalid allowed caps"); + goto done; + +not_negotiated: + gst_caps_unref (src_caps); + GST_ERROR_OBJECT (vpp, "Couldn't find suitable output format"); + goto done; } static void @@ -562,7 +604,7 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp) vpp->discont = FALSE; vpp->mixer = VDP_INVALID_HANDLE; - vpp->device = NULL; + vpp->vpool = NULL; for (i = 0; i < MAX_PICTURES; i++) { vpp->future_pictures[i].buf = NULL; @@ -590,6 +632,9 @@ gst_vdp_vpp_stop (GstVdpVideoPostProcess * vpp) { gst_vdp_vpp_flush (vpp); + if (vpp->vpool) + g_object_unref (vpp->vpool); + if (vpp->mixer != VDP_INVALID_HANDLE) { GstVdpDevice *device = vpp->device; VdpStatus status; @@ -738,6 +783,7 @@ gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer) GstClockTime qostime; GstFlowReturn ret = GST_FLOW_OK; + GError *err; GST_DEBUG ("chain"); @@ -790,8 +836,9 @@ no_qos: if (!vpp->native_input) { GstVdpVideoBuffer *video_buf; - video_buf = gst_vdp_video_buffer_new (vpp->device, vpp->chroma_type, - vpp->width, vpp->height, NULL); + err = NULL; + video_buf = + (GstVdpVideoBuffer *) gst_vdp_buffer_pool_get_buffer (vpp->vpool, &err); if (G_UNLIKELY (!video_buf)) goto video_buf_error; @@ -832,8 +879,7 @@ error: video_buf_error: gst_buffer_unref (GST_BUFFER (buffer)); - GST_ELEMENT_ERROR (vpp, RESOURCE, READ, - ("Couldn't create GstVdpVideoBuffer"), (NULL)); + gst_vdp_vpp_post_error (vpp, err); ret = GST_FLOW_ERROR; goto done; } @@ -861,59 +907,6 @@ gst_vdp_vpp_sink_getcaps (GstPad * pad) return caps; } -static GstFlowReturn -gst_vdp_vpp_sink_bufferalloc (GstPad * pad, guint64 offset, guint size, - GstCaps * caps, GstBuffer ** buf) -{ - GstVdpVideoPostProcess *vpp = - GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad)); - GstFlowReturn ret = GST_FLOW_ERROR; - GstStructure *structure; - - GST_DEBUG ("buffer_alloc"); - structure = gst_caps_get_structure (caps, 0); - if (gst_structure_has_name (structure, "video/x-vdpau-video")) { - gint width, height; - VdpChromaType chroma_type; - - if (!gst_structure_get_int (structure, "width", &width) || - !gst_structure_get_int (structure, "height", &height) || - !gst_structure_get_int (structure, "chroma-type", - (gint *) & chroma_type)) - goto invalid_caps; - - *buf = - GST_BUFFER (gst_vdp_video_buffer_new (vpp->device, chroma_type, width, - height, NULL)); - - if (*buf == NULL) - goto video_buffer_error; - } else - *buf = gst_buffer_new_and_alloc (size); - - GST_BUFFER_SIZE (*buf) = size; - GST_BUFFER_OFFSET (*buf) = offset; - - gst_buffer_set_caps (*buf, caps); - - ret = GST_FLOW_OK; - -done: - gst_object_unref (vpp); - return ret; - -invalid_caps: - GST_ELEMENT_ERROR (vpp, STREAM, FAILED, ("Invalid caps"), (NULL)); - ret = GST_FLOW_ERROR; - goto done; - -video_buffer_error: - GST_ELEMENT_ERROR (vpp, RESOURCE, READ, - ("Couldn't create GstVdpVideoBuffer"), (NULL)); - ret = GST_FLOW_ERROR; - goto done; -} - static gboolean gst_vdp_vpp_src_event (GstPad * pad, GstEvent * event) { @@ -1291,7 +1284,6 @@ gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp, GST_DEBUG_FUNCPTR (gst_vdp_vpp_chain)); gst_pad_set_event_function (vpp->sinkpad, GST_DEBUG_FUNCPTR (gst_vdp_vpp_sink_event)); - gst_pad_set_bufferalloc_function (vpp->sinkpad, gst_vdp_vpp_sink_bufferalloc); } static void diff --git a/sys/vdpau/gstvdpvideopostprocess.h b/sys/vdpau/gstvdpvideopostprocess.h index 678015800..da57e827a 100644 --- a/sys/vdpau/gstvdpvideopostprocess.h +++ b/sys/vdpau/gstvdpvideopostprocess.h @@ -25,6 +25,7 @@ #include "gstvdp/gstvdpdevice.h" #include "gstvdp/gstvdpvideobuffer.h" +#include "gstvdp/gstvdpvideobufferpool.h" G_BEGIN_DECLS @@ -72,6 +73,7 @@ struct _GstVdpVideoPostProcess VdpChromaType chroma_type; gint width, height; guint32 fourcc; + GstVdpBufferPool *vpool; gboolean got_par; gint par_n, par_d; |