[gst-cvs] gst-plugins-bad: baseparse: add another hook for subclass prior to pushing buffer
Mark Nauwelaerts
mnauw at kemper.freedesktop.org
Fri Oct 1 03:53:45 PDT 2010
Module: gst-plugins-bad
Branch: master
Commit: 582b756bc1ce80a709aa62a347dfae0120a86060
URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=582b756bc1ce80a709aa62a347dfae0120a86060
Author: Mark Nauwelaerts <mark.nauwelaerts at collabora.co.uk>
Date: Fri Sep 17 17:21:46 2010 +0200
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.
---
gst/audioparsers/gstbaseparse.c | 51 ++++++++++++++++++++++++++------------
gst/audioparsers/gstbaseparse.h | 33 ++++++++++++++++++++++++-
2 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/gst/audioparsers/gstbaseparse.c b/gst/audioparsers/gstbaseparse.c
index 9473633..23ea2b0 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 8df1d88..b31c853 100644
--- a/gst/audioparsers/gstbaseparse.h
+++ b/gst/audioparsers/gstbaseparse.h
@@ -69,16 +69,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:
*
* A #GstBufferFlag that can be set to have this buffer not counted as 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];
};
More information about the Gstreamer-commits
mailing list