audioparsers: adjust to modified baseparse API
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Thu, 9 Feb 2012 12:41:53 +0000 (13:41 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 13 Feb 2012 17:27:53 +0000 (18:27 +0100)
gst/audioparsers/gstaacparse.c
gst/audioparsers/gstac3parse.c
gst/audioparsers/gstamrparse.c
gst/audioparsers/gstdcaparse.c
gst/audioparsers/gstflacparse.c
gst/audioparsers/gstmpegaudioparse.c

index cc91747..fed17da 100644 (file)
@@ -89,11 +89,8 @@ static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
     GstCaps * filter);
 
-static gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * size, gint * skipsize);
-
-static GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_aac_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 
 gboolean gst_aac_parse_convert (GstBaseParse * parse,
     GstFormat src_format,
@@ -146,9 +143,7 @@ gst_aac_parse_class_init (GstAacParseClass * klass)
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_parse_frame);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_aac_parse_check_valid_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_handle_frame);
 }
 
 
@@ -900,48 +895,63 @@ gst_aac_parse_detect_stream (GstAacParse * aacparse,
 /**
  * gst_aac_parse_check_valid_frame:
  * @parse: #GstBaseParse.
- * @buffer: #GstBuffer.
- * @framesize: If the buffer contains a valid frame, its size will be put here
+ * @frame: #GstBaseParseFrame.
  * @skipsize: How much data parent class should skip in order to find the
  *            frame header.
  *
- * Implementation of "check_valid_frame" vmethod in #GstBaseParse class.
+ * Implementation of "handle_frame" vmethod in #GstBaseParse class.
+ *
+ * Also determines frame overhead.
+ * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
+ * a per-frame header. LOAS has 3 bytes.
+ *
+ * We're making a couple of simplifying assumptions:
+ *
+ * 1. We count Program Configuration Elements rather than searching for them
+ *    in the streams to discount them - the overhead is negligible.
+ *
+ * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
+ *    bits, which should still not be significant enough to warrant the
+ *    additional parsing through the headers
  *
- * Returns: TRUE if buffer contains a valid frame.
+ * Returns: a #GstFlowReturn.
  */
-static gboolean
-gst_aac_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_aac_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstMapInfo map;
   GstAacParse *aacparse;
   gboolean ret = FALSE;
   gboolean lost_sync;
   GstBuffer *buffer;
+  guint framesize;
+  gint rate, channels;
 
   aacparse = GST_AAC_PARSE (parse);
   buffer = frame->buffer;
 
   gst_buffer_map (buffer, &map, GST_MAP_READ);
 
+  *skipsize = -1;
   lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
 
   if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
       aacparse->header_type == DSPAAC_HEADER_NONE) {
     /* There is nothing to parse */
-    *framesize = map.size;
+    framesize = map.size;
     ret = TRUE;
 
   } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
 
     ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
-        GST_BASE_PARSE_DRAINING (parse), framesize, skipsize);
+        GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
 
   } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
     guint needed_data = 1024;
 
     ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
-        GST_BASE_PARSE_DRAINING (parse), framesize, &needed_data);
+        GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
 
     if (!ret) {
       GST_DEBUG ("buffer didn't contain valid frame");
@@ -953,7 +963,7 @@ gst_aac_parse_check_valid_frame (GstBaseParse * parse,
     guint needed_data = 1024;
 
     ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
-        map.size, GST_BASE_PARSE_DRAINING (parse), framesize, &needed_data);
+        map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
 
     if (!ret) {
       GST_DEBUG ("buffer didn't contain valid frame");
@@ -966,72 +976,29 @@ gst_aac_parse_check_valid_frame (GstBaseParse * parse,
     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
         ADTS_MAX_SIZE);
   }
-  gst_buffer_unmap (buffer, &map);
-
-  return ret;
-}
 
-
-/**
- * gst_aac_parse_parse_frame:
- * @parse: #GstBaseParse.
- * @buffer: #GstBuffer.
- *
- * Implementation of "parse_frame" vmethod in #GstBaseParse class.
- *
- * Also determines frame overhead.
- * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
- * a per-frame header. LOAS has 3 bytes.
- *
- * We're making a couple of simplifying assumptions:
- *
- * 1. We count Program Configuration Elements rather than searching for them
- *    in the streams to discount them - the overhead is negligible.
- *
- * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
- *    bits, which should still not be significant enough to warrant the
- *    additional parsing through the headers
- *
- * Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed
- *          forward. Otherwise appropriate error is returned.
- */
-static GstFlowReturn
-gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
-  GstAacParse *aacparse;
-  GstBuffer *buffer;
-  GstFlowReturn ret = GST_FLOW_OK;
-  gint rate, channels;
-  GstMapInfo map;
-
-  aacparse = GST_AAC_PARSE (parse);
-  buffer = frame->buffer;
+  if (G_UNLIKELY (!ret))
+    goto exit;
 
   if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
     /* see above */
     frame->overhead = 7;
 
-    gst_buffer_map (buffer, &map, GST_MAP_READ);
     gst_aac_parse_parse_adts_header (aacparse, map.data,
         &rate, &channels, NULL, NULL);
-    gst_buffer_unmap (buffer, &map);
 
     GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
 
     if (G_UNLIKELY (rate != aacparse->sample_rate
             || channels != aacparse->channels)) {
-      GstCaps *sinkcaps;
-
       aacparse->sample_rate = rate;
       aacparse->channels = channels;
 
-      if ((sinkcaps =
-              gst_pad_get_current_caps (GST_BASE_PARSE (aacparse)->sinkpad))) {
-        if (!gst_aac_parse_set_src_caps (aacparse, sinkcaps)) {
-          /* If linking fails, we need to return appropriate error */
-          ret = GST_FLOW_NOT_LINKED;
-        }
-        gst_caps_unref (sinkcaps);
+      GST_DEBUG_OBJECT (aacparse, "here");
+
+      if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
+        /* If linking fails, we need to return appropriate error */
+        ret = GST_FLOW_NOT_LINKED;
       }
 
       gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
@@ -1043,7 +1010,6 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     /* see above */
     frame->overhead = 3;
 
-    gst_buffer_map (buffer, &map, GST_MAP_READ);
     if (!gst_aac_parse_read_loas_config (aacparse, map.data, map.size, &rate,
             &channels, NULL)) {
       GST_WARNING_OBJECT (aacparse, "Error reading LOAS config");
@@ -1055,22 +1021,15 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
       GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
           channels);
     }
-    gst_buffer_unmap (buffer, &map);
 
     /* We want to set caps both at start, and when rate/channels change.
        Since only some LOAS frames have that info, we may receive frames
        before knowing about rate/channels. */
     if (setcaps
         || !gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse))) {
-      GstCaps *sinkcaps;
-
-      if ((sinkcaps =
-              gst_pad_get_current_caps (GST_BASE_PARSE (aacparse)->sinkpad))) {
-        if (!gst_aac_parse_set_src_caps (aacparse, sinkcaps)) {
-          /* If linking fails, we need to return appropriate error */
-          ret = GST_FLOW_NOT_LINKED;
-        }
-        gst_caps_unref (sinkcaps);
+      if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
+        /* If linking fails, we need to return appropriate error */
+        ret = GST_FLOW_NOT_LINKED;
       }
 
       gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
@@ -1078,7 +1037,24 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     }
   }
 
-  return ret;
+exit:
+  gst_buffer_unmap (buffer, &map);
+
+  if (ret) {
+    /* found, skip if needed */
+    if (*skipsize > 0)
+      return GST_FLOW_OK;
+    *skipsize = 0;
+  } else {
+    if (*skipsize < 0)
+      *skipsize = 1;
+  }
+
+  if (ret && framesize <= map.size) {
+    return gst_base_parse_finish_frame (parse, frame, framesize);
+  }
+
+  return GST_FLOW_OK;
 }
 
 
index 9b1a365..f88972f 100644 (file)
@@ -159,10 +159,8 @@ static void gst_ac3_parse_finalize (GObject * object);
 
 static gboolean gst_ac3_parse_start (GstBaseParse * parse);
 static gboolean gst_ac3_parse_stop (GstBaseParse * parse);
-static gboolean gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * size, gint * skipsize);
-static GstFlowReturn gst_ac3_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_ac3_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static gboolean gst_ac3_parse_src_event (GstBaseParse * parse,
     GstEvent * event);
 static GstCaps *gst_ac3_parse_get_sink_caps (GstBaseParse * parse,
@@ -194,9 +192,7 @@ gst_ac3_parse_class_init (GstAc3ParseClass * klass)
 
   parse_class->start = GST_DEBUG_FUNCPTR (gst_ac3_parse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_ac3_parse_stop);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_ac3_parse_check_valid_frame);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_parse_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_handle_frame);
   parse_class->src_event = GST_DEBUG_FUNCPTR (gst_ac3_parse_src_event);
   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_ac3_parse_get_sink_caps);
 }
@@ -481,9 +477,9 @@ cleanup:
   return ret;
 }
 
-static gboolean
-gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_ac3_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstAc3Parse *ac3parse = GST_AC3_PARSE (parse);
   GstBuffer *buf = frame->buffer;
@@ -491,14 +487,20 @@ gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
   gint off;
   gboolean lost_sync, draining, eac, more = FALSE;
   guint frmsiz, blocks, sid;
+  guint rate, chans;
+  gboolean update_rate = FALSE;
+  gint framesize = 0;
   gint have_blocks = 0;
   GstMapInfo map;
   gboolean ret = FALSE;
+  GstFlowReturn res = GST_FLOW_OK;
 
   gst_buffer_map (buf, &map, GST_MAP_READ);
 
-  if (G_UNLIKELY (map.size < 6))
+  if (G_UNLIKELY (map.size < 6)) {
+    *skipsize = 1;
     goto cleanup;
+  }
 
   gst_byte_reader_init (&reader, map.data, map.size);
   off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffff0000, 0x0b770000,
@@ -519,13 +521,16 @@ gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
   }
 
   /* make sure the values in the frame header look sane */
-  if (!gst_ac3_parse_frame_header (ac3parse, buf, 0, &frmsiz, NULL, NULL,
+  if (!gst_ac3_parse_frame_header (ac3parse, buf, 0, &frmsiz, &rate, &chans,
           &blocks, &sid, &eac)) {
     *skipsize = off + 2;
     goto cleanup;
   }
 
-  *framesize = frmsiz;
+  GST_LOG_OBJECT (parse, "size: %u, blocks: %u, rate: %u, chans: %u", frmsiz,
+      blocks, rate, chans);
+
+  framesize = frmsiz;
 
   if (G_UNLIKELY (g_atomic_int_get (&ac3parse->align) ==
           GST_AC3_PARSE_ALIGN_NONE))
@@ -550,21 +555,21 @@ gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
       goto cleanup;
     }
 
-    *framesize = 0;
+    framesize = 0;
 
     /* Loop till we have 6 blocks per substream */
     for (have_blocks = 0; !more && have_blocks < 6; have_blocks += blocks) {
       /* Loop till we get one frame from each substream */
       do {
-        *framesize += frmsiz;
+        framesize += frmsiz;
 
         if (!gst_byte_reader_skip (&reader, frmsiz)
-            || map.size < (*framesize + 6)) {
+            || map.size < (framesize + 6)) {
           more = TRUE;
           break;
         }
 
-        if (!gst_ac3_parse_frame_header (ac3parse, buf, *framesize, &frmsiz,
+        if (!gst_ac3_parse_frame_header (ac3parse, buf, framesize, &frmsiz,
                 NULL, NULL, NULL, &sid, &eac)) {
           *skipsize = off + 2;
           goto cleanup;
@@ -584,7 +589,7 @@ gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
     if (more || !gst_byte_reader_skip (&reader, frmsiz) ||
         !gst_byte_reader_get_uint16_be (&reader, &word)) {
       GST_DEBUG_OBJECT (ac3parse, "... but not sufficient data");
-      gst_base_parse_set_min_frame_size (parse, *framesize + 6);
+      gst_base_parse_set_min_frame_size (parse, framesize + 6);
       *skipsize = 0;
       goto cleanup;
     } else {
@@ -594,34 +599,16 @@ gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
         goto cleanup;
       } else {
         /* ok, got sync now, let's assume constant frame size */
-        gst_base_parse_set_min_frame_size (parse, *framesize);
+        gst_base_parse_set_min_frame_size (parse, framesize);
       }
     }
   }
 
+  /* expect to have found a frame here */
+  g_assert (framesize);
   ret = TRUE;
 
-cleanup:
-  gst_buffer_unmap (buf, &map);
-
-  return ret;
-}
-
-static GstFlowReturn
-gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
-  GstAc3Parse *ac3parse = GST_AC3_PARSE (parse);
-  GstBuffer *buf = frame->buffer;
-  guint fsize, rate, chans, blocks, sid;
-  gboolean eac, update_rate = FALSE;
-
-  if (!gst_ac3_parse_frame_header (ac3parse, buf, 0, &fsize, &rate, &chans,
-          &blocks, &sid, &eac))
-    goto broken_header;
-
-  GST_LOG_OBJECT (parse, "size: %u, blocks: %u, rate: %u, chans: %u", fsize,
-      blocks, rate, chans);
-
+  /* arrange for metadata setup */
   if (G_UNLIKELY (sid)) {
     /* dependent frame, no need to (ac)count for or consider further */
     GST_LOG_OBJECT (parse, "sid: %d", sid);
@@ -631,9 +618,9 @@ gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     /* occupies same time space as previous base frame */
     if (G_LIKELY (GST_BUFFER_TIMESTAMP (buf) >= GST_BUFFER_DURATION (buf)))
       GST_BUFFER_TIMESTAMP (buf) -= GST_BUFFER_DURATION (buf);
-    /* only return if we already arranged for caps */
+    /* only shortcut if we already arranged for caps */
     if (G_LIKELY (ac3parse->sample_rate > 0))
-      return GST_FLOW_OK;
+      goto cleanup;
   }
 
   if (G_UNLIKELY (ac3parse->sample_rate != rate || ac3parse->channels != chans
@@ -663,15 +650,14 @@ gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   if (G_UNLIKELY (update_rate))
     gst_base_parse_set_frame_rate (parse, rate, 256 * blocks, 2, 2);
 
-  return GST_FLOW_OK;
+cleanup:
+  gst_buffer_unmap (buf, &map);
 
-/* ERRORS */
-broken_header:
-  {
-    /* this really shouldn't ever happen */
-    GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), (NULL));
-    return GST_FLOW_ERROR;
+  if (ret && framesize <= map.size) {
+    res = gst_base_parse_finish_frame (parse, frame, framesize);
   }
+
+  return res;
 }
 
 static gboolean
index 974d635..28e64db 100644 (file)
@@ -79,11 +79,8 @@ static gboolean gst_amr_parse_sink_setcaps (GstBaseParse * parse,
 static GstCaps *gst_amr_parse_sink_getcaps (GstBaseParse * parse,
     GstCaps * filter);
 
-static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
-
-static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_amr_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 
 G_DEFINE_TYPE (GstAmrParse, gst_amr_parse, GST_TYPE_BASE_PARSE);
 
@@ -115,9 +112,7 @@ gst_amr_parse_class_init (GstAmrParseClass * klass)
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_amr_parse_stop);
   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_setcaps);
   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_getcaps);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_parse_frame);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_amr_parse_check_valid_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_handle_frame);
 }
 
 
@@ -254,15 +249,16 @@ gst_amr_parse_parse_header (GstAmrParse * amrparse,
  *
  * Returns: TRUE if the given data contains valid frame.
  */
-static gboolean
-gst_amr_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_amr_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstBuffer *buffer;
   GstMapInfo map;
-  gint fsize, mode, dsize;
+  gint fsize = 0, mode, dsize;
   GstAmrParse *amrparse;
-  gboolean ret = FALSE;
+  GstFlowReturn ret = GST_FLOW_OK;
+  gboolean found = FALSE;
 
   amrparse = GST_AMR_PARSE (parse);
   buffer = frame->buffer;
@@ -285,6 +281,7 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse,
     goto done;
   }
 
+  *skipsize = 1;
   /* Does this look like a possible frame header candidate? */
   if ((map.data[0] & 0x83) == 0) {
     /* Yep. Retrieve the frame size */
@@ -299,8 +296,7 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse,
      *       perform this check)
      */
     if (fsize) {
-      gboolean found = FALSE;
-
+      *skipsize = 0;
       /* in sync, no further check */
       if (!GST_BASE_PARSE_LOST_SYNC (parse)) {
         found = TRUE;
@@ -311,42 +307,20 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse,
       } else if (GST_BASE_PARSE_DRAINING (parse)) {
         /* not enough, but draining, so ok */
         found = TRUE;
-      } else {
-        /* indicate we need not skip, but need more data */
-        *skipsize = 0;
-        *framesize = fsize + 1;
-      }
-      if (found) {
-        *framesize = fsize;
-        return TRUE;
       }
     }
   }
-  GST_LOG ("sync lost");
 
 done:
   gst_buffer_unmap (buffer, &map);
 
-  return ret;
-}
-
+  if (found && fsize <= map.size) {
+    ret = gst_base_parse_finish_frame (parse, frame, fsize);
+  }
 
-/**
- * gst_amr_parse_parse_frame:
- * @parse: #GstBaseParse.
- * @buffer: #GstBuffer.
- *
- * Implementation of "parse" vmethod in #GstBaseParse class.
- *
- * Returns: #GstFlowReturn defining the parsing status.
- */
-static GstFlowReturn
-gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
-  return GST_FLOW_OK;
+  return ret;
 }
 
-
 /**
  * gst_amr_parse_start:
  * @parse: #GstBaseParse.
index 24aa2a8..b1e256b 100644 (file)
@@ -74,10 +74,8 @@ static void gst_dca_parse_finalize (GObject * object);
 
 static gboolean gst_dca_parse_start (GstBaseParse * parse);
 static gboolean gst_dca_parse_stop (GstBaseParse * parse);
-static gboolean gst_dca_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * size, gint * skipsize);
-static GstFlowReturn gst_dca_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_dca_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstCaps *gst_dca_parse_get_sink_caps (GstBaseParse * parse,
     GstCaps * filter);
 
@@ -98,9 +96,7 @@ gst_dca_parse_class_init (GstDcaParseClass * klass)
 
   parse_class->start = GST_DEBUG_FUNCPTR (gst_dca_parse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_dca_parse_stop);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_dca_parse_check_valid_frame);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_parse_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_handle_frame);
   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_dca_parse_get_sink_caps);
 
   gst_element_class_add_pad_template (element_class,
@@ -305,9 +301,9 @@ gst_dca_parse_find_sync (GstDcaParse * dcaparse, GstByteReader * reader,
   return best_offset;
 }
 
-static gboolean
-gst_dca_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_dca_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
   GstBuffer *buf = frame->buffer;
@@ -316,15 +312,19 @@ gst_dca_parse_check_valid_frame (GstBaseParse * parse,
   gboolean parser_in_sync;
   gboolean terminator;
   guint32 sync = 0;
-  guint size, rate, chans, num_blocks, samples_per_block;
+  guint size, rate, chans, num_blocks, samples_per_block, depth;
+  gint block_size;
+  gint endianness;
   gint off = -1;
   GstMapInfo map;
-  gboolean ret = FALSE;
+  GstFlowReturn ret = GST_FLOW_EOS;
 
   gst_buffer_map (buf, &map, GST_MAP_READ);
 
-  if (G_UNLIKELY (map.size < 16))
+  if (G_UNLIKELY (map.size < 16)) {
+    *skipsize = 1;
     goto cleanup;
+  }
 
   parser_in_sync = !GST_BASE_PARSE_LOST_SYNC (parse);
 
@@ -355,8 +355,8 @@ gst_dca_parse_check_valid_frame (GstBaseParse * parse,
   }
 
   /* make sure the values in the frame header look sane */
-  if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, NULL,
-          NULL, &num_blocks, &samples_per_block, &terminator)) {
+  if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, &depth,
+          &endianness, &num_blocks, &samples_per_block, &terminator)) {
     *skipsize = 4;
     goto cleanup;
   }
@@ -364,8 +364,6 @@ gst_dca_parse_check_valid_frame (GstBaseParse * parse,
   GST_LOG_OBJECT (parse, "got frame, sync %08x, size %u, rate %d, channels %d",
       sync, size, rate, chans);
 
-  *framesize = size;
-
   dcaparse->last_sync = sync;
 
   parser_draining = GST_BASE_PARSE_DRAINING (parse);
@@ -391,41 +389,18 @@ gst_dca_parse_check_valid_frame (GstBaseParse * parse,
       /* ok, got sync now, let's assume constant frame size */
       gst_base_parse_set_min_frame_size (parse, size);
     } else {
-      /* FIXME: baseparse always seems to hand us buffers of min_frame_size
-       * bytes, which is unhelpful here */
+      /* wait for some more data */
       GST_LOG_OBJECT (dcaparse,
           "next sync out of reach (%" G_GSIZE_FORMAT " < %u)", map.size,
           size + 16);
-      /* *skipsize = 0; */
-      /* return FALSE; */
+      goto cleanup;
     }
   }
 
-  ret = TRUE;
-
-cleanup:
-  gst_buffer_unmap (buf, &map);
-  return ret;
-}
-
-static GstFlowReturn
-gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
-  GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
-  GstBuffer *buf = frame->buffer;
-  GstByteReader r;
-  guint size, rate, chans, depth, block_size, num_blocks, samples_per_block;
-  gint endianness;
-  gboolean terminator;
-  GstMapInfo map;
-
-  gst_buffer_map (buf, &map, GST_MAP_READ);
-  gst_byte_reader_init (&r, map.data, map.size);
-
-  if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, &depth,
-          &endianness, &num_blocks, &samples_per_block, &terminator))
-    goto broken_header;
+  /* found frame */
+  ret = GST_FLOW_OK;
 
+  /* metadata handling */
   block_size = num_blocks * samples_per_block;
 
   if (G_UNLIKELY (dcaparse->rate != rate || dcaparse->channels != chans
@@ -453,17 +428,16 @@ gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     gst_base_parse_set_frame_rate (parse, rate, block_size, 0, 0);
   }
 
+cleanup:
   gst_buffer_unmap (buf, &map);
-  return GST_FLOW_OK;
-
-/* ERRORS */
-broken_header:
-  {
-    /* this really shouldn't ever happen */
-    GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), (NULL));
-    gst_buffer_unmap (buf, &map);
-    return GST_FLOW_ERROR;
+
+  if (ret == GST_FLOW_OK && size <= map.size) {
+    ret = gst_base_parse_finish_frame (parse, frame, size);
+  } else {
+    ret = GST_FLOW_OK;
   }
+
+  return ret;
 }
 
 static GstCaps *
index 4480b83..06a964e 100644 (file)
@@ -192,10 +192,10 @@ static void gst_flac_parse_get_property (GObject * object, guint prop_id,
 
 static gboolean gst_flac_parse_start (GstBaseParse * parse);
 static gboolean gst_flac_parse_stop (GstBaseParse * parse);
-static gboolean gst_flac_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_flac_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstFlowReturn gst_flac_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+    GstBaseParseFrame * frame, gint size);
 static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse,
     GstBaseParseFrame * frame);
 static gboolean gst_flac_parse_convert (GstBaseParse * parse,
@@ -229,9 +229,8 @@ gst_flac_parse_class_init (GstFlacParseClass * klass)
 
   baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
   baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
-  baseparse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_flac_parse_check_valid_frame);
-  baseparse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_flac_parse_parse_frame);
+  baseparse_class->handle_frame =
+      GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
   baseparse_class->pre_push_frame =
       GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
   baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
@@ -704,17 +703,21 @@ cleanup:
   return result;
 }
 
-static gboolean
-gst_flac_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_flac_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
   GstBuffer *buffer = frame->buffer;
   GstMapInfo map;
   gboolean result = TRUE;
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint framesize;
 
   gst_buffer_map (buffer, &map, GST_MAP_READ);
 
+  *skipsize = 1;
+
   if (G_UNLIKELY (map.size < 4)) {
     result = FALSE;
     goto cleanup;
@@ -723,7 +726,7 @@ gst_flac_parse_check_valid_frame (GstBaseParse * parse,
   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
     if (memcmp (map.data, "fLaC", 4) == 0) {
       GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
-      *framesize = 4;
+      framesize = 4;
       goto cleanup;
     }
     if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
@@ -744,7 +747,7 @@ gst_flac_parse_check_valid_frame (GstBaseParse * parse,
     guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));
 
     GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
-    *framesize = size;
+    framesize = size;
     goto cleanup;
   }
 
@@ -759,7 +762,7 @@ gst_flac_parse_check_valid_frame (GstBaseParse * parse,
     GST_DEBUG_OBJECT (flacparse, "Found sync code");
     ret = gst_flac_parse_frame_is_valid (flacparse, frame, &next);
     if (ret) {
-      *framesize = next;
+      framesize = next;
       goto cleanup;
     } else {
       /* If we're at EOS and the frame was not valid, drop it! */
@@ -809,7 +812,21 @@ gst_flac_parse_check_valid_frame (GstBaseParse * parse,
 
 cleanup:
   gst_buffer_unmap (buffer, &map);
-  return result;
+
+  if (result)
+    *skipsize = 0;
+
+  if (result && framesize <= map.size) {
+    ret = gst_flac_parse_parse_frame (parse, frame, framesize);
+    if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
+      frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+      ret = GST_FLOW_OK;
+    }
+    if (ret == GST_FLOW_OK)
+      ret = gst_base_parse_finish_frame (parse, frame, framesize);
+  }
+
+  return ret;
 }
 
 static gboolean
@@ -1166,6 +1183,7 @@ push_headers:
       res = FALSE;
       break;
     }
+    gst_base_parse_frame_free (&frame);
   }
   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
   g_list_free (flacparse->headers);
@@ -1291,27 +1309,28 @@ gst_flac_parse_generate_headers (GstFlacParse * flacparse)
 }
 
 static GstFlowReturn
-gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
+gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
+    gint size)
 {
   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
-  GstBuffer *buffer = frame->buffer;
+  GstBuffer *buffer = frame->buffer, *sbuffer;
   GstMapInfo map;
   GstFlowReturn res = GST_FLOW_ERROR;
 
   gst_buffer_map (buffer, &map, GST_MAP_READ);
 
   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
-    GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
-    GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
-    GST_BUFFER_OFFSET (buffer) = 0;
-    GST_BUFFER_OFFSET_END (buffer) = 0;
+    sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
+    GST_BUFFER_TIMESTAMP (sbuffer) = GST_CLOCK_TIME_NONE;
+    GST_BUFFER_DURATION (sbuffer) = GST_CLOCK_TIME_NONE;
+    GST_BUFFER_OFFSET (sbuffer) = 0;
+    GST_BUFFER_OFFSET_END (sbuffer) = 0;
 
     /* 32 bits metadata block */
     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
     flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
 
-    flacparse->headers =
-        g_list_append (flacparse->headers, gst_buffer_ref (buffer));
+    flacparse->headers = g_list_append (flacparse->headers, sbuffer);
 
     res = GST_BASE_PARSE_FLOW_DROPPED;
   } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
@@ -1326,21 +1345,23 @@ gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
 
     GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
 
+    sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
+
     switch (type) {
       case 0:                  /* STREAMINFO */
-        if (!gst_flac_parse_handle_streaminfo (flacparse, buffer))
+        if (!gst_flac_parse_handle_streaminfo (flacparse, sbuffer))
           goto cleanup;
         break;
       case 3:                  /* SEEKTABLE */
-        if (!gst_flac_parse_handle_seektable (flacparse, buffer))
+        if (!gst_flac_parse_handle_seektable (flacparse, sbuffer))
           goto cleanup;
         break;
       case 4:                  /* VORBIS_COMMENT */
-        if (!gst_flac_parse_handle_vorbiscomment (flacparse, buffer))
+        if (!gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer))
           goto cleanup;
         break;
       case 6:                  /* PICTURE */
-        if (!gst_flac_parse_handle_picture (flacparse, buffer))
+        if (!gst_flac_parse_handle_picture (flacparse, sbuffer))
           goto cleanup;
         break;
       case 1:                  /* PADDING */
@@ -1350,13 +1371,12 @@ gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
         break;
     }
 
-    GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
-    GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
-    GST_BUFFER_OFFSET (buffer) = 0;
-    GST_BUFFER_OFFSET_END (buffer) = 0;
+    GST_BUFFER_TIMESTAMP (sbuffer) = GST_CLOCK_TIME_NONE;
+    GST_BUFFER_DURATION (sbuffer) = GST_CLOCK_TIME_NONE;
+    GST_BUFFER_OFFSET (sbuffer) = 0;
+    GST_BUFFER_OFFSET_END (sbuffer) = 0;
 
-    flacparse->headers =
-        g_list_append (flacparse->headers, gst_buffer_ref (buffer));
+    flacparse->headers = g_list_append (flacparse->headers, sbuffer);
 
     if (is_last) {
       if (!gst_flac_parse_handle_headers (flacparse))
index d3dca66..1cc9f64 100644 (file)
@@ -91,10 +91,8 @@ static void gst_mpeg_audio_parse_finalize (GObject * object);
 
 static gboolean gst_mpeg_audio_parse_start (GstBaseParse * parse);
 static gboolean gst_mpeg_audio_parse_stop (GstBaseParse * parse);
-static gboolean gst_mpeg_audio_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * size, gint * skipsize);
-static GstFlowReturn gst_mpeg_audio_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_mpeg_audio_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstFlowReturn gst_mpeg_audio_parse_pre_push_frame (GstBaseParse * parse,
     GstBaseParseFrame * frame);
 static gboolean gst_mpeg_audio_parse_convert (GstBaseParse * parse,
@@ -103,6 +101,9 @@ static gboolean gst_mpeg_audio_parse_convert (GstBaseParse * parse,
 static GstCaps *gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse,
     GstCaps * filter);
 
+static void gst_mpeg_audio_parse_handle_first_frame (GstMpegAudioParse *
+    mp3parse, GstBuffer * buf);
+
 #define gst_mpeg_audio_parse_parent_class parent_class
 G_DEFINE_TYPE (GstMpegAudioParse, gst_mpeg_audio_parse, GST_TYPE_BASE_PARSE);
 
@@ -156,10 +157,8 @@ gst_mpeg_audio_parse_class_init (GstMpegAudioParseClass * klass)
 
   parse_class->start = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_stop);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_check_valid_frame);
-  parse_class->parse_frame =
-      GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_parse_frame);
+  parse_class->handle_frame =
+      GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_handle_frame);
   parse_class->pre_push_frame =
       GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_pre_push_frame);
   parse_class->convert = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_convert);
@@ -485,9 +484,9 @@ gst_mpeg_audio_parse_head_check (GstMpegAudioParse * mp3parse,
   return TRUE;
 }
 
-static gboolean
-gst_mpeg_audio_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_mpeg_audio_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstMpegAudioParse *mp3parse = GST_MPEG_AUDIO_PARSE (parse);
   GstBuffer *buf = frame->buffer;
@@ -500,8 +499,10 @@ gst_mpeg_audio_parse_check_valid_frame (GstBaseParse * parse,
   gboolean res = FALSE;
 
   gst_buffer_map (buf, &map, GST_MAP_READ);
-  if (G_UNLIKELY (map.size < 6))
+  if (G_UNLIKELY (map.size < 6)) {
+    *skipsize = 1;
     goto cleanup;
+  }
 
   gst_byte_reader_init (&reader, map.data, map.size);
 
@@ -566,12 +567,67 @@ gst_mpeg_audio_parse_check_valid_frame (GstBaseParse * parse,
   /* restore default minimum */
   gst_base_parse_set_min_frame_size (parse, MIN_FRAME_SIZE);
 
-  *framesize = bpf;
   res = TRUE;
 
+  /* metadata handling */
+  if (G_UNLIKELY (caps_change)) {
+    GstCaps *caps = gst_caps_new_simple ("audio/mpeg",
+        "mpegversion", G_TYPE_INT, 1,
+        "mpegaudioversion", G_TYPE_INT, version,
+        "layer", G_TYPE_INT, layer,
+        "rate", G_TYPE_INT, rate,
+        "channels", G_TYPE_INT, channels, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
+    gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
+    gst_caps_unref (caps);
+
+    mp3parse->rate = rate;
+    mp3parse->channels = channels;
+    mp3parse->layer = layer;
+    mp3parse->version = version;
+
+    /* see http://www.codeproject.com/audio/MPEGAudioInfo.asp */
+    if (mp3parse->layer == 1)
+      mp3parse->spf = 384;
+    else if (mp3parse->layer == 2)
+      mp3parse->spf = 1152;
+    else if (mp3parse->version == 1) {
+      mp3parse->spf = 1152;
+    } else {
+      /* MPEG-2 or "2.5" */
+      mp3parse->spf = 576;
+    }
+
+    /* lead_in:
+     * We start pushing 9 frames earlier (29 frames for MPEG2) than
+     * segment start to be able to decode the first frame we want.
+     * 9 (29) frames are the theoretical maximum of frames that contain
+     * data for the current frame (bit reservoir).
+     *
+     * lead_out:
+     * Some mp3 streams have an offset in the timestamps, for which we have to
+     * push the frame *after* the end position in order for the decoder to be
+     * able to decode everything up until the segment.stop position. */
+    gst_base_parse_set_frame_rate (parse, mp3parse->rate, mp3parse->spf,
+        (version == 1) ? 10 : 30, 2);
+  }
+
+  mp3parse->hdr_bitrate = bitrate;
+
+  /* For first frame; check for seek tables and output a codec tag */
+  gst_mpeg_audio_parse_handle_first_frame (mp3parse, buf);
+
+  /* store some frame info for later processing */
+  mp3parse->last_crc = crc;
+  mp3parse->last_mode = mode;
+
 cleanup:
   gst_buffer_unmap (buf, &map);
-  return res;
+
+  if (res && bpf <= map.size) {
+    return gst_base_parse_finish_frame (parse, frame, bpf);
+  }
+
+  return GST_FLOW_OK;
 }
 
 static void
@@ -977,94 +1033,6 @@ cleanup:
   gst_buffer_unmap (buf, &map);
 }
 
-static GstFlowReturn
-gst_mpeg_audio_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame)
-{
-  GstMpegAudioParse *mp3parse = GST_MPEG_AUDIO_PARSE (parse);
-  GstBuffer *buf = frame->buffer;
-  GstMapInfo map;
-  guint bitrate, layer, rate, channels, version, mode, crc;
-
-  gst_buffer_map (buf, &map, GST_MAP_READ);
-  if (G_UNLIKELY (map.size < 4))
-    goto short_buffer;
-
-  if (!mp3_type_frame_length_from_header (mp3parse,
-          GST_READ_UINT32_BE (map.data),
-          &version, &layer, &channels, &bitrate, &rate, &mode, &crc))
-    goto broken_header;
-
-  if (G_UNLIKELY (channels != mp3parse->channels || rate != mp3parse->rate ||
-          layer != mp3parse->layer || version != mp3parse->version)) {
-    GstCaps *caps = gst_caps_new_simple ("audio/mpeg",
-        "mpegversion", G_TYPE_INT, 1,
-        "mpegaudioversion", G_TYPE_INT, version,
-        "layer", G_TYPE_INT, layer,
-        "rate", G_TYPE_INT, rate,
-        "channels", G_TYPE_INT, channels, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
-    gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
-    gst_caps_unref (caps);
-
-    mp3parse->rate = rate;
-    mp3parse->channels = channels;
-    mp3parse->layer = layer;
-    mp3parse->version = version;
-
-    /* see http://www.codeproject.com/audio/MPEGAudioInfo.asp */
-    if (mp3parse->layer == 1)
-      mp3parse->spf = 384;
-    else if (mp3parse->layer == 2)
-      mp3parse->spf = 1152;
-    else if (mp3parse->version == 1) {
-      mp3parse->spf = 1152;
-    } else {
-      /* MPEG-2 or "2.5" */
-      mp3parse->spf = 576;
-    }
-
-    /* lead_in:
-     * We start pushing 9 frames earlier (29 frames for MPEG2) than
-     * segment start to be able to decode the first frame we want.
-     * 9 (29) frames are the theoretical maximum of frames that contain
-     * data for the current frame (bit reservoir).
-     *
-     * lead_out:
-     * Some mp3 streams have an offset in the timestamps, for which we have to
-     * push the frame *after* the end position in order for the decoder to be
-     * able to decode everything up until the segment.stop position. */
-    gst_base_parse_set_frame_rate (parse, mp3parse->rate, mp3parse->spf,
-        (version == 1) ? 10 : 30, 2);
-  }
-
-  mp3parse->hdr_bitrate = bitrate;
-
-  /* For first frame; check for seek tables and output a codec tag */
-  gst_mpeg_audio_parse_handle_first_frame (mp3parse, buf);
-
-  /* store some frame info for later processing */
-  mp3parse->last_crc = crc;
-  mp3parse->last_mode = mode;
-
-  gst_buffer_unmap (buf, &map);
-  return GST_FLOW_OK;
-
-/* ERRORS */
-broken_header:
-  {
-    /* this really shouldn't ever happen */
-    gst_buffer_unmap (buf, &map);
-    GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), (NULL));
-    return GST_FLOW_ERROR;
-  }
-
-short_buffer:
-  {
-    gst_buffer_unmap (buf, &map);
-    return GST_FLOW_ERROR;
-  }
-}
-
 static gboolean
 gst_mpeg_audio_parse_time_to_bytepos (GstMpegAudioParse * mp3parse,
     GstClockTime ts, gint64 * bytepos)