baseparse: refactor passthrough into format flags
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 10 Jan 2011 15:56:36 +0000 (16:56 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 28 Jan 2011 11:16:57 +0000 (12:16 +0100)
Also add a format flag to signal baseparse that subclass/format can provide
(parsed) timestamp rather than an estimated one.  In particular, such "strong"
timestamp then allows to e.g. determine duration.

gst/audioparsers/gstaacparse.c
gst/audioparsers/gstbaseparse.c
gst/audioparsers/gstbaseparse.h
gst/audioparsers/gstflacparse.c

index 140f5e4..09e3e71 100644 (file)
@@ -267,7 +267,8 @@ gst_aacparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
 
       /* arrange for metadata and get out of the way */
       gst_aacparse_set_src_caps (aacparse, caps);
-      gst_base_parse_set_passthrough (parse, TRUE);
+      gst_base_parse_set_format (parse,
+          GST_BASE_PARSE_FORMAT_PASSTHROUGH, TRUE);
     } else
       return FALSE;
 
@@ -542,7 +543,8 @@ gst_aacparse_detect_stream (GstAacParse * aacparse,
     /* arrange for metadata and get out of the way */
     gst_aacparse_set_src_caps (aacparse,
         GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (aacparse)));
-    gst_base_parse_set_passthrough (GST_BASE_PARSE (aacparse), TRUE);
+    gst_base_parse_set_format (GST_BASE_PARSE (aacparse),
+        GST_BASE_PARSE_FORMAT_PASSTHROUGH, TRUE);
 
     *framesize = avail;
     return TRUE;
@@ -693,7 +695,6 @@ gst_aacparse_start (GstBaseParse * parse)
   aacparse = GST_AACPARSE (parse);
   GST_DEBUG ("start");
   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
-  gst_base_parse_set_passthrough (parse, FALSE);
   return TRUE;
 }
 
index 9189846..a4505c1 100644 (file)
  *      Update the duration information with @gst_base_parse_set_duration
  *   </para></listitem>
  *   <listitem><para>
- *      Optionally passthrough using @gst_base_parse_set_passthrough
+ *      Optionally passthrough using @gst_base_parse_set_format
  *   </para></listitem>
  *   <listitem><para>
  *      Configure various baseparse parameters using @gst_base_parse_set_seek and
@@ -220,7 +220,7 @@ struct _GstBaseParsePrivate
   gint64 estimated_duration;
 
   guint min_frame_size;
-  gboolean passthrough;
+  guint format;
   guint fps_num, fps_den;
   guint update_interval;
   guint bitrate;
@@ -294,6 +294,12 @@ typedef struct _GstBaseParseSeek
   GstClockTime start_ts;
 } GstBaseParseSeek;
 
+#define GST_BASE_PARSE_PASSTHROUGH(parse)  \
+    (parse->priv->format & GST_BASE_PARSE_FORMAT_PASSTHROUGH)
+#define GST_BASE_PARSE_HAS_TIME(parse)  \
+    (parse->priv->format & GST_BASE_PARSE_FORMAT_HAS_TIME)
+
+
 static GstElementClass *parent_class = NULL;
 
 static void gst_base_parse_class_init (GstBaseParseClass * klass);
@@ -571,7 +577,7 @@ gst_base_parse_reset (GstBaseParse * parse)
   parse->priv->first_frame_offset = -1;
   parse->priv->estimated_duration = -1;
   parse->priv->next_ts = 0;
-  parse->priv->passthrough = FALSE;
+  parse->priv->format = 0;
   parse->priv->post_min_bitrate = TRUE;
   parse->priv->post_avg_bitrate = TRUE;
   parse->priv->post_max_bitrate = TRUE;
@@ -1471,10 +1477,11 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
   /* subclass must play nice */
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
 
-  /* check initial frame to determine if subclass/format can provide ts.
+  /* check if subclass/format can provide ts.
    * If so, that allows and enables extra seek and duration determining options */
   if (G_UNLIKELY (parse->priv->first_frame_offset < 0 && ret == GST_FLOW_OK)) {
     if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
+        GST_BASE_PARSE_HAS_TIME (parse) &&
         parse->priv->pad_mode == GST_ACTIVATE_PULL) {
       parse->priv->first_frame_offset = offset;
       parse->priv->first_frame_ts = GST_BUFFER_TIMESTAMP (buffer);
@@ -1583,7 +1590,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR);
 
   /* segment adjustment magic; only if we are running the whole show */
-  if (!parse->priv->passthrough && parse->segment.rate > 0.0 &&
+  if (!GST_BASE_PARSE_PASSTHROUGH (parse) && parse->segment.rate > 0.0 &&
       (parse->priv->pad_mode == GST_ACTIVATE_PULL ||
           parse->priv->upstream_seekable)) {
     /* segment times are typically estimates,
@@ -1748,7 +1755,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
         GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret));
     /* if we are not sufficiently in control, let upstream decide on EOS */
     if (ret == GST_FLOW_UNEXPECTED &&
-        (parse->priv->passthrough ||
+        (GST_BASE_PARSE_PASSTHROUGH (parse) ||
             (parse->priv->pad_mode == GST_ACTIVATE_PUSH &&
                 !parse->priv->upstream_seekable)))
       ret = GST_FLOW_OK;
@@ -1957,7 +1964,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
   if (G_LIKELY (buffer)) {
     GST_LOG_OBJECT (parse, "buffer size: %d, offset = %" G_GINT64_FORMAT,
         GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer));
-    if (G_UNLIKELY (parse->priv->passthrough)) {
+    if (G_UNLIKELY (GST_BASE_PARSE_PASSTHROUGH (parse))) {
       frame->buffer = gst_buffer_make_metadata_writable (buffer);
       return gst_base_parse_push_frame (parse, frame);
     }
@@ -2722,24 +2729,24 @@ gst_base_parse_set_min_frame_size (GstBaseParse * parse, guint min_size)
 }
 
 /**
- * gst_base_parse_set_passthrough:
- * @parse: the #GstBaseParse to set
- * @passthrough: boolean indicating passthrough mode.
+ * gst_base_parse_set_format:
+ * @parse: the #GstBaseParseFormat to set or unset
+ * @flags: format flag to enable or disable
+ * @on: whether or not to enable
  *
- * Set passthrough mode for this parser (which only applies operating in pull
- * mode).  If operating in passthrough, incoming buffers are pushed through
- * unmodified.  That is, no @check_valid_frame or @parse_frame callbacks
- * will be invoked.  On the ohter hand, @pre_push_buffer is still invoked,
- * where subclass can perform as much or as little is appropriate for
- * "passthrough" semantics.
+ * Set flags describing characteristics of parsed format.
  */
 void
-gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough)
+gst_base_parse_set_format (GstBaseParse * parse, GstBaseParseFormat flag,
+    gboolean on)
 {
   g_return_if_fail (parse != NULL);
 
-  parse->priv->passthrough = passthrough;
-  GST_LOG_OBJECT (parse, "set passthrough: %d", passthrough);
+  GST_LOG_OBJECT (parse, "set flag %d to %d", flag, on);
+  if (on)
+    parse->priv->format |= flag;
+  else
+    parse->priv->format &= ~flag;
 }
 
 /**
index d5d4415..0438c42 100644 (file)
@@ -163,12 +163,33 @@ typedef struct {
  */
 #define GST_BASE_PARSE_FRAME_DRAIN(frame)    (!!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_DRAIN))
 
+/**
+ * GstBaseParseFormat:
+ * @GST_BASE_PARSE_FORMAT_NONE: default setting
+ * @GST_BASE_PARSE_FORMAT_PASSTHROUGH: nature of format or configuration
+ *   does not allow (much) parsing, so parser should operate in passthrough mode
+ *   (which only applies operating in pull mode).  That is, incoming buffers
+ *   are pushed through unmodified, i.e. no @check_valid_frame or @parse_frame
+ *   callbacks will be invoked.  On the other hand, @pre_push_buffer is still invoked,
+ *   where subclass can perform as much or as little is appropriate for
+ *   "passthrough" semantics.
+ * @GST_BASE_PARSE_FORMAT_HAS_TIME: frames carry timing info which subclass
+ *   can (generally) parse and provide.  In particular, intrinsic time
+ *   (rather than estimated) can be obtained following seek.
+ *
+ * Since: 0.10.x
+ */
+typedef enum _GstBaseParseFormat {
+  GST_BASE_PARSE_FORMAT_NONE               = 0,
+  GST_BASE_PARSE_FORMAT_PASSTHROUGH        = (1 << 0),
+  GST_BASE_PARSE_FORMAT_HAS_TIME           = (1 << 1),
+} GstBaseParseFormat;
 
 /**
  * GstBaseParseSeekable:
  * @GST_BASE_PARSE_SEEK_NONE: No seeking possible.
- * GST_BASE_PARSE_SEEK_DEFAULT: Default seeking possible using estimated bitrate.
- * GST_BASE_PARSE_SEEK_TABLE: Additional metadata provides more accurate seeking.
+ * @GST_BASE_PARSE_SEEK_DEFAULT: Default seeking possible using estimated bitrate.
+ * @GST_BASE_PARSE_SEEK_TABLE: Additional metadata provides more accurate seeking.
  *
  * Indicates what level (of quality) of seeking is possible.
  *
@@ -317,7 +338,8 @@ void gst_base_parse_set_seek (GstBaseParse * parse,
 
 void gst_base_parse_set_min_frame_size (GstBaseParse *parse, guint min_size);
 
-void gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough);
+void gst_base_parse_set_format (GstBaseParse * parse, GstBaseParseFormat flag,
+                                gboolean on);
 
 void gst_base_parse_set_frame_props (GstBaseParse * parse, guint fps_num,
                                      guint fps_den, guint lead_in, guint lead_out);
index f991095..8306e8e 100644 (file)
@@ -326,6 +326,9 @@ gst_flac_parse_start (GstBaseParse * parse)
 
   /* "fLaC" marker */
   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
+  /* inform baseclass we can come up with ts, based on counters in packets */
+  gst_base_parse_set_format (GST_BASE_PARSE (flacparse),
+      GST_BASE_PARSE_FORMAT_HAS_TIME, TRUE);
 
   return TRUE;
 }