gst-plugins-ugly: mad: unhack last frame coaxing

Mark Nauwelaerts mnauw at kemper.freedesktop.org
Thu Feb 16 05:58:03 PST 2012


Module: gst-plugins-ugly
Branch: master
Commit: 2e35999f68c530f3c1076ba6d4753c13bc72fff4
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-ugly/commit/?id=2e35999f68c530f3c1076ba6d4753c13bc72fff4

Author: Mark Nauwelaerts <mark.nauwelaerts at collabora.co.uk>
Date:   Thu Feb 16 14:29:47 2012 +0100

mad: unhack last frame coaxing

... so as to maximally use available base class API and interfere least
as possible with its internal state.

---

 ext/mad/gstmad.c |   44 ++++++++++++++++++--------------------------
 1 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/ext/mad/gstmad.c b/ext/mad/gstmad.c
index 8336638..9b5f597 100644
--- a/ext/mad/gstmad.c
+++ b/ext/mad/gstmad.c
@@ -82,7 +82,6 @@ static gboolean gst_mad_parse (GstAudioDecoder * dec, GstAdapter * adapter,
     gint * offset, gint * length);
 static GstFlowReturn gst_mad_handle_frame (GstAudioDecoder * dec,
     GstBuffer * buffer);
-static gboolean gst_mad_event (GstAudioDecoder * dec, GstEvent * event);
 static void gst_mad_flush (GstAudioDecoder * dec, gboolean hard);
 
 static void gst_mad_set_property (GObject * object, guint prop_id,
@@ -120,7 +119,6 @@ gst_mad_class_init (GstMadClass * klass)
   base_class->parse = GST_DEBUG_FUNCPTR (gst_mad_parse);
   base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mad_handle_frame);
   base_class->flush = GST_DEBUG_FUNCPTR (gst_mad_flush);
-  base_class->event = GST_DEBUG_FUNCPTR (gst_mad_event);
 
   gobject_class->set_property = gst_mad_set_property;
   gobject_class->get_property = gst_mad_get_property;
@@ -282,21 +280,30 @@ gst_mad_parse (GstAudioDecoder * dec, GstAdapter * adapter,
   GstFlowReturn ret = GST_FLOW_UNEXPECTED;
   gint av, size, offset, prev_offset, consumed = 0;
   const guint8 *data;
+  gboolean eos;
+  GstBuffer *guard = NULL;
 
   mad = GST_MAD (dec);
 
-  if (mad->eos) {
-    /* This is one steaming hack right there.
+  av = gst_adapter_available (adapter);
+  data = gst_adapter_peek (adapter, av);
+
+  gst_audio_decoder_get_parse_state (dec, NULL, &eos);
+  if (eos) {
+    /* This is one streaming hack right there.
      * mad will not decode the last frame if it is not followed by
      * a number of 0 bytes, due to some buffer overflow, which can
      * not be fixed for reasons I did not inquire into, see
      * http://www.mars.org/mailman/public/mad-dev/2001-May/000262.html
      */
-    GstBuffer *guard = gst_buffer_new_and_alloc (MAD_BUFFER_GUARD);
+    guard = gst_buffer_new_and_alloc (av + MAD_BUFFER_GUARD);
+    /* let's be nice and not mess with baseclass state and keep hacks local */
     memset (GST_BUFFER_DATA (guard), 0, GST_BUFFER_SIZE (guard));
-    GST_DEBUG_OBJECT (mad, "Discreetly stuffing %u zero bytes in the adapter",
-        GST_BUFFER_SIZE (guard));
-    gst_adapter_push (adapter, guard);
+    memcpy (GST_BUFFER_DATA (guard), data, av);
+    GST_DEBUG_OBJECT (mad, "Added %u zero guard bytes in the adapter; "
+        "using fallback buffer of size %u",
+        GST_BUFFER_SIZE (guard) - av, GST_BUFFER_SIZE (guard));
+    data = GST_BUFFER_DATA (guard);
   }
 
   /* we basically let mad library do parsing,
@@ -306,10 +313,8 @@ gst_mad_parse (GstAudioDecoder * dec, GstAdapter * adapter,
 
   prev_offset = -1;
   offset = 0;
-  av = gst_adapter_available (adapter);
   while (offset < av) {
     size = MIN (MAD_BUFFER_MDLEN * 3, av - offset);
-    data = gst_adapter_peek (adapter, av);
 
     /* check for mad asking too much */
     if (offset == prev_offset) {
@@ -417,13 +422,15 @@ exit:
 
   /* ensure that if we added some dummy guard bytes above, we don't claim
      to have used them as they're unknown to the caller. */
-  if (mad->eos) {
+  if (eos) {
     g_assert (av >= MAD_BUFFER_GUARD);
     av -= MAD_BUFFER_GUARD;
     if (*_offset > av)
       *_offset = av;
     if (*len > av)
       *len = av;
+    g_assert (guard);
+    gst_buffer_unref (guard);
   }
 
   return ret;
@@ -510,21 +517,6 @@ gst_mad_flush (GstAudioDecoder * dec, gboolean hard)
   }
 }
 
-static gboolean
-gst_mad_event (GstAudioDecoder * dec, GstEvent * event)
-{
-  GstMad *mad;
-
-  mad = GST_MAD (dec);
-  if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
-    GST_DEBUG_OBJECT (mad, "We got EOS, will pad next time");
-    mad->eos = TRUE;
-  }
-
-  /* Let the base class do its usual thing */
-  return FALSE;
-}
-
 static void
 gst_mad_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)



More information about the gstreamer-commits mailing list