From: Mark Nauwelaerts Date: Fri, 17 Sep 2010 15:21:46 +0000 (+0200) Subject: baseparse: add another hook for subclass prior to pushing buffer X-Git-Tag: RELEASE-0.10.29~361 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=30be03004e82bd4be94444c6da92910da9ffc7ce;p=platform%2Fupstream%2Fgst-plugins-good.git baseparse: add another hook for subclass prior to pushing buffer ... and allow subclass to perform custom segment clipping, or to emit tags or messages at this time. --- diff --git a/gst/audioparsers/gstbaseparse.c b/gst/audioparsers/gstbaseparse.c index 9473633f4..23ea2b066 100644 --- a/gst/audioparsers/gstbaseparse.c +++ b/gst/audioparsers/gstbaseparse.c @@ -1063,6 +1063,7 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer) GstFlowReturn ret = GST_FLOW_OK; GstClockTime last_start = GST_CLOCK_TIME_NONE; GstClockTime last_stop = GST_CLOCK_TIME_NONE; + GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse); GST_LOG_OBJECT (parse, "processing buffer of size %d with ts %" GST_TIME_FORMAT @@ -1142,24 +1143,42 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer) /* TODO: Add to seek table */ - if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && - GST_CLOCK_TIME_IS_VALID (parse->segment.stop) && - GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) { - 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"); + if (klass->pre_push_buffer) + ret = klass->pre_push_buffer (parse, buffer); + else + ret = GST_BASE_PARSE_FLOW_CLIP; + + if (ret == GST_BASE_PARSE_FLOW_CLIP) { + if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && + GST_CLOCK_TIME_IS_VALID (parse->segment.stop) && + GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) { + GST_LOG_OBJECT (parse, "Dropped frame, after segment"); + ret = GST_FLOW_UNEXPECTED; + } 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) { + GST_LOG_OBJECT (parse, "Dropped frame, before segment"); + ret = GST_BASE_PARSE_FLOW_DROPPED; + } else { + ret = GST_FLOW_OK; + } + } + + if (ret == GST_BASE_PARSE_FLOW_DROPPED) { + GST_LOG_OBJECT (parse, "frame (%d bytes) dropped", + GST_BUFFER_SIZE (buffer)); gst_buffer_unref (buffer); - } else { + ret = GST_FLOW_OK; + } else if (ret == GST_FLOW_OK) { ret = gst_pad_push (parse->srcpad, buffer); - GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d", - GST_BUFFER_SIZE (buffer), ret); + GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %s", + GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret)); + } else { + gst_buffer_unref (buffer); + GST_LOG_OBJECT (parse, "frame (%d bytes) not pushed: %s", + GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret)); } /* Update current running segment position */ diff --git a/gst/audioparsers/gstbaseparse.h b/gst/audioparsers/gstbaseparse.h index 8df1d88dc..b31c8530f 100644 --- a/gst/audioparsers/gstbaseparse.h +++ b/gst/audioparsers/gstbaseparse.h @@ -68,16 +68,37 @@ G_BEGIN_DECLS */ #define GST_BASE_PARSE_SINK_PAD(obj) (GST_BASE_PARSE_CAST (obj)->sinkpad) +/** + * GST_BASE_PARSE_SEGMENT: + * @obj: base parse instance + * + * Gives the segment of the element. + * + * Since: 0.10.x + */ +#define GST_BASE_PARSE_SEGMENT(obj) (GST_BASE_PARSE_CAST (obj)->segment) + /** * GST_BASE_PARSE_FLOW_DROPPED: * * A #GstFlowReturn that can be returned from parse_frame to - * indicate that no output buffer was generated. + * indicate that no output buffer was generated, or from pre_push_buffer to + * to forego pushing buffer. * * Since: 0.10.x */ #define GST_BASE_PARSE_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS +/** + * GST_BASE_PARSE_FLOW_CLIP: + * + * A #GstFlowReturn that can be returned from pre_push_buffer to + * indicate that regular segment clipping should be performed. + * + * Since: 0.10.x + */ +#define GST_BASE_PARSE_FLOW_CLIP GST_FLOW_CUSTOM_SUCCESS_1 + /** * GST_BASE_PARSE_BUFFER_FLAG_NO_FRAME: * @@ -186,6 +207,13 @@ struct _GstBaseParse { * this returns -1, it is assumed that this frame should * be skipped in bitrate calculation. * + * @pre_push_buffer: Optional. + * Called just prior to pushing a frame (after any pending + * events have been sent) to give subclass a chance to perform + * additional actions at this time (e.g. tag sending) or to + * decide whether this buffer should be dropped or no + * (e.g. custom segment clipping). + * * Subclasses can override any of the available virtual methods or not, as * needed. At minimum @check_valid_frame and @parse_frame needs to be * overridden. @@ -233,6 +261,9 @@ struct _GstBaseParseClass { gint (*get_frame_overhead) (GstBaseParse *parse, GstBuffer *buf); + GstFlowReturn (*pre_push_buffer) (GstBaseParse *parse, + GstBuffer *buf); + /*< private >*/ gpointer _gst_reserved[GST_PADDING_LARGE]; };