diff options
-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 @@ -22,2 +22,3 @@ #include "gstvdpvideobuffer.h" +#include "gstvdpoutputbufferpool.h" @@ -48,3 +49,3 @@ struct _GstVdpOutputSrcPad - GstCaps *input_caps; + GstCaps *output_caps; GstVdpOutputSrcPadFormat output_format; @@ -53,2 +54,4 @@ struct _GstVdpOutputSrcPad + GstVdpBufferPool *bpool; + /* properties */ @@ -128,3 +131,2 @@ gst_vdp_output_src_pad_create_buffer (GstVdpOutputSrcPad * vdp_pad, GstBuffer *neg_buf; - GstStructure *structure; @@ -133,48 +135,12 @@ gst_vdp_output_src_pad_create_buffer (GstVdpOutputSrcPad * 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; - } @@ -187,3 +153,3 @@ gst_vdp_output_src_pad_alloc_with_caps (GstVdpOutputSrcPad * vdp_pad, - 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); @@ -246,37 +212,31 @@ 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); @@ -288,2 +248,8 @@ gst_vdp_output_src_pad_negotiate_output (GstVdpOutputSrcPad * vdp_pad, + /* 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; @@ -292,21 +258,3 @@ gst_vdp_output_src_pad_negotiate_output (GstVdpOutputSrcPad * vdp_pad, - 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; } @@ -339,4 +287,12 @@ gst_vdp_output_src_pad_activate_push (GstPad * pad, gboolean active) + 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; @@ -415,3 +371,4 @@ gst_vdp_output_src_pad_init (GstVdpOutputSrcPad * vdp_pad) vdp_pad->caps = NULL; - + vdp_pad->output_caps = NULL; + vdp_pad->bpool = NULL; vdp_pad->device = NULL; @@ -420,2 +377,4 @@ gst_vdp_output_src_pad_init (GstVdpOutputSrcPad * vdp_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, 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 @@ -45,4 +45,2 @@ GstFlowReturn gst_vdp_output_src_pad_get_device (GstVdpOutputSrcPad *vdp_pad, Gs -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); 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 @@ -476,2 +476,4 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) + GstCaps *allowed_caps, *output_caps, *src_caps; + /* check if the input is non native */ @@ -485,2 +487,8 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * 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 { @@ -488,2 +496,7 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) video_caps = gst_caps_copy (caps); + + if (vpp->vpool) { + g_object_unref (vpp->vpool); + vpp->vpool = NULL; + } } @@ -524,5 +537,25 @@ gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) - 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); @@ -534,2 +567,11 @@ done: 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; } @@ -564,3 +606,3 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp) vpp->mixer = VDP_INVALID_HANDLE; - vpp->device = NULL; + vpp->vpool = NULL; @@ -592,2 +634,5 @@ gst_vdp_vpp_stop (GstVdpVideoPostProcess * vpp) + if (vpp->vpool) + g_object_unref (vpp->vpool); + if (vpp->mixer != VDP_INVALID_HANDLE) { @@ -740,2 +785,3 @@ gst_vdp_vpp_chain (GstPad * pad, GstBuffer * buffer) GstFlowReturn ret = GST_FLOW_OK; + GError *err; @@ -792,4 +838,5 @@ no_qos: - 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)) @@ -834,4 +881,3 @@ 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; @@ -863,55 +909,2 @@ gst_vdp_vpp_sink_getcaps (GstPad * pad) -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 @@ -1293,3 +1286,2 @@ gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp, GST_DEBUG_FUNCPTR (gst_vdp_vpp_sink_event)); - gst_pad_set_bufferalloc_function (vpp->sinkpad, gst_vdp_vpp_sink_bufferalloc); } 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 @@ -27,2 +27,3 @@ #include "gstvdp/gstvdpvideobuffer.h" +#include "gstvdp/gstvdpvideobufferpool.h" @@ -74,2 +75,3 @@ struct _GstVdpVideoPostProcess guint32 fourcc; + GstVdpBufferPool *vpool; |