diff options
Diffstat (limited to 'sys/vdpau/gstvdp/gstvdpoutputsrcpad.c')
-rw-r--r-- | sys/vdpau/gstvdp/gstvdpoutputsrcpad.c | 143 |
1 files changed, 51 insertions, 92 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)); } |