Commit 30be0300 authored by Mark Nauwelaerts's avatar Mark Nauwelaerts Committed by Tim-Philipp Müller

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.
parent dc6bd085
......@@ -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 */
......
......@@ -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];
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment