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 fcd31748a7..60bf98c0e1 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; @@ -56,4 +58,6 @@ void gst_fft_f32_inverse_fft (GstFFTF32 *self, const GstFFTF32Complex 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 7bb42cae3b..782bd8b7fb 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; @@ -56,4 +58,6 @@ void gst_fft_f64_inverse_fft (GstFFTF64 *self, const GstFFTF64Complex 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 30cbdeea89..4f94bb011b 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; @@ -56,4 +58,6 @@ void gst_fft_s16_inverse_fft (GstFFTS16 *self, const GstFFTS16Complex 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 f73ad9609d..99d7815d16 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; @@ -56,4 +58,6 @@ void gst_fft_s32_inverse_fft (GstFFTS32 *self, const GstFFTS32Complex void gst_fft_s32_window (GstFFTS32 *self, gint32 *timedata, GstFFTWindow window); +G_END_DECLS + #endif /* __GST_FFT_S32_H__ */ diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index c84e95b5bc..6def60157d 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -1100,10 +1100,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; } diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c index d5479e605c..38a34766d8 100644 --- a/gst/playback/gstplaysinkconvertbin.c +++ b/gst/playback/gstplaysinkconvertbin.c @@ -398,7 +398,7 @@ gst_play_sink_convert_bin_getcaps (GstPad * pad, GstCaps * filter) if (peer) { GstCaps *peer_caps = gst_pad_query_caps (peer, filter); gst_object_unref (peer); - if (self->converter_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; 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 b256ea4911..8c3f0e4e92 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,159 @@ 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; + + low = high = 0; + + 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 = 0; + + 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 +4416,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 +4591,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,