GST_DEBUG_CATEGORY_STATIC (gst_capsfilter_debug);
#define GST_CAT_DEFAULT gst_capsfilter_debug
-#define _do_init(bla) \
+#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_capsfilter_debug, "capsfilter", 0, \
"capsfilter element");
-
-GST_BOILERPLATE_FULL (GstCapsFilter, gst_capsfilter, GstBaseTransform,
- GST_TYPE_BASE_TRANSFORM, _do_init);
+#define gst_capsfilter_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstCapsFilter, gst_capsfilter, GST_TYPE_BASE_TRANSFORM,
+ _do_init);
static void gst_capsfilter_set_property (GObject * object, guint prop_id,
static void gst_capsfilter_dispose (GObject * object);
static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base,
- GstPadDirection direction, GstCaps * caps);
+ GstPadDirection direction, GstCaps * caps, GstCaps * filter);
static gboolean gst_capsfilter_accept_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)
-{
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (gstelement_class,
- "CapsFilter",
- "Generic",
- "Pass data without modification, limiting formats",
- "David Schleef <ds@schleef.org>");
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&srctemplate));
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&sinktemplate));
-}
+ GstBuffer * input, GstBuffer ** buf);
static void
gst_capsfilter_class_init (GstCapsFilterClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
GstBaseTransformClass *trans_class;
gobject_class = G_OBJECT_CLASS (klass);
"object."), GST_TYPE_CAPS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ gstelement_class = GST_ELEMENT_CLASS (klass);
+ gst_element_class_set_details_simple (gstelement_class,
+ "CapsFilter",
+ "Generic",
+ "Pass data without modification, limiting formats",
+ "David Schleef <ds@schleef.org>");
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&srctemplate));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sinktemplate));
+
trans_class = GST_BASE_TRANSFORM_CLASS (klass);
trans_class->transform_caps =
GST_DEBUG_FUNCPTR (gst_capsfilter_transform_caps);
}
static void
-gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class)
+gst_capsfilter_init (GstCapsFilter * filter)
{
GstBaseTransform *trans = GST_BASE_TRANSFORM (filter);
gst_base_transform_set_gap_aware (trans, TRUE);
GST_DEBUG_OBJECT (capsfilter, "set new caps %" GST_PTR_FORMAT, new_caps);
/* filter the currently negotiated format against the new caps */
- GST_OBJECT_LOCK (GST_BASE_TRANSFORM_SINK_PAD (object));
- nego = GST_PAD_CAPS (GST_BASE_TRANSFORM_SINK_PAD (object));
+ nego = gst_pad_get_current_caps (GST_BASE_TRANSFORM_SINK_PAD (object));
if (nego) {
GST_DEBUG_OBJECT (capsfilter, "we had negotiated caps %" GST_PTR_FORMAT,
nego);
suggest = gst_caps_copy (new_caps);
}
}
+ gst_caps_unref (nego);
} else {
GST_DEBUG_OBJECT (capsfilter, "no negotiated caps");
/* Suggest the new caps, we can't just rely on _get_caps as this may
* pushed yet */
suggest = gst_caps_copy (new_caps);
}
- GST_OBJECT_UNLOCK (GST_BASE_TRANSFORM_SINK_PAD (object));
GST_DEBUG_OBJECT (capsfilter, "suggesting new caps %" GST_PTR_FORMAT,
suggest);
static GstCaps *
gst_capsfilter_transform_caps (GstBaseTransform * base,
- GstPadDirection direction, GstCaps * caps)
+ GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
GstCapsFilter *capsfilter = GST_CAPSFILTER (base);
- GstCaps *ret, *filter_caps;
+ GstCaps *ret, *filter_caps, *tmp;
GST_OBJECT_LOCK (capsfilter);
filter_caps = gst_caps_ref (capsfilter->filter_caps);
GST_OBJECT_UNLOCK (capsfilter);
- ret = gst_caps_intersect (caps, filter_caps);
+ if (filter) {
+ tmp =
+ gst_caps_intersect_full (filter, filter_caps, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (filter_caps);
+ filter_caps = tmp;
+ }
+
+ ret = gst_caps_intersect_full (filter_caps, caps, GST_CAPS_INTERSECT_FIRST);
+
GST_DEBUG_OBJECT (capsfilter, "input: %" GST_PTR_FORMAT, caps);
- GST_DEBUG_OBJECT (capsfilter, "filter: %" GST_PTR_FORMAT, filter_caps);
+ GST_DEBUG_OBJECT (capsfilter, "filter: %" GST_PTR_FORMAT, filter);
+ GST_DEBUG_OBJECT (capsfilter, "caps filter: %" GST_PTR_FORMAT,
+ filter_caps);
GST_DEBUG_OBJECT (capsfilter, "intersect: %" GST_PTR_FORMAT, ret);
gst_caps_unref (filter_caps);
*/
static GstFlowReturn
gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
- gint size, GstCaps * caps, GstBuffer ** buf)
+ GstBuffer ** buf)
{
GstFlowReturn ret = GST_FLOW_OK;
- if (GST_BUFFER_CAPS (input) != NULL) {
- /* Output buffer already has caps */
- GST_LOG_OBJECT (trans, "Input buffer already has caps (implicitely fixed)");
- /* FIXME : Move this behaviour to basetransform. The given caps are the ones
- * of the source pad, therefore our outgoing buffers should always have
- * those caps. */
- if (GST_BUFFER_CAPS (input) != caps) {
- /* caps are different, make a metadata writable output buffer to set
- * caps */
- if (gst_buffer_is_metadata_writable (input)) {
- /* input is writable, just set caps and use this as the output */
- *buf = input;
- gst_buffer_set_caps (*buf, caps);
- gst_buffer_ref (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_set_caps (*buf, caps);
- }
- } else {
- /* caps are right, just use a ref of the input as the outbuf */
- *buf = input;
- gst_buffer_ref (input);
- }
- } else {
+ /* always return the input as output buffer */
+ *buf = input;
+
+ if (!gst_pad_has_current_caps (trans->sinkpad)) {
/* Buffer has no caps. See if the output pad only supports fixed caps */
GstCaps *out_caps;
- out_caps = GST_PAD_CAPS (trans->srcpad);
+ GST_LOG_OBJECT (trans, "Input pad does not have caps");
- if (out_caps != NULL) {
- gst_caps_ref (out_caps);
- } else {
+ out_caps = gst_pad_get_current_caps (trans->srcpad);
+ if (out_caps == NULL) {
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_metadata_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 (*buf) = out_caps;
+ GST_PTR_FORMAT " to apply to srcpad", out_caps);
- if (GST_PAD_CAPS (trans->srcpad) == NULL)
- gst_pad_set_caps (trans->srcpad, out_caps);
+ if (!gst_pad_has_current_caps (trans->srcpad))
+ gst_pad_push_event (trans->srcpad, gst_event_new_caps (out_caps));
} else {
gchar *caps_str = gst_caps_to_string (out_caps);