/**
* SECTION:gstbasesink
+ * @title: GstBaseSink
* @short_description: Base class for sink elements
* @see_also: #GstBaseTransform, #GstBaseSrc
*
* "Sink name",
* "Sink",
* "My Sink element",
- * "The author <my.sink@my.email>");
+ * "The author <my.sink@my.email>");
* }
* ]|
*
* should configure itself to process a specific media type.
*
* The #GstBaseSinkClass.start() and #GstBaseSinkClass.stop() virtual methods
- * will be called when resources should be allocated. Any
+ * will be called when resources should be allocated. Any
* #GstBaseSinkClass.preroll(), #GstBaseSinkClass.render() and
* #GstBaseSinkClass.set_caps() function will be called between the
* #GstBaseSinkClass.start() and #GstBaseSinkClass.stop() calls.
*
* Set the time that will be inserted between rendered buffers. This
* can be used to control the maximum buffers per second that the sink
- * will render.
+ * will render.
*/
void
gst_base_sink_set_throttle_time (GstBaseSink * sink, guint64 throttle)
* gst_base_sink_get_throttle_time:
* @sink: a #GstBaseSink
*
- * Get the time that will be inserted between frames to control the
+ * Get the time that will be inserted between frames to control the
* maximum buffers per second.
*
* Returns: the number of nanoseconds @sink will put between frames.
* against the clock it must unblock when going from PLAYING to the PAUSED state
* and call this method before continuing to render the remaining data.
*
+ * If the #GstBaseSinkClass.render() method can block on something else than
+ * the clock, it must also be ready to unblock immediately on
+ * the #GstBaseSinkClass.unlock() method and cause the
+ * #GstBaseSinkClass.render() method to immediately call this function.
+ * In this case, the subclass must be prepared to continue rendering where it
+ * left off if this function returns %GST_FLOW_OK.
+ *
* This function will block until a state change to PLAYING happens (in which
* case this function returns %GST_FLOW_OK) or the processing must be stopped due
* to a state change to READY or a FLUSH event (in which case this function
}
}
+ /* We are about to prepare the first frame, make sure we have prerolled
+ * already. This prevent nesting prepare/render calls. */
+ ret = gst_base_sink_do_preroll (basesink, obj);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
+ goto preroll_failed;
+
if (G_UNLIKELY (late))
goto dropped;
}
goto done;
}
+preroll_failed:
+ {
+ GST_DEBUG_OBJECT (basesink, "preroll failed: %s", gst_flow_get_name (ret));
+ return ret;
+ }
}
/* with STREAM_LOCK
}
} else if (result == GST_FLOW_NOT_LINKED || result <= GST_FLOW_EOS) {
/* for fatal errors we post an error message, post the error
- * first so the app knows about the error first.
+ * first so the app knows about the error first.
* wrong-state is not a fatal error because it happens due to
* flushing and posting an error message in that case is the
* wrong thing to do, e.g. when basesrc is doing a flushing
}
if (forward) {
+ GST_DEBUG_OBJECT (basesink, "sending event %p %" GST_PTR_FORMAT, event,
+ event);
result = gst_pad_push_event (pad, event);
} else {
/* not forwarded, unref the event */
gst_object_unref (pad);
- GST_DEBUG_OBJECT (basesink, "handled event %p %" GST_PTR_FORMAT ": %d", event,
- event, result);
+ GST_DEBUG_OBJECT (basesink, "handled event: %d", result);
return result;
}