From 1feeaffc7fb4cd1a5a4b98c5a2678e4fc9fb2fe9 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 9 Sep 2005 23:45:15 +0000 Subject: [PATCH] check/gst-libs/controller.c: Header include fix. Original commit message from CVS: * check/gst-libs/controller.c: Header include fix. * gst/base/gstbasetransform.c: (gst_base_transform_default_prepare_buf), (gst_base_transform_handle_buffer): * gst/base/gstbasetransform.h: Some more basetransform changes and fixes to enable sub-classes that modify buffer metadata only. * gst/elements/gstcapsfilter.c: (gst_capsfilter_class_init), (gst_capsfilter_init), (gst_capsfilter_transform_ip), (gst_capsfilter_prepare_buf): If the output pad has fixed allowed caps and input buffers don't have any, set the fixed caps on outgoing buffers. --- ChangeLog | 16 ++++++++++ check/gst-libs/controller.c | 2 +- gst/base/gstbasetransform.c | 17 ++++++---- gst/base/gstbasetransform.h | 9 +++--- gst/elements/gstcapsfilter.c | 69 +++++++++++++++++++++++++++++++++------- libs/gst/base/gstbasetransform.c | 17 ++++++---- libs/gst/base/gstbasetransform.h | 9 +++--- plugins/elements/gstcapsfilter.c | 69 +++++++++++++++++++++++++++++++++------- tests/check/libs/controller.c | 2 +- 9 files changed, 166 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 772b029..9c91472 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-09-10 Jan Schmidt + + * check/gst-libs/controller.c: + Header include fix. + * gst/base/gstbasetransform.c: + (gst_base_transform_default_prepare_buf), + (gst_base_transform_handle_buffer): + * gst/base/gstbasetransform.h: + Some more basetransform changes and fixes to enable sub-classes + that modify buffer metadata only. + * gst/elements/gstcapsfilter.c: (gst_capsfilter_class_init), + (gst_capsfilter_init), (gst_capsfilter_transform_ip), + (gst_capsfilter_prepare_buf): + If the output pad has fixed allowed caps and input buffers + don't have any, set the fixed caps on outgoing buffers. + 2005-09-09 Jan Schmidt * check/elements/identity.c: (GST_START_TEST): Make the error a little clearer when the test fails because diff --git a/check/gst-libs/controller.c b/check/gst-libs/controller.c index c20fce9..83974a9 100644 --- a/check/gst-libs/controller.c +++ b/check/gst-libs/controller.c @@ -22,7 +22,7 @@ #include "config.h" #include -#include +#include /* LOCAL TEST ELEMENT */ diff --git a/gst/base/gstbasetransform.c b/gst/base/gstbasetransform.c index 2651d9d..819948b 100644 --- a/gst/base/gstbasetransform.c +++ b/gst/base/gstbasetransform.c @@ -797,8 +797,8 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans, bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); /* See if we want to prepare the buffer for in place output */ - if (GST_BUFFER_SIZE (input) == size && bclass->transform_ip) { - if (gst_buffer_is_writable (input) && (*buf == NULL)) { + if (*buf == NULL && GST_BUFFER_SIZE (input) == size && bclass->transform_ip) { + if (gst_buffer_is_writable (input)) { /* Input buffer is already writable, just ref and return it */ *buf = input; gst_buffer_ref (input); @@ -823,15 +823,15 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans, * buffer flags */ if (*buf != input && GST_MINI_OBJECT_REFCOUNT_VALUE (*buf) == 1) { + if (copy_inbuf && gst_buffer_is_writable (*buf)) + memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size); + gst_buffer_stamp (*buf, input); GST_BUFFER_FLAGS (*buf) |= GST_BUFFER_FLAGS (input) & (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_DELTA_UNIT); } - if (copy_inbuf && gst_buffer_is_writable (*buf)) - memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size); - return ret; } @@ -1070,7 +1070,11 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GST_LOG_OBJECT (trans, "handling buffer %p of size %d and offset NONE", inbuf, GST_BUFFER_SIZE (inbuf)); - if (!trans->negotiated && !trans->passthrough) + /* Don't allow buffer handling before negotiation, except in passthrough mode + * or if the class doesn't implement a set_caps function (in which case it doesn't + * care about caps) + */ + if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL)) goto not_negotiated; if (trans->passthrough) { @@ -1088,6 +1092,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, } want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place; + *outbuf = NULL; if (want_in_place) { /* If want_in_place is TRUE, we may need to prepare a new output buffer diff --git a/gst/base/gstbasetransform.h b/gst/base/gstbasetransform.h index ae8bba8..2f42a81 100644 --- a/gst/base/gstbasetransform.h +++ b/gst/base/gstbasetransform.h @@ -51,9 +51,6 @@ struct _GstBaseTransform { gboolean passthrough; gboolean always_in_place; - /* Set if caps on each pad are equal */ - gboolean have_same_caps; - GstCaps *cache_caps1; guint cache_caps1_size; GstCaps *cache_caps2; @@ -70,8 +67,12 @@ struct _GstBaseTransform { gint64 segment_stop; gint64 segment_base; + /* FIXME: When adjusting the padding, move this to a nice place in the structure */ + /* Set if caps on each pad are equal */ + gboolean have_same_caps; + /*< private >*/ - gpointer _gst_reserved[GST_PADDING]; + gpointer _gst_reserved[GST_PADDING - 1]; }; /** diff --git a/gst/elements/gstcapsfilter.c b/gst/elements/gstcapsfilter.c index b113007..9a6b168 100644 --- a/gst/elements/gstcapsfilter.c +++ b/gst/elements/gstcapsfilter.c @@ -102,7 +102,8 @@ static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps); static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf); - +static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans, + GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf); static void gst_capsfilter_base_init (gpointer g_class) @@ -135,12 +136,12 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass) trans_class = (GstBaseTransformClass *) klass; trans_class->transform_caps = gst_capsfilter_transform_caps; trans_class->transform_ip = gst_capsfilter_transform_ip; + trans_class->prepare_output_buffer = gst_capsfilter_prepare_buf; } static void gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class) { - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE); filter->filter_caps = gst_caps_new_any (); } @@ -216,15 +217,61 @@ gst_capsfilter_transform_caps (GstBaseTransform * base, static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf) { - /* Ensure that outgoing buffers have caps if we can, so that pipelines - * like: - * gst-launch filesrc location=rawsamples.raw ! - * audio/x-raw-int,width=16,depth=16,rate=48000,channels=2, - * endianness=4321,signed='(boolean)'true ! alsasink - * will work. - */ - if (GST_BUFFER_CAPS (buf) == NULL) { + /* No actual work here. It's all done in the prepare output buffer + * func. */ + return GST_FLOW_OK; +} + +/* Output buffer preparation... if the buffer has no caps, and + * our allowed output caps is fixed, then give the caps to the + * buffer. + * This ensures that outgoing buffers have caps if we can, so + * that pipelines like: + * gst-launch filesrc location=rawsamples.raw ! + * audio/x-raw-int,width=16,depth=16,rate=48000,channels=2, + * endianness=4321,signed='(boolean)'true ! alsasink + * will work. + */ +static GstFlowReturn +gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input, + gint size, GstCaps * caps, GstBuffer ** buf) +{ + if (GST_BUFFER_CAPS (input) != NULL) { + /* Output buffer already has caps */ + GST_DEBUG_OBJECT (trans, "Input buffer already has caps"); + gst_buffer_ref (input); + *buf = input; + } else { + /* Buffer has no caps. See if the output pad only supports fixed caps */ + GstCaps *out_caps; + + if (GST_PAD_CAPS (trans->srcpad) != NULL) { + gst_caps_ref (GST_PAD_CAPS (trans->srcpad)); + out_caps = GST_PAD_CAPS (trans->srcpad); + } else { + out_caps = gst_pad_get_allowed_caps (trans->srcpad); + g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR); + } + + if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) { + GST_DEBUG_OBJECT (trans, "Have fixed output caps %" + GST_PTR_FORMAT " to apply to buffer with no caps", out_caps); + if (gst_buffer_is_writable (input)) { + gst_buffer_ref (input); + *buf = input; + } else { + GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps"); + *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input)); + } + GST_BUFFER_CAPS (input) = out_caps; + + if (GST_PAD_CAPS (trans->srcpad) == NULL) + gst_pad_set_caps (trans->srcpad, out_caps); + } else { + gst_caps_unref (out_caps); + } } - return GST_FLOW_OK; + return GST_BASE_TRANSFORM_CLASS (parent_class)-> + prepare_output_buffer (trans, input, size, caps, buf); } diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 2651d9d..819948b 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -797,8 +797,8 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans, bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); /* See if we want to prepare the buffer for in place output */ - if (GST_BUFFER_SIZE (input) == size && bclass->transform_ip) { - if (gst_buffer_is_writable (input) && (*buf == NULL)) { + if (*buf == NULL && GST_BUFFER_SIZE (input) == size && bclass->transform_ip) { + if (gst_buffer_is_writable (input)) { /* Input buffer is already writable, just ref and return it */ *buf = input; gst_buffer_ref (input); @@ -823,15 +823,15 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans, * buffer flags */ if (*buf != input && GST_MINI_OBJECT_REFCOUNT_VALUE (*buf) == 1) { + if (copy_inbuf && gst_buffer_is_writable (*buf)) + memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size); + gst_buffer_stamp (*buf, input); GST_BUFFER_FLAGS (*buf) |= GST_BUFFER_FLAGS (input) & (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_DELTA_UNIT); } - if (copy_inbuf && gst_buffer_is_writable (*buf)) - memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size); - return ret; } @@ -1070,7 +1070,11 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GST_LOG_OBJECT (trans, "handling buffer %p of size %d and offset NONE", inbuf, GST_BUFFER_SIZE (inbuf)); - if (!trans->negotiated && !trans->passthrough) + /* Don't allow buffer handling before negotiation, except in passthrough mode + * or if the class doesn't implement a set_caps function (in which case it doesn't + * care about caps) + */ + if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL)) goto not_negotiated; if (trans->passthrough) { @@ -1088,6 +1092,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, } want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place; + *outbuf = NULL; if (want_in_place) { /* If want_in_place is TRUE, we may need to prepare a new output buffer diff --git a/libs/gst/base/gstbasetransform.h b/libs/gst/base/gstbasetransform.h index ae8bba8..2f42a81 100644 --- a/libs/gst/base/gstbasetransform.h +++ b/libs/gst/base/gstbasetransform.h @@ -51,9 +51,6 @@ struct _GstBaseTransform { gboolean passthrough; gboolean always_in_place; - /* Set if caps on each pad are equal */ - gboolean have_same_caps; - GstCaps *cache_caps1; guint cache_caps1_size; GstCaps *cache_caps2; @@ -70,8 +67,12 @@ struct _GstBaseTransform { gint64 segment_stop; gint64 segment_base; + /* FIXME: When adjusting the padding, move this to a nice place in the structure */ + /* Set if caps on each pad are equal */ + gboolean have_same_caps; + /*< private >*/ - gpointer _gst_reserved[GST_PADDING]; + gpointer _gst_reserved[GST_PADDING - 1]; }; /** diff --git a/plugins/elements/gstcapsfilter.c b/plugins/elements/gstcapsfilter.c index b113007..9a6b168 100644 --- a/plugins/elements/gstcapsfilter.c +++ b/plugins/elements/gstcapsfilter.c @@ -102,7 +102,8 @@ static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps); static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf); - +static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans, + GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf); static void gst_capsfilter_base_init (gpointer g_class) @@ -135,12 +136,12 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass) trans_class = (GstBaseTransformClass *) klass; trans_class->transform_caps = gst_capsfilter_transform_caps; trans_class->transform_ip = gst_capsfilter_transform_ip; + trans_class->prepare_output_buffer = gst_capsfilter_prepare_buf; } static void gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class) { - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE); filter->filter_caps = gst_caps_new_any (); } @@ -216,15 +217,61 @@ gst_capsfilter_transform_caps (GstBaseTransform * base, static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf) { - /* Ensure that outgoing buffers have caps if we can, so that pipelines - * like: - * gst-launch filesrc location=rawsamples.raw ! - * audio/x-raw-int,width=16,depth=16,rate=48000,channels=2, - * endianness=4321,signed='(boolean)'true ! alsasink - * will work. - */ - if (GST_BUFFER_CAPS (buf) == NULL) { + /* No actual work here. It's all done in the prepare output buffer + * func. */ + return GST_FLOW_OK; +} + +/* Output buffer preparation... if the buffer has no caps, and + * our allowed output caps is fixed, then give the caps to the + * buffer. + * This ensures that outgoing buffers have caps if we can, so + * that pipelines like: + * gst-launch filesrc location=rawsamples.raw ! + * audio/x-raw-int,width=16,depth=16,rate=48000,channels=2, + * endianness=4321,signed='(boolean)'true ! alsasink + * will work. + */ +static GstFlowReturn +gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input, + gint size, GstCaps * caps, GstBuffer ** buf) +{ + if (GST_BUFFER_CAPS (input) != NULL) { + /* Output buffer already has caps */ + GST_DEBUG_OBJECT (trans, "Input buffer already has caps"); + gst_buffer_ref (input); + *buf = input; + } else { + /* Buffer has no caps. See if the output pad only supports fixed caps */ + GstCaps *out_caps; + + if (GST_PAD_CAPS (trans->srcpad) != NULL) { + gst_caps_ref (GST_PAD_CAPS (trans->srcpad)); + out_caps = GST_PAD_CAPS (trans->srcpad); + } else { + out_caps = gst_pad_get_allowed_caps (trans->srcpad); + g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR); + } + + if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) { + GST_DEBUG_OBJECT (trans, "Have fixed output caps %" + GST_PTR_FORMAT " to apply to buffer with no caps", out_caps); + if (gst_buffer_is_writable (input)) { + gst_buffer_ref (input); + *buf = input; + } else { + GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps"); + *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input)); + } + GST_BUFFER_CAPS (input) = out_caps; + + if (GST_PAD_CAPS (trans->srcpad) == NULL) + gst_pad_set_caps (trans->srcpad, out_caps); + } else { + gst_caps_unref (out_caps); + } } - return GST_FLOW_OK; + return GST_BASE_TRANSFORM_CLASS (parent_class)-> + prepare_output_buffer (trans, input, size, caps, buf); } diff --git a/tests/check/libs/controller.c b/tests/check/libs/controller.c index c20fce9..83974a9 100644 --- a/tests/check/libs/controller.c +++ b/tests/check/libs/controller.c @@ -22,7 +22,7 @@ #include "config.h" #include -#include +#include /* LOCAL TEST ELEMENT */ -- 2.7.4