From e67aa28de9df1deae94697dcc32ef8c3e7c35fa4 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 30 Sep 2011 20:00:50 +0100 Subject: [PATCH 1/7] typefind: typefind UTF-16 and UTF-32 This avoids the MP3 typefinder from getting the highest score every time it thinks there's something it might possibly be able to parse. https://bugzilla.gnome.org/show_bug.cgi?id=607619 --- gst/typefind/Makefile.am | 2 +- gst/typefind/gsttypefindfunctions.c | 157 ++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/gst/typefind/Makefile.am b/gst/typefind/Makefile.am index 3258b15a85..f64cdc369a 100644 --- a/gst/typefind/Makefile.am +++ b/gst/typefind/Makefile.am @@ -7,7 +7,7 @@ libgsttypefindfunctions_la_CFLAGS = \ libgsttypefindfunctions_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgsttypefindfunctions_la_LIBADD = \ $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \ - $(GST_LIBS) $(GIO_LIBS) + $(GST_BASE_LIBS) $(GST_LIBS) $(GIO_LIBS) libgsttypefindfunctions_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 1675addd0c..22ad2fb40c 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -41,6 +41,7 @@ #include #include +#include GST_DEBUG_CATEGORY_STATIC (type_find_debug); #define GST_CAT_DEFAULT type_find_debug @@ -206,6 +207,157 @@ utf8_type_find (GstTypeFind * tf, gpointer unused) gst_type_find_suggest (tf, (start_prob + mid_prob) / 2, UTF8_CAPS); } +/*** text/utf-16 and text/utf-32} ***/ +/* While UTF-8 is unicode too, using text/plain for UTF-16 and UTF-32 + is going to break stuff. */ + +typedef struct +{ + size_t bomlen; + const char *const bom; + gboolean (*checker) (const guint8 *, gint, gint); + int boost; + int endianness; +} GstUnicodeTester; + +static gboolean +check_utf16 (const guint8 * data, gint len, gint endianness) +{ + GstByteReader br; + guint16 high, low; + + if (len & 1) + return FALSE; + + gst_byte_reader_init (&br, data, len); + while (len >= 2) { + /* test first for a single 16 bit value in the BMP */ + if (endianness == G_BIG_ENDIAN) + gst_byte_reader_get_uint16_be (&br, &high); + else + gst_byte_reader_get_uint16_le (&br, &high); + if (high >= 0xD800 && high <= 0xDBFF) { + /* start of a surrogate pair */ + if (len < 4) + return FALSE; + len -= 2; + if (endianness == G_BIG_ENDIAN) + gst_byte_reader_get_uint16_be (&br, &low); + else + gst_byte_reader_get_uint16_le (&br, &low); + if (low >= 0xDC00 && low <= 0xDFFF) { + /* second half of the surrogate pair */ + } else + return FALSE; + } else { + if (high >= 0xDC00 && high <= 0xDFFF) + return FALSE; + } + len -= 2; + } + return TRUE; +} + +static gboolean +check_utf32 (const guint8 * data, gint len, gint endianness) +{ + if (len & 3) + return FALSE; + while (len > 3) { + guint32 v; + if (endianness == G_BIG_ENDIAN) + v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + else + v = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]; + if (v >= 0x10FFFF) + return FALSE; + data += 4; + len -= 4; + } + return TRUE; +} + +static void +unicode_type_find (GstTypeFind * tf, const GstUnicodeTester * tester, + guint n_tester, const char *media_type) +{ + size_t n; + gint len = 4; + const guint8 *data = gst_type_find_peek (tf, 0, len); + int prob = -1; + const gint max_scan_size = 256 * 1024; + int endianness; + + if (!data) { + len = 2; + data = gst_type_find_peek (tf, 0, len); + if (!data) + return; + } + + /* find a large enough size that works */ + while (len < max_scan_size) { + size_t newlen = len << 1; + const guint8 *newdata = gst_type_find_peek (tf, 0, newlen); + if (!newdata) + break; + len = newlen; + data = newdata; + } + + for (n = 0; n < n_tester; ++n) { + int bom_boost = 0, tmpprob; + if (len >= tester[n].bomlen) { + if (!memcmp (data, tester[n].bom, tester[n].bomlen)) + bom_boost = tester[n].boost; + } + if (!(*tester[n].checker) (data, len, tester[n].endianness)) + continue; + tmpprob = GST_TYPE_FIND_POSSIBLE - 20 + bom_boost; + if (tmpprob > prob) { + prob = tmpprob; + endianness = tester[n].endianness; + } + } + + if (prob > 0) { + GST_DEBUG ("This is valid %s %s", media_type, + endianness == G_BIG_ENDIAN ? "be" : "le"); + gst_type_find_suggest_simple (tf, prob, media_type, + "endianness", G_TYPE_INT, endianness, NULL); + } +} + +static GstStaticCaps utf16_caps = GST_STATIC_CAPS ("text/utf-16"); + +#define UTF16_CAPS gst_static_caps_get(&utf16_caps) + +static void +utf16_type_find (GstTypeFind * tf, gpointer unused) +{ + static const GstUnicodeTester utf16tester[2] = { + {2, "\xff\xfe", check_utf16, 10, G_LITTLE_ENDIAN}, + {2, "\xfe\xff", check_utf16, 20, G_BIG_ENDIAN}, + }; + unicode_type_find (tf, utf16tester, G_N_ELEMENTS (utf16tester), + "text/utf-16"); +} + +static GstStaticCaps utf32_caps = GST_STATIC_CAPS ("text/utf-32"); + +#define UTF32_CAPS gst_static_caps_get(&utf32_caps) + +static void +utf32_type_find (GstTypeFind * tf, gpointer unused) +{ + static const GstUnicodeTester utf32tester[2] = { + {4, "\xff\xfe\x00\x00", check_utf32, 10, G_LITTLE_ENDIAN}, + {4, "\x00\x00\xfe\xff", check_utf32, 20, G_BIG_ENDIAN} + }; + unicode_type_find (tf, utf32tester, G_N_ELEMENTS (utf32tester), + "text/utf-32"); +} + /*** text/uri-list ***/ static GstStaticCaps uri_caps = GST_STATIC_CAPS ("text/uri-list"); @@ -4262,6 +4414,7 @@ plugin_init (GstPlugin * plugin) static const gchar *rm_exts[] = { "ra", "ram", "rm", "rmvb", NULL }; static const gchar *swf_exts[] = { "swf", "swfl", NULL }; static const gchar *utf8_exts[] = { "txt", NULL }; + static const gchar *unicode_exts[] = { "txt", NULL }; static const gchar *wav_exts[] = { "wav", NULL }; static const gchar *aiff_exts[] = { "aiff", "aif", "aifc", NULL }; static const gchar *svx_exts[] = { "iff", "svx", NULL }; @@ -4436,6 +4589,10 @@ plugin_init (GstPlugin * plugin) flv_exts, "FLV", 3, GST_TYPE_FIND_MAXIMUM); TYPE_FIND_REGISTER (plugin, "text/plain", GST_RANK_MARGINAL, utf8_type_find, utf8_exts, UTF8_CAPS, NULL, NULL); + TYPE_FIND_REGISTER (plugin, "text/utf-16", GST_RANK_MARGINAL, utf16_type_find, + unicode_exts, UTF16_CAPS, NULL, NULL); + TYPE_FIND_REGISTER (plugin, "text/utf-32", GST_RANK_MARGINAL, utf32_type_find, + unicode_exts, UTF32_CAPS, NULL, NULL); TYPE_FIND_REGISTER (plugin, "text/uri-list", GST_RANK_MARGINAL, uri_type_find, uri_exts, URI_CAPS, NULL, NULL); TYPE_FIND_REGISTER (plugin, "application/x-hls", GST_RANK_MARGINAL, From 4c52f4e625f910d6fba34d49fe06cfd1220c9c93 Mon Sep 17 00:00:00 2001 From: Kipp Cannon Date: Mon, 28 Nov 2011 17:59:32 +0100 Subject: [PATCH 2/7] audioresample: Don't emit DISCONT buffers if no discontinuity happened audioresample is derived from GstBaseTransform, and one of GstBaseTransform's traits is that if the derived element does not produce an output buffer from some input buffer then the first output buffer after that gets flaged as a discontinuity, whether or not the buffer actually is discontinuous from the output buffer that preceded it. When downsampling, the audioresample element requires more than one input sample for each output sample, and if the ratio of input to output sample rates is high enough and the input buffers short enough it can come to pass that the resampler does not receive enough samples on its input to produce any output. Currently the resampler returns GST_BASE_TRANSFORM_FLOW_DROPPED from the transform() method in this case, causing the next buffer to be flagged as a discontinuity. If subsequent elements in the pipeline reset themselves on disconts, this can cause clicks and other undesireable behaviour. Fixes bug #665004. --- gst/audioresample/gstaudioresample.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 7c488829d3..80988cb7fc 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -1168,10 +1168,6 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf)); - if (out_processed == 0) { - GST_DEBUG_OBJECT (resample, "buffer dropped"); - return GST_BASE_TRANSFORM_FLOW_DROPPED; - } return GST_FLOW_OK; } From c1b1e2b44e59ba79100c70eeee964dde8b48750c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 28 Nov 2011 19:03:54 +0100 Subject: [PATCH 3/7] playsinkconvertbin: Only return the converter caps if we actually have raw caps Fixes bug #664818 (hopefully). --- gst/playback/gstplaysinkconvertbin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c index 361b5d20c1..4f707d7d1f 100644 --- a/gst/playback/gstplaysinkconvertbin.c +++ b/gst/playback/gstplaysinkconvertbin.c @@ -391,7 +391,7 @@ gst_play_sink_convert_bin_getcaps (GstPad * pad) if (peer) { GstCaps *peer_caps = gst_pad_get_caps_reffed (peer); gst_object_unref (peer); - if (self->converter_caps) { + if (self->converter_caps && is_raw_caps (peer_caps)) { peer_caps = gst_caps_make_writable (peer_caps); gst_caps_merge (peer_caps, gst_caps_ref (self->converter_caps)); ret = peer_caps; From f179213aa0ee36476bb6f6ffdc817ea21509cf4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 28 Nov 2011 19:06:57 +0100 Subject: [PATCH 4/7] playsinkconvertbin: Fix stupid mistake in last commit --- gst/playback/gstplaysinkconvertbin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c index 4f707d7d1f..b3655264f3 100644 --- a/gst/playback/gstplaysinkconvertbin.c +++ b/gst/playback/gstplaysinkconvertbin.c @@ -391,7 +391,7 @@ gst_play_sink_convert_bin_getcaps (GstPad * pad) if (peer) { GstCaps *peer_caps = gst_pad_get_caps_reffed (peer); gst_object_unref (peer); - if (self->converter_caps && is_raw_caps (peer_caps)) { + if (self->converter_caps && is_raw_caps (peer_caps, self->audio)) { peer_caps = gst_caps_make_writable (peer_caps); gst_caps_merge (peer_caps, gst_caps_ref (self->converter_caps)); ret = peer_caps; From 36434c20ebc7dbfd69e7a8514da67c4d277bb497 Mon Sep 17 00:00:00 2001 From: Alexey Fisher Date: Mon, 28 Nov 2011 19:03:50 +0100 Subject: [PATCH 5/7] typefind: fix build error fix build errors: gsttypefindfunctions.c:248:25: error: 'low' may be used uninitialized in this function [-Werror=uninitialized] gsttypefindfunctions.c:239:24: error: 'high' may be used uninitialized in this function [-Werror=uninitialized] Signed-off-by: Alexey Fisher --- gst/typefind/gsttypefindfunctions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 22ad2fb40c..55c21a9bf2 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -226,6 +226,8 @@ check_utf16 (const guint8 * data, gint len, gint endianness) GstByteReader br; guint16 high, low; + low = high = 0; + if (len & 1) return FALSE; From ed5279e3c57936864890e80eba58f8e7c4aa0298 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Mon, 28 Nov 2011 20:10:18 +0100 Subject: [PATCH 6/7] typefindfunctions: Fix compiler warning --- gst/typefind/gsttypefindfunctions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 55c21a9bf2..7784d2c87e 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -215,7 +215,7 @@ typedef struct { size_t bomlen; const char *const bom; - gboolean (*checker) (const guint8 *, gint, gint); + gboolean (*checker) (const guint8 *, gint, gint); int boost; int endianness; } GstUnicodeTester; @@ -288,7 +288,7 @@ unicode_type_find (GstTypeFind * tf, const GstUnicodeTester * tester, const guint8 *data = gst_type_find_peek (tf, 0, len); int prob = -1; const gint max_scan_size = 256 * 1024; - int endianness; + int endianness = 0; if (!data) { len = 2; From 0a841f67126c59b21212d5105346945d318fd2bc Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Mon, 28 Nov 2011 20:11:09 +0100 Subject: [PATCH 7/7] fft: Bracket public headers This is especially needed if the gstfftw library is used from C++ code. Fixes #665074 --- gst-libs/gst/fft/gstfft.h | 4 ++++ gst-libs/gst/fft/gstfftf32.h | 4 ++++ gst-libs/gst/fft/gstfftf64.h | 4 ++++ gst-libs/gst/fft/gstffts16.h | 5 +++++ gst-libs/gst/fft/gstffts32.h | 4 ++++ 5 files changed, 21 insertions(+) diff --git a/gst-libs/gst/fft/gstfft.h b/gst-libs/gst/fft/gstfft.h index fa5defe220..9071b1c8d2 100644 --- a/gst-libs/gst/fft/gstfft.h +++ b/gst-libs/gst/fft/gstfft.h @@ -23,6 +23,8 @@ #ifndef __GST_FFT_H__ #define __GST_FFT_H__ +G_BEGIN_DECLS + /** * GstFFTWindow: * @GST_FFT_WINDOW_RECTANGULAR: Rectangular window @@ -46,4 +48,6 @@ typedef enum gint gst_fft_next_fast_length (gint n) G_GNUC_CONST; +G_END_DECLS + #endif /* __GST_FFT_H__ */ diff --git a/gst-libs/gst/fft/gstfftf32.h b/gst-libs/gst/fft/gstfftf32.h index 3b56b48394..2d634f8180 100644 --- a/gst-libs/gst/fft/gstfftf32.h +++ b/gst-libs/gst/fft/gstfftf32.h @@ -25,6 +25,8 @@ #include "gstfft.h" +G_BEGIN_DECLS + typedef struct _GstFFTF32 GstFFTF32; typedef struct _GstFFTF32Complex GstFFTF32Complex; @@ -72,4 +74,6 @@ void gst_fft_f32_free (GstFFTF32 *self); void gst_fft_f32_window (GstFFTF32 *self, gfloat *timedata, GstFFTWindow window); +G_END_DECLS + #endif /* __GST_FFT_F32_H__ */ diff --git a/gst-libs/gst/fft/gstfftf64.h b/gst-libs/gst/fft/gstfftf64.h index 8ebbee49ab..66a830a119 100644 --- a/gst-libs/gst/fft/gstfftf64.h +++ b/gst-libs/gst/fft/gstfftf64.h @@ -25,6 +25,8 @@ #include "gstfft.h" +G_BEGIN_DECLS + typedef struct _GstFFTF64 GstFFTF64; typedef struct _GstFFTF64Complex GstFFTF64Complex; @@ -72,4 +74,6 @@ void gst_fft_f64_free (GstFFTF64 *self); void gst_fft_f64_window (GstFFTF64 *self, gdouble *timedata, GstFFTWindow window); +G_END_DECLS + #endif /* __GST_FFT_F64_H__ */ diff --git a/gst-libs/gst/fft/gstffts16.h b/gst-libs/gst/fft/gstffts16.h index 9a752f1ffd..cae969badc 100644 --- a/gst-libs/gst/fft/gstffts16.h +++ b/gst-libs/gst/fft/gstffts16.h @@ -25,6 +25,8 @@ #include "gstfft.h" +G_BEGIN_DECLS + typedef struct _GstFFTS16 GstFFTS16; typedef struct _GstFFTS16Complex GstFFTS16Complex; @@ -71,4 +73,7 @@ void gst_fft_s16_inverse_fft (GstFFTS16 *self, const GstFFTS16Complex *freqdata, void gst_fft_s16_free (GstFFTS16 *self); void gst_fft_s16_window (GstFFTS16 *self, gint16 *timedata, GstFFTWindow window); + +G_END_DECLS + #endif /* __GST_FFT_S16_H__ */ diff --git a/gst-libs/gst/fft/gstffts32.h b/gst-libs/gst/fft/gstffts32.h index fd3b2798e4..281434bc27 100644 --- a/gst-libs/gst/fft/gstffts32.h +++ b/gst-libs/gst/fft/gstffts32.h @@ -25,6 +25,8 @@ #include "gstfft.h" +G_BEGIN_DECLS + typedef struct _GstFFTS32 GstFFTS32; typedef struct _GstFFTS32Complex GstFFTS32Complex; @@ -72,4 +74,6 @@ void gst_fft_s32_free (GstFFTS32 *self); void gst_fft_s32_window (GstFFTS32 *self, gint32 *timedata, GstFFTWindow window); +G_END_DECLS + #endif /* __GST_FFT_S32_H__ */