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