aacparse: Add function for the baseparse subclass to push buffers downstream

Also handle the case gracefully where the subclass decides to drop
the first buffers and has no caps set yet. It's still required to
have valid caps set when the first buffer should be passed downstream.
This commit is contained in:
Sebastian Dröge 2009-07-14 14:08:04 +02:00 committed by Tim-Philipp Müller
parent c83364ee81
commit bfe54aff4b
2 changed files with 60 additions and 27 deletions

View file

@ -735,7 +735,6 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
GstBaseParseClass * klass, GstBuffer * buffer) GstBaseParseClass * klass, GstBuffer * buffer)
{ {
GstFlowReturn ret; GstFlowReturn ret;
GstClockTime last_stop = GST_CLOCK_TIME_NONE;
if (parse->priv->discont) { if (parse->priv->discont) {
GST_DEBUG_OBJECT (parse, "marking DISCONT"); GST_DEBUG_OBJECT (parse, "marking DISCONT");
@ -749,6 +748,46 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
* keep track of timestamp and calculate everything possible * keep track of timestamp and calculate everything possible
* if not set already */ * if not set already */
/* First buffers are dropped, this means that the subclass needs more
* frames to decide on the format and queues them internally */
if (ret == GST_BASE_PARSE_FLOW_DROPPED && !GST_PAD_CAPS (parse->srcpad)) {
gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
/* convert internal flow to OK and mark discont for the next buffer. */
if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
parse->priv->discont = TRUE;
ret = GST_FLOW_OK;
gst_buffer_unref (buffer);
return ret;
} else if (ret != GST_FLOW_OK) {
return ret;
}
return gst_base_parse_push_buffer (parse, buffer);
}
/**
* gst_base_parse_push_buffer:
* @parse: #GstBaseParse.
* @buffer: #GstBuffer.
*
* Pushes the buffer downstream, sends any pending events and
* does some timestamp and segment handling.
*
* This must be called with srcpad STREAM_LOCK held.
*
* Returns: #GstFlowReturn
*/
GstFlowReturn
gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
{
GstFlowReturn ret = GST_FLOW_OK;
GstClockTime last_stop = GST_CLOCK_TIME_NONE;
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
last_stop = GST_BUFFER_TIMESTAMP (buffer); last_stop = GST_BUFFER_TIMESTAMP (buffer);
if (last_stop != GST_CLOCK_TIME_NONE && GST_BUFFER_DURATION_IS_VALID (buffer)) if (last_stop != GST_CLOCK_TIME_NONE && GST_BUFFER_DURATION_IS_VALID (buffer))
@ -792,39 +831,30 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
/* TODO: Add to seek table */ /* TODO: Add to seek table */
if (ret == GST_FLOW_OK) { if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
GST_CLOCK_TIME_IS_VALID (parse->segment.stop) && GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) { GST_LOG_OBJECT (parse, "Dropped frame, after segment");
GST_LOG_OBJECT (parse, "Dropped frame, after segment");
gst_buffer_unref (buffer);
} else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
GST_BUFFER_DURATION_IS_VALID (buffer) &&
GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer)
< parse->segment.start) {
/* FIXME: subclass needs way to override the start as downstream might
* need frames before for proper decoding */
GST_LOG_OBJECT (parse, "Dropped frame, before segment");
gst_buffer_unref (buffer);
} else {
ret = gst_pad_push (parse->srcpad, buffer);
GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d",
GST_BUFFER_SIZE (buffer), ret);
}
} else {
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
} else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
GST_BUFFER_DURATION_IS_VALID (buffer) &&
GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer)
< parse->segment.start) {
/* FIXME: subclass needs way to override the start as downstream might
* need frames before for proper decoding */
GST_LOG_OBJECT (parse, "Dropped frame, before segment");
gst_buffer_unref (buffer);
} else {
ret = gst_pad_push (parse->srcpad, buffer);
GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d",
GST_BUFFER_SIZE (buffer), ret);
} }
/* Update current running segment position */ /* Update current running segment position */
if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE) if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE)
gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop); gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop);
/* convert internal flow to OK and mark discont for the next buffer. */
if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
parse->priv->discont = TRUE;
ret = GST_FLOW_OK;
}
return ret; return ret;
} }

View file

@ -225,6 +225,9 @@ struct _GstBaseParseClass {
GType gst_base_parse_get_type (void); GType gst_base_parse_get_type (void);
GstFlowReturn gst_base_parse_push_buffer (GstBaseParse *parse,
GstBuffer *buffer);
void gst_base_parse_set_duration (GstBaseParse *parse, void gst_base_parse_set_duration (GstBaseParse *parse,
GstFormat fmt, GstFormat fmt,
gint64 duration); gint64 duration);