From 82a6cb39ae9f46d3381e70696a5d2345e01728a1 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 17 May 2011 22:15:38 +0200 Subject: [PATCH] baseparse: make minimum frame size handling more efficient and convenient While some formats allow subclass to determine a specific subsequent needed frame size, others may to need to scan for markers and can only request 'additional data' by whatever reasonable available step. In push mode, trying to minimize additional latency leads to step size being the next input buffer. In pull mode, any reasonable step size (such as already used by buffer caching) can be applied. --- libs/gst/base/gstbaseparse.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 357788d..ef6bff0 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -82,7 +82,11 @@ * contain a valid frame, this call must return FALSE and optionally * set the @skipsize value to inform base class that how many bytes * it needs to skip in order to find a valid frame. @framesize can always - * indicate a new minimum for current frame parsing. The passed buffer + * indicate a new minimum for current frame parsing. Indicating G_MAXUINT + * for requested amount means subclass simply needs best available + * subsequent data. In push mode this amounts to an additional input buffer + * (thus minimal additional latency), in pull mode this amounts to some + * arbitrary reasonable buffer size increase. The passed buffer * is read-only. Note that @check_valid_frame might receive any small * amount of input data when leftover data is being drained (e.g. at EOS). * @@ -2196,6 +2200,8 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) old_min_size = 0; /* Synchronization loop */ for (;;) { + /* note: if subclass indicates MAX fsize, + * this will not likely be available anyway ... */ min_size = MAX (parse->priv->min_frame_size, fsize); av = gst_adapter_available (parse->priv->adapter); @@ -2497,6 +2503,12 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass, GST_LOG_OBJECT (parse, "scanning for frame at offset %" G_GUINT64_FORMAT " (%#" G_GINT64_MODIFIER "x)", parse->priv->offset, parse->priv->offset); + /* let's make this efficient for all subclass once and for all; + * maybe it does not need this much, but in the latter case, we know we are + * in pull mode here and might as well try to read and supply more anyway + * (so does the buffer caching mechanism) */ + fsize = 64 * 1024; + while (TRUE) { gboolean res; @@ -2547,7 +2559,9 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass, if (!parse->priv->discont) parse->priv->sync_offset = parse->priv->offset; parse->priv->discont = TRUE; - /* something changed least; nullify loop check */ + /* something changed at least; nullify loop check */ + if (fsize == G_MAXUINT) + fsize = old_min_size + 64 * 1024; old_min_size = 0; } /* skip == 0 should imply subclass set min_size to need more data; -- 2.7.4