mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
capsfilter: Send caps before segment
In the case the source has no caps, caps must be sent before segment. This fixes few unit tests that where failing due to the new misordering warning. https://bugzilla.gnome.org/show_bug.cgi?id=699968
This commit is contained in:
parent
a68e33712e
commit
c86f42bc88
2 changed files with 43 additions and 7 deletions
|
@ -83,6 +83,8 @@ static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans,
|
static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans,
|
||||||
GstBuffer * input, GstBuffer ** buf);
|
GstBuffer * input, GstBuffer ** buf);
|
||||||
|
static gboolean gst_capsfilter_sink_event (GstBaseTransform * trans,
|
||||||
|
GstEvent * event);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_capsfilter_class_init (GstCapsFilterClass * klass)
|
gst_capsfilter_class_init (GstCapsFilterClass * klass)
|
||||||
|
@ -121,6 +123,7 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
|
||||||
trans_class->accept_caps = GST_DEBUG_FUNCPTR (gst_capsfilter_accept_caps);
|
trans_class->accept_caps = GST_DEBUG_FUNCPTR (gst_capsfilter_accept_caps);
|
||||||
trans_class->prepare_output_buffer =
|
trans_class->prepare_output_buffer =
|
||||||
GST_DEBUG_FUNCPTR (gst_capsfilter_prepare_buf);
|
GST_DEBUG_FUNCPTR (gst_capsfilter_prepare_buf);
|
||||||
|
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_capsfilter_sink_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -193,6 +196,7 @@ gst_capsfilter_dispose (GObject * object)
|
||||||
GstCapsFilter *filter = GST_CAPSFILTER (object);
|
GstCapsFilter *filter = GST_CAPSFILTER (object);
|
||||||
|
|
||||||
gst_caps_replace (&filter->filter_caps, NULL);
|
gst_caps_replace (&filter->filter_caps, NULL);
|
||||||
|
gst_event_replace (&filter->pending_segment, NULL);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
@ -268,11 +272,11 @@ gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output buffer preparation... if the buffer has no caps, and
|
/* Ouput buffer preparation ... if the buffer has no caps, and our allowed
|
||||||
* our allowed output caps is fixed, then give the caps to the
|
* output caps is fixed, then send the caps downstream, making sure caps are
|
||||||
* buffer.
|
* sent before segment event.
|
||||||
* This ensures that outgoing buffers have caps if we can, so
|
*
|
||||||
* that pipelines like:
|
* This ensures that caps event is sent if we can, so that pipelines like:
|
||||||
* gst-launch filesrc location=rawsamples.raw !
|
* gst-launch filesrc location=rawsamples.raw !
|
||||||
* audio/x-raw,format=S16LE,rate=48000,channels=2 ! alsasink
|
* audio/x-raw,format=S16LE,rate=48000,channels=2 ! alsasink
|
||||||
* will work.
|
* will work.
|
||||||
|
@ -287,11 +291,17 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
|
||||||
*buf = input;
|
*buf = input;
|
||||||
|
|
||||||
if (!gst_pad_has_current_caps (trans->sinkpad)) {
|
if (!gst_pad_has_current_caps (trans->sinkpad)) {
|
||||||
/* Buffer has no caps. See if the output pad only supports fixed caps */
|
/* No caps. See if the output pad only supports fixed caps */
|
||||||
|
GstCapsFilter *filter = GST_CAPSFILTER (trans);
|
||||||
GstCaps *out_caps;
|
GstCaps *out_caps;
|
||||||
|
GstEvent *pending_segment = filter->pending_segment;
|
||||||
|
|
||||||
GST_LOG_OBJECT (trans, "Input pad does not have caps");
|
GST_LOG_OBJECT (trans, "Input pad does not have caps");
|
||||||
|
|
||||||
|
filter->pending_segment = NULL;
|
||||||
|
g_return_val_if_fail (pending_segment != NULL || trans->have_segment,
|
||||||
|
GST_FLOW_ERROR);
|
||||||
|
|
||||||
out_caps = gst_pad_get_current_caps (trans->srcpad);
|
out_caps = gst_pad_get_current_caps (trans->srcpad);
|
||||||
if (out_caps == NULL) {
|
if (out_caps == NULL) {
|
||||||
out_caps = gst_pad_get_allowed_caps (trans->srcpad);
|
out_caps = gst_pad_get_allowed_caps (trans->srcpad);
|
||||||
|
@ -307,6 +317,11 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
|
||||||
if (!gst_pad_has_current_caps (trans->srcpad))
|
if (!gst_pad_has_current_caps (trans->srcpad))
|
||||||
if (!gst_pad_set_caps (trans->srcpad, out_caps))
|
if (!gst_pad_set_caps (trans->srcpad, out_caps))
|
||||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
|
if (pending_segment)
|
||||||
|
GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans,
|
||||||
|
pending_segment);
|
||||||
|
|
||||||
gst_caps_unref (out_caps);
|
gst_caps_unref (out_caps);
|
||||||
} else {
|
} else {
|
||||||
gchar *caps_str = gst_caps_to_string (out_caps);
|
gchar *caps_str = gst_caps_to_string (out_caps);
|
||||||
|
@ -315,13 +330,33 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
|
||||||
GST_PTR_FORMAT, out_caps);
|
GST_PTR_FORMAT, out_caps);
|
||||||
gst_caps_unref (out_caps);
|
gst_caps_unref (out_caps);
|
||||||
|
|
||||||
ret = GST_FLOW_ERROR;
|
|
||||||
GST_ELEMENT_ERROR (trans, STREAM, FORMAT,
|
GST_ELEMENT_ERROR (trans, STREAM, FORMAT,
|
||||||
("Filter caps do not completely specify the output format"),
|
("Filter caps do not completely specify the output format"),
|
||||||
("Output caps are unfixed: %s", caps_str));
|
("Output caps are unfixed: %s", caps_str));
|
||||||
|
|
||||||
g_free (caps_str);
|
g_free (caps_str);
|
||||||
|
gst_event_unref (pending_segment);
|
||||||
|
|
||||||
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Queue the segment event if there was no caps event */
|
||||||
|
static gboolean
|
||||||
|
gst_capsfilter_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
|
{
|
||||||
|
if (GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (!gst_pad_has_current_caps (trans->sinkpad)) {
|
||||||
|
GST_LOG_OBJECT (trans, "Got segment without caps, queue segment event");
|
||||||
|
gst_event_replace (&GST_CAPSFILTER (trans)->pending_segment, event);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct _GstCapsFilter {
|
||||||
GstBaseTransform trans;
|
GstBaseTransform trans;
|
||||||
|
|
||||||
GstCaps *filter_caps;
|
GstCaps *filter_caps;
|
||||||
|
GstEvent *pending_segment;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstCapsFilterClass {
|
struct _GstCapsFilterClass {
|
||||||
|
|
Loading…
Reference in a new issue