From 593ddf4bb9dc3c4d97bdde8d087db42147511274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 3 Mar 2012 16:56:13 +0000 Subject: [PATCH 1/6] configure: get rid of non-pkg-config ways to check for opencore-amr --- configure.ac | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index e5be3ed613..3c2e341b91 100644 --- a/configure.ac +++ b/configure.ac @@ -250,12 +250,11 @@ AG_GST_CHECK_FEATURE(A52DEC, [a52dec], a52dec, [ dnl *** amr-nb *** translit(dnm, m, l) AM_CONDITIONAL(USE_AMRNB, true) AG_GST_CHECK_FEATURE(AMRNB, [amrnb library], amrnb, [ - PKG_CHECK_MODULES(AMRNB, opencore-amrnb, HAVE_AMRNB="yes", - [ AG_GST_CHECK_LIBHEADER(AMRNB, opencore-amrnb, - Decoder_Interface_init, $LIBM, - opencore-amrnb/interf_dec.h, - AMRNB_LIBS="-lopencore-amrnb") - ]) + PKG_CHECK_MODULES(AMRNB, opencore-amrnb, [ + HAVE_AMRNB="yes" + ], [ + HAVE_AMRNB="no" + ]) AC_SUBST(AMRNB_CFLAGS) AC_SUBST(AMRNB_LIBS) ]) @@ -263,12 +262,11 @@ AG_GST_CHECK_FEATURE(AMRNB, [amrnb library], amrnb, [ dnl *** amr-wb dec *** translit(dnm, m, l) AM_CONDITIONAL(USE_AMRWB, true) AG_GST_CHECK_FEATURE(AMRWB, [amrwb library], amrwbdec, [ - PKG_CHECK_MODULES(AMRWB, opencore-amrwb, HAVE_AMRWB="yes", - [ AG_GST_CHECK_LIBHEADER(AMRWB, opencore-amrwb, - D_IF_decode, , - opencore-amrwb/dec_if.h, - AMRWB_LIBS="-lopencore-amrwb") - ]) + PKG_CHECK_MODULES(AMRWB, opencore-amrwb, [ + HAVE_AMRWB="yes" + ], [ + HAVE_AMRWB="no" + ]) AC_SUBST(AMRWB_CFLAGS) AC_SUBST(AMRWB_LIBS) ]) From 425e6e395f6bcaff77d0393126e1253066ddcd8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 3 Mar 2012 17:17:31 +0000 Subject: [PATCH 2/6] amrnb, amrwbdec: fix build with opencore-amr >= 0.1.3 In previous versions, the opencore-amr include sub-directory would be specified in the include path in the CFLAGS, but this is no longer the case in newer versions, so we need to add those to our include directives. Based on patch by: Christian Morales Vega https://bugzilla.gnome.org/show_bug.cgi?id=671123 --- configure.ac | 6 ++++++ ext/amrnb/amrnbdec.h | 5 +++++ ext/amrnb/amrnbenc.h | 7 ++++++- ext/amrwbdec/amrwbdec.h | 6 ++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3c2e341b91..18f2904e6f 100644 --- a/configure.ac +++ b/configure.ac @@ -251,6 +251,9 @@ dnl *** amr-nb *** translit(dnm, m, l) AM_CONDITIONAL(USE_AMRNB, true) AG_GST_CHECK_FEATURE(AMRNB, [amrnb library], amrnb, [ PKG_CHECK_MODULES(AMRNB, opencore-amrnb, [ + if $PKG_CONFIG --atleast-version=0.1.3 opencore-amrnb; then + AC_DEFINE(HAVE_OPENCORE_AMRNB_0_1_3_OR_LATER, 1, [Defined for newer opencore-amrnb]) + fi HAVE_AMRNB="yes" ], [ HAVE_AMRNB="no" @@ -263,6 +266,9 @@ dnl *** amr-wb dec *** translit(dnm, m, l) AM_CONDITIONAL(USE_AMRWB, true) AG_GST_CHECK_FEATURE(AMRWB, [amrwb library], amrwbdec, [ PKG_CHECK_MODULES(AMRWB, opencore-amrwb, [ + if $PKG_CONFIG --atleast-version=0.1.3 opencore-amrwb; then + AC_DEFINE(HAVE_OPENCORE_AMRWB_0_1_3_OR_LATER, 1, [Defined for newer opencore-amrwb]) + fi HAVE_AMRWB="yes" ], [ HAVE_AMRWB="no" diff --git a/ext/amrnb/amrnbdec.h b/ext/amrnb/amrnbdec.h index 1e818395b9..5fe698290c 100644 --- a/ext/amrnb/amrnbdec.h +++ b/ext/amrnb/amrnbdec.h @@ -22,7 +22,12 @@ #include #include + +#ifdef HAVE_OPENCORE_AMRNB_0_1_3_OR_LATER +#include +#else #include +#endif G_BEGIN_DECLS diff --git a/ext/amrnb/amrnbenc.h b/ext/amrnb/amrnbenc.h index 7f673ac69a..48a8fe8c62 100644 --- a/ext/amrnb/amrnbenc.h +++ b/ext/amrnb/amrnbenc.h @@ -21,9 +21,14 @@ #define __GST_AMRNBENC_H__ #include -#include #include +#ifdef HAVE_OPENCORE_AMRNB_0_1_3_OR_LATER +#include +#else +#include +#endif + G_BEGIN_DECLS #define GST_TYPE_AMRNBENC \ diff --git a/ext/amrwbdec/amrwbdec.h b/ext/amrwbdec/amrwbdec.h index c3528fca00..6b82ae9920 100644 --- a/ext/amrwbdec/amrwbdec.h +++ b/ext/amrwbdec/amrwbdec.h @@ -22,8 +22,14 @@ #include #include + +#ifdef HAVE_OPENCORE_AMRWB_0_1_3_OR_LATER +#include +#include +#else #include #include +#endif G_BEGIN_DECLS From 4a4d652dd47c1d9082a042cd7de7603ac8bf17a5 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 14 Jan 2011 18:50:41 +0100 Subject: [PATCH 3/6] mpeg2dec: Copy planes in one go when possible --- ext/mpeg2dec/gstmpeg2dec.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ext/mpeg2dec/gstmpeg2dec.c b/ext/mpeg2dec/gstmpeg2dec.c index 51c47e66d6..5c3d2a0e9b 100644 --- a/ext/mpeg2dec/gstmpeg2dec.c +++ b/ext/mpeg2dec/gstmpeg2dec.c @@ -357,10 +357,20 @@ gst_mpeg2dec_crop_buffer (GstMpeg2dec * dec, GstBuffer ** buf) gst_video_format_get_component_height (dec->format, c, dec->height); c_width = gst_video_format_get_component_width (dec->format, c, dec->width); - for (line = 0; line < c_height; line++) { - memcpy (dest, src, c_width); - dest += stride_out; - src += stride_in; + GST_DEBUG ("stride_in:%d _out:%d c_width:%d c_height:%d", + stride_in, stride_out, c_width, c_height); + + if (stride_in == stride_out && stride_in == c_width) { + /* FAST PATH */ + memcpy (dest, src, c_height * stride_out); + dest += stride_out * c_height; + src += stride_out * c_height; + } else { + for (line = 0; line < c_height; line++) { + memcpy (dest, src, c_width); + dest += stride_out; + src += stride_in; + } } } From 6e9a53422338d97093843d93464b579970ba3204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 6 Mar 2012 14:28:15 +0100 Subject: [PATCH 4/6] dvdreadsrc: Use variable type with correct signedness --- ext/dvdread/dvdreadsrc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/dvdread/dvdreadsrc.c b/ext/dvdread/dvdreadsrc.c index 9877f07247..d0ebcaf491 100644 --- a/ext/dvdread/dvdreadsrc.c +++ b/ext/dvdread/dvdreadsrc.c @@ -536,7 +536,7 @@ gst_dvd_read_src_goto_title (GstDvdReadSrc * src, gint title, gint angle) sid = i; if (pgc0 != NULL) { - if (v->display_aspect_ratio == 0) /* 4:3 */ + if (v->display_aspect_ratio == 0) /* 4:3 */ sid = (pgc0->subp_control[i] >> 24) & 0x1f; else if (v->display_aspect_ratio == 3) /* 16:9 */ sid = (pgc0->subp_control[i] >> 8) & 0x1f; @@ -1073,7 +1073,7 @@ gst_dvd_read_src_get_size (GstDvdReadSrc * src, gint64 * size) gboolean ret = FALSE; if (src->dvd_title) { - gsize blocks; + gssize blocks; blocks = DVDFileSize (src->dvd_title); if (blocks >= 0) { From 110a993cc9f893c456e6823ffa3511af0b0e1434 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 6 Mar 2012 16:08:23 +0100 Subject: [PATCH 5/6] a52dec: use base class tag handling helper ... so as to ensure these to be handled and sent at proper time. --- ext/a52dec/gsta52dec.c | 30 +++--------------------------- ext/a52dec/gsta52dec.h | 2 -- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/ext/a52dec/gsta52dec.c b/ext/a52dec/gsta52dec.c index 3ada93f188..aeab8a1da1 100644 --- a/ext/a52dec/gsta52dec.c +++ b/ext/a52dec/gsta52dec.c @@ -96,8 +96,6 @@ static gboolean gst_a52dec_parse (GstAudioDecoder * dec, GstAdapter * adapter, gint * offset, gint * length); static GstFlowReturn gst_a52dec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer); -static GstFlowReturn gst_a52dec_pre_push (GstAudioDecoder * bdec, - GstBuffer ** buffer); static GstFlowReturn gst_a52dec_chain (GstPad * pad, GstBuffer * buffer); @@ -163,7 +161,6 @@ gst_a52dec_class_init (GstA52DecClass * klass) gstbase_class->set_format = GST_DEBUG_FUNCPTR (gst_a52dec_set_format); gstbase_class->parse = GST_DEBUG_FUNCPTR (gst_a52dec_parse); gstbase_class->handle_frame = GST_DEBUG_FUNCPTR (gst_a52dec_handle_frame); - gstbase_class->pre_push = GST_DEBUG_FUNCPTR (gst_a52dec_pre_push); /** * GstA52Dec::drc @@ -282,10 +279,6 @@ gst_a52dec_stop (GstAudioDecoder * dec) a52_free (a52dec->state); a52dec->state = NULL; } - if (a52dec->pending_tags) { - gst_tag_list_free (a52dec->pending_tags); - a52dec->pending_tags = NULL; - } return TRUE; } @@ -463,26 +456,9 @@ gst_a52dec_update_streaminfo (GstA52Dec * a52dec) gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE, (guint) a52dec->bit_rate, NULL); - if (a52dec->pending_tags) { - gst_tag_list_free (a52dec->pending_tags); - a52dec->pending_tags = NULL; - } - - a52dec->pending_tags = taglist; -} - -static GstFlowReturn -gst_a52dec_pre_push (GstAudioDecoder * bdec, GstBuffer ** buffer) -{ - GstA52Dec *a52dec = GST_A52DEC (bdec); - - if (G_UNLIKELY (a52dec->pending_tags)) { - gst_element_found_tags_for_pad (GST_ELEMENT (a52dec), - GST_AUDIO_DECODER_SRC_PAD (a52dec), a52dec->pending_tags); - a52dec->pending_tags = NULL; - } - - return GST_FLOW_OK; + gst_audio_decoder_merge_tags (GST_AUDIO_DECODER (a52dec), taglist, + GST_TAG_MERGE_REPLACE); + gst_tag_list_free (taglist); } static GstFlowReturn diff --git a/ext/a52dec/gsta52dec.h b/ext/a52dec/gsta52dec.h index 44fab5d2c6..0c1dc5f5dc 100644 --- a/ext/a52dec/gsta52dec.h +++ b/ext/a52dec/gsta52dec.h @@ -62,8 +62,6 @@ struct _GstA52Dec { gboolean dynamic_range_compression; sample_t *samples; a52_state_t *state; - - GstTagList *pending_tags; }; struct _GstA52DecClass { From 6d44ed77a4779e991084caccec51926986427e0d Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 13 Mar 2012 18:27:51 +0100 Subject: [PATCH 6/6] mad: simplify parsing code Also fixes #671455 (expected at least). --- ext/mad/gstmad.c | 205 ++++++++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 117 deletions(-) diff --git a/ext/mad/gstmad.c b/ext/mad/gstmad.c index a24c89ddd0..1c063a712f 100644 --- a/ext/mad/gstmad.c +++ b/ext/mad/gstmad.c @@ -278,9 +278,9 @@ gst_mad_parse (GstAudioDecoder * dec, GstAdapter * adapter, { GstMad *mad; GstFlowReturn ret = GST_FLOW_UNEXPECTED; - gint av, size, offset, prev_offset, consumed = 0; + gint av, size, offset; const guint8 *data; - gboolean eos; + gboolean eos, sync; GstBuffer *guard = NULL; mad = GST_MAD (dec); @@ -288,7 +288,9 @@ gst_mad_parse (GstAudioDecoder * dec, GstAdapter * adapter, av = gst_adapter_available (adapter); data = gst_adapter_peek (adapter, av); - gst_audio_decoder_get_parse_state (dec, NULL, &eos); + gst_audio_decoder_get_parse_state (dec, &sync, &eos); + GST_LOG_OBJECT (mad, "parse state sync %d, eos %d", sync, eos); + if (eos) { /* This is one streaming hack right there. * mad will not decode the last frame if it is not followed by @@ -312,130 +314,99 @@ gst_mad_parse (GstAudioDecoder * dec, GstAdapter * adapter, * if a frame is found (and also decoded), subsequent handle_frame * only needs to synthesize it */ - prev_offset = -1; offset = 0; - while (offset < av) { - size = MIN (MAD_BUFFER_MDLEN * 3, av - offset); + size = 0; - /* check for mad asking too much */ - if (offset == prev_offset) { - if (G_UNLIKELY (offset + size < av)) { - /* mad should not do this, so really fatal */ - GST_ELEMENT_ERROR (mad, STREAM, DECODE, (NULL), - ("mad claims to need more data than %u bytes", size)); - ret = GST_FLOW_ERROR; - goto exit; - } else { +resume: + if (G_UNLIKELY (offset + MAD_BUFFER_GUARD > av)) + goto exit; + + GST_LOG_OBJECT (mad, "setup mad stream at offset %d (of av %d)", offset, av); + mad_stream_buffer (&mad->stream, data + offset, av - offset); + /* convey sync idea to mad */ + mad->stream.sync = sync; + /* if we get back here, lost sync anyway */ + sync = FALSE; + + while (TRUE) { + GST_LOG_OBJECT (mad, "decoding the header now"); + if (mad_header_decode (&mad->frame.header, &mad->stream) == -1) { + /* HACK it seems mad reports wrong error when it is trying to determine + * free bitrate and scanning for next header */ + if (mad->stream.error == MAD_ERROR_LOSTSYNC) { + const guint8 *ptr = mad->stream.this_frame; + guint32 header; + + if (ptr >= data && ptr < data + av) { + header = GST_READ_UINT32_BE (ptr); + /* looks like possible freeform header with not much data */ + if (((header & 0xFFE00000) == 0xFFE00000) && + (((header >> 12) & 0xF) == 0x0) && (av < 4096)) { + GST_DEBUG_OBJECT (mad, "overriding freeform LOST_SYNC to BUFLEN"); + mad->stream.error = MAD_ERROR_BUFLEN; + } + } + } + if (mad->stream.error == MAD_ERROR_BUFLEN) { + GST_LOG_OBJECT (mad, "not enough data, getting more"); + offset = mad->stream.next_frame - data; break; - } - } - - /* only feed that much to mad at a time */ - mad_stream_buffer (&mad->stream, data + offset, size); - prev_offset = offset; - - while (offset - prev_offset < size) { - consumed = 0; - - GST_LOG_OBJECT (mad, "decoding the header now"); - if (mad_header_decode (&mad->frame.header, &mad->stream) == -1) { - /* HACK it seems mad reports wrong error when it is trying to determine - * free bitrate and scanning for next header */ - if (mad->stream.error == MAD_ERROR_LOSTSYNC) { - const guint8 *ptr = mad->stream.this_frame; - guint32 header; - - if (ptr >= data && ptr < data + av) { - header = GST_READ_UINT32_BE (ptr); - /* looks like possible freeform header with not much data */ - if (((header & 0xFFE00000) == 0xFFE00000) && - (((header >> 12) & 0xF) == 0x0) && (av < 4096)) { - GST_DEBUG_OBJECT (mad, "overriding freeform LOST_SYNC to BUFLEN"); - mad->stream.error = MAD_ERROR_BUFLEN; - } - } - } - if (mad->stream.error == MAD_ERROR_BUFLEN) { - GST_LOG_OBJECT (mad, - "not enough data in tempbuffer (%d), breaking to get more", size); - break; - } else { - GST_WARNING_OBJECT (mad, "mad_header_decode had an error: %s", - mad_stream_errorstr (&mad->stream)); - } - } - - GST_LOG_OBJECT (mad, "parsing and decoding one frame now"); - if (mad_frame_decode (&mad->frame, &mad->stream) == -1) { - GST_LOG_OBJECT (mad, "got error %d", mad->stream.error); - - /* not enough data, need to wait for next buffer? */ - if (mad->stream.error == MAD_ERROR_BUFLEN) { - if (mad->stream.next_frame == data) { - GST_LOG_OBJECT (mad, - "not enough data in tempbuffer (%d), breaking to get more", - size); - break; - } else { - GST_LOG_OBJECT (mad, "sync error, flushing unneeded data"); - goto flush; - } - } else if (mad->stream.error == MAD_ERROR_BADDATAPTR) { - /* Flush data */ - goto flush; - } else { - GST_WARNING_OBJECT (mad, "mad_frame_decode had an error: %s", - mad_stream_errorstr (&mad->stream)); - if (!MAD_RECOVERABLE (mad->stream.error)) { - /* well, all may be well enough bytes later on ... */ - GST_AUDIO_DECODER_ERROR (mad, 1, STREAM, DECODE, (NULL), - ("mad error: %s", mad_stream_errorstr (&mad->stream)), ret); - /* so make sure we really move along ... */ - if (!offset) - offset++; - goto exit; - } else { - const guint8 *before_sync, *after_sync; - - mad_frame_mute (&mad->frame); - mad_synth_mute (&mad->synth); - before_sync = mad->stream.ptr.byte; - if (mad_stream_sync (&mad->stream) != 0) - GST_WARNING_OBJECT (mad, "mad_stream_sync failed"); - after_sync = mad->stream.ptr.byte; - /* a succesful resync should make us drop bytes as consumed, so - * calculate from the byte pointers before and after resync */ - consumed = after_sync - before_sync; - GST_DEBUG_OBJECT (mad, "resynchronization consumes %d bytes", - consumed); - GST_DEBUG_OBJECT (mad, "synced to data: 0x%0x 0x%0x", - *mad->stream.ptr.byte, *(mad->stream.ptr.byte + 1)); - - mad_stream_sync (&mad->stream); - /* recoverable errors pass */ - goto flush; - } - } + } else if (mad->stream.error == MAD_ERROR_LOSTSYNC) { + GST_LOG_OBJECT (mad, "lost sync"); + continue; } else { - /* decoding ok; found frame */ - ret = GST_FLOW_OK; + /* probably some bogus header, basically also lost sync */ + GST_DEBUG_OBJECT (mad, "mad_header_decode had an error: %s", + mad_stream_errorstr (&mad->stream)); + continue; } - flush: - if (consumed == 0) { - consumed = mad->stream.next_frame - (data + offset); - g_assert (consumed >= 0); - } - - if (ret == GST_FLOW_OK) - goto exit; - - offset += consumed; } + + /* could have a frame now, subsequent will confirm */ + offset = mad->stream.this_frame - data; + size = mad->stream.next_frame - mad->stream.this_frame; + g_assert (size); + + GST_LOG_OBJECT (mad, "parsing and decoding one frame now " + "(offset %d, size %d)", offset, size); + if (mad_frame_decode (&mad->frame, &mad->stream) == -1) { + GST_LOG_OBJECT (mad, "got error %d", mad->stream.error); + + /* not enough data, need to wait for next buffer? */ + if (mad->stream.error == MAD_ERROR_BUFLEN) { + /* not really expect this error at this stage anymore + * assume bogus frame and bad sync and move along a bit */ + GST_WARNING_OBJECT (mad, "not enough data (unexpected), moving along"); + offset++; + goto resume; + } else if (mad->stream.error == MAD_ERROR_BADDATAPTR) { + GST_DEBUG_OBJECT (mad, "bad data ptr, skipping presumed frame"); + /* flush past presumed frame */ + offset += size; + goto resume; + } else { + GST_WARNING_OBJECT (mad, "mad_frame_decode had an error: %s", + mad_stream_errorstr (&mad->stream)); + if (!MAD_RECOVERABLE (mad->stream.error)) { + /* well, all may be well enough bytes later on ... */ + GST_AUDIO_DECODER_ERROR (mad, 1, STREAM, DECODE, (NULL), + ("mad error: %s", mad_stream_errorstr (&mad->stream)), ret); + } + /* move along and try again */ + offset++; + goto resume; + } + g_assert_not_reached (); + } + + /* so decoded ok, got a frame now */ + ret = GST_FLOW_OK; + break; } exit: *_offset = offset; - *len = consumed; + *len = size; /* 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. */