diff --git a/ChangeLog b/ChangeLog index fecde4368d..2edbbf03f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2007-06-08 Thomas Vander Stichele + + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * docs/plugins/gst-plugins-bad-plugins.hierarchy: + * docs/plugins/inspect/plugin-wavpack.xml: + * ext/Makefile.am: + * ext/wavpack/Makefile.am: + * ext/wavpack/gstwavpack.c: + * ext/wavpack/gstwavpackcommon.c: + * ext/wavpack/gstwavpackcommon.h: + * ext/wavpack/gstwavpackdec.c: + * ext/wavpack/gstwavpackdec.h: + * ext/wavpack/gstwavpackenc.c: + * ext/wavpack/gstwavpackenc.h: + * ext/wavpack/gstwavpackparse.c: + * ext/wavpack/gstwavpackparse.h: + * ext/wavpack/gstwavpackstreamreader.c: + * ext/wavpack/gstwavpackstreamreader.h: + * ext/wavpack/md5.c: + * ext/wavpack/md5.h: + * tests/check/Makefile.am: + * tests/check/elements/wavpackdec.c: + * tests/check/elements/wavpackenc.c: + * tests/check/elements/wavpackparse.c: + Move wavpack to good. + 2007-06-08 Jan Schmidt * configure.ac: diff --git a/configure.ac b/configure.ac index 4e9ae62049..eaf5bb4e7e 100644 --- a/configure.ac +++ b/configure.ac @@ -878,22 +878,6 @@ int main () { return 0; } ], ) ]) -dnl *** wavpack *** -translit(dnm, m, l) AM_CONDITIONAL(USE_WAVPACK, true) -AG_GST_CHECK_FEATURE(WAVPACK, [wavpack plug-in], wavpack, [ - PKG_CHECK_MODULES(WAVPACK, wavpack >= 4.40.0, HAVE_WAVPACK=yes, [ - PKG_CHECK_MODULES(WAVPACK, wavpack >= 4.20, [ - HAVE_WAVPACK=yes - AC_DEFINE(WAVPACK_OLD_API, 1, [old wavpack API]) - ],[ - HAVE_WAVPACK=no - AC_MSG_RESULT(no) - ]) - ]) - AC_SUBST(WAVPACK_CFLAGS) - AC_SUBST(WAVPACK_LIBS) -]) - dnl *** dvb *** translit(dnm, m, l) AM_CONDITIONAL(USE_DVB, true) AG_GST_CHECK_FEATURE(DVB, [DVB Source], dvb, [ @@ -949,7 +933,6 @@ AM_CONDITIONAL(USE_THEORADEC, false) AM_CONDITIONAL(USE_TIMIDITY, false) AM_CONDITIONAL(USE_X264, false) AM_CONDITIONAL(USE_XVID, false) -AM_CONDITIONAL(USE_WAVPACK, false) AM_CONDITIONAL(USE_WILDMIDI, false) AM_CONDITIONAL(USE_DVB, false) AM_CONDITIONAL(USE_ZLIB, false) @@ -1076,7 +1059,6 @@ ext/spc/Makefile ext/swfdec/Makefile ext/theora/Makefile ext/timidity/Makefile -ext/wavpack/Makefile ext/x264/Makefile ext/xvid/Makefile po/Makefile.in diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index faabf249a0..8c91e2760a 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -96,9 +96,6 @@ EXTRA_HFILES = \ $(top_srcdir)/ext/musicbrainz/gsttrm.h \ $(top_srcdir)/ext/sdl/sdlaudiosink.h \ $(top_srcdir)/ext/sdl/sdlvideosink.h \ - $(top_srcdir)/ext/wavpack/gstwavpackdec.h \ - $(top_srcdir)/ext/wavpack/gstwavpackenc.h \ - $(top_srcdir)/ext/wavpack/gstwavpackparse.h \ $(top_srcdir)/gst/qtdemux/qtdemux.h \ $(top_srcdir)/gst/replaygain/gstrganalysis.h \ $(top_srcdir)/gst/replaygain/gstrglimiter.h \ diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index 81b1b688c8..fb6530bf9b 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -32,9 +32,6 @@ - - - @@ -64,7 +61,6 @@ - diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index f23ca4f7d4..276c467c11 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -234,28 +234,3 @@ GstWaveFormSink GstWaveFormSinkClass - -
-element-wavpackdec -GstWavpackDec -wavpackdec - -GstWavpackDecClass -
- -
-element-wavpackenc -GstWavpackEnc -wavpackenc - -GstWavpackEncClass -
- -
-element-wavpackparse -GstWavpackParse -wavpackparse - -GstWavpackParseClass -
- diff --git a/docs/plugins/gst-plugins-bad-plugins.hierarchy b/docs/plugins/gst-plugins-bad-plugins.hierarchy index b170c1cad9..030639dc8d 100644 --- a/docs/plugins/gst-plugins-bad-plugins.hierarchy +++ b/docs/plugins/gst-plugins-bad-plugins.hierarchy @@ -14,9 +14,6 @@ GObject GstX264Enc GstXvidEnc GstXvidDec - GstWavpackParse - GstWavpackDec - GstWavpackEnc GstSwfdec GstSpcDec GstPitch diff --git a/docs/plugins/inspect/plugin-wavpack.xml b/docs/plugins/inspect/plugin-wavpack.xml deleted file mode 100644 index 7d3ff98eaa..0000000000 --- a/docs/plugins/inspect/plugin-wavpack.xml +++ /dev/null @@ -1,34 +0,0 @@ - - wavpack - Wavpack lossless/lossy audio format handling - ../../ext/wavpack/.libs/libgstwavpack.so - libgstwavpack.so - 0.10.4.1 - LGPL - gst-plugins-bad - GStreamer Bad Plug-ins CVS/prerelease - Unknown package origin - - - wavpackdec - Wavpack audio decoder - Codec/Decoder/Audio - Decodes Wavpack audio data - Arwed v. Merkatz <v.merkatz@gmx.net>, Sebastian Dröge <slomo@circular-chaos.org> - - - wavpackenc - Wavpack audio encoder - Codec/Encoder/Audio - Encodes audio with the Wavpack lossless/lossy audio codec - Sebastian Dröge <slomo@circular-chaos.org> - - - wavpackparse - Wavpack parser - Codec/Demuxer/Audio - Parses Wavpack files - Arwed v. Merkatz <v.merkatz@gmx.net>, Sebastian Dröge <slomo@circular-chaos.org> - - - \ No newline at end of file diff --git a/ext/Makefile.am b/ext/Makefile.am index 1f42647e65..a986ee91b4 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -94,12 +94,6 @@ endif HERMES_DIR= # endif -if USE_WAVPACK -WAVPACK_DIR=wavpack -else -WAVPACK_DIR= -endif - if USE_IVORBIS IVORBIS_DIR=ivorbis else @@ -303,12 +297,11 @@ SUBDIRS=\ $(TARKIN_DIR) \ $(THEORA_DIR) \ $(TIMIDITY_DIR) \ - $(WAVPACK_DIR) \ $(X264_DIR) \ $(XINE_DIR) \ $(XVID_DIR) -DIST_SUBDIRS= \ +DIST_SUBDIRS = \ alsaspdif \ amrwb \ bz2 \ @@ -336,6 +329,5 @@ DIST_SUBDIRS= \ swfdec \ theora \ timidity \ - wavpack \ x264 \ xvid diff --git a/ext/wavpack/Makefile.am b/ext/wavpack/Makefile.am deleted file mode 100644 index 6de09e938d..0000000000 --- a/ext/wavpack/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -plugin_LTLIBRARIES = libgstwavpack.la - -libgstwavpack_la_SOURCES = \ - gstwavpack.c \ - gstwavpackcommon.c \ - gstwavpackparse.c \ - gstwavpackdec.c \ - gstwavpackenc.c \ - gstwavpackstreamreader.c \ - md5.c - -libgstwavpack_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(WAVPACK_CFLAGS) -libgstwavpack_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(WAVPACK_LIBS) -libgstwavpack_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -noinst_HEADERS = \ - gstwavpackparse.h \ - gstwavpackdec.h \ - gstwavpackenc.h \ - gstwavpackcommon.h \ - gstwavpackstreamreader.h \ - md5.h - diff --git a/ext/wavpack/gstwavpack.c b/ext/wavpack/gstwavpack.c deleted file mode 100644 index 580d658ec0..0000000000 --- a/ext/wavpack/gstwavpack.c +++ /dev/null @@ -1,55 +0,0 @@ -/* GStreamer wavpack plugin - * (c) 2004 Arwed v. Merkatz - * - * gstwavpack.c: plugin loader - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstwavpackparse.h" -#include "gstwavpackdec.h" -#include "gstwavpackenc.h" - -/* debug category for common code */ -GST_DEBUG_CATEGORY (wavpack_debug); - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (wavpack_debug, "wavpack", 0, "Wavpack elements"); - -#if ENABLE_NLS - GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE, - LOCALEDIR); - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); -#endif - - return (gst_wavpack_parse_plugin_init (plugin) - && gst_wavpack_dec_plugin_init (plugin) - && gst_wavpack_enc_plugin_init (plugin)); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "wavpack", - "Wavpack lossless/lossy audio format handling", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/wavpack/gstwavpackcommon.c b/ext/wavpack/gstwavpackcommon.c deleted file mode 100644 index ad161867a0..0000000000 --- a/ext/wavpack/gstwavpackcommon.c +++ /dev/null @@ -1,98 +0,0 @@ -/* GStreamer Wavpack plugin - * Copyright (c) 2005 Arwed v. Merkatz - * Copyright (c) 1998 - 2005 Conifer Software - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackcommon.c: common helper functions - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstwavpackcommon.h" -#include - -GST_DEBUG_CATEGORY_EXTERN (wavpack_debug); -#define GST_CAT_DEFAULT wavpack_debug - -gboolean -gst_wavpack_read_header (WavpackHeader * header, guint8 * buf) -{ - g_memmove (header, buf, sizeof (WavpackHeader)); - -#ifndef WAVPACK_OLD_API - WavpackLittleEndianToNative (header, WavpackHeaderFormat); -#else - little_endian_to_native (header, WavpackHeaderFormat); -#endif - - return (memcmp (header->ckID, "wvpk", 4) == 0); -} - -/* inspired by the original one in wavpack */ -gboolean -gst_wavpack_read_metadata (GstWavpackMetadata * wpmd, guint8 * header_data, - guint8 ** p_data) -{ - WavpackHeader hdr; - guint8 *end; - - gst_wavpack_read_header (&hdr, header_data); - end = header_data + hdr.ckSize + 8; - - if (end - *p_data < 2) - return FALSE; - - wpmd->id = GST_READ_UINT8 (*p_data); - wpmd->byte_length = 2 * (guint) GST_READ_UINT8 (*p_data + 1); - - *p_data += 2; - - if ((wpmd->id & ID_LARGE) == ID_LARGE) { - guint extra; - - wpmd->id &= ~ID_LARGE; - - if (end - *p_data < 2) - return FALSE; - - extra = GST_READ_UINT16_LE (*p_data); - wpmd->byte_length += (extra << 9); - *p_data += 2; - } - - if ((wpmd->id & ID_ODD_SIZE) == ID_ODD_SIZE) { - wpmd->id &= ~ID_ODD_SIZE; - --wpmd->byte_length; - } - - if (wpmd->byte_length > 0) { - if (end - *p_data < wpmd->byte_length + (wpmd->byte_length & 1)) { - wpmd->data = NULL; - return FALSE; - } - - wpmd->data = *p_data; - *p_data += wpmd->byte_length + (wpmd->byte_length & 1); - } else { - wpmd->data = NULL; - } - - return TRUE; -} diff --git a/ext/wavpack/gstwavpackcommon.h b/ext/wavpack/gstwavpackcommon.h deleted file mode 100644 index 3cf6e56cac..0000000000 --- a/ext/wavpack/gstwavpackcommon.h +++ /dev/null @@ -1,69 +0,0 @@ -/* GStreamer Wavpack plugin - * Copyright (c) 2005 Arwed v. Merkatz - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackcommon.h: common helper functions - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_WAVPACK_COMMON_H__ -#define __GST_WAVPACK_COMMON_H__ - -#include -#include - -typedef struct -{ - guint32 byte_length; - guint8 *data; - guint8 id; -} GstWavpackMetadata; - -#define ID_UNIQUE 0x3f -#define ID_OPTIONAL_DATA 0x20 -#define ID_ODD_SIZE 0x40 -#define ID_LARGE 0x80 - -#define ID_DUMMY 0x0 -#define ID_ENCODER_INFO 0x1 -#define ID_DECORR_TERMS 0x2 -#define ID_DECORR_WEIGHTS 0x3 -#define ID_DECORR_SAMPLES 0x4 -#define ID_ENTROPY_VARS 0x5 -#define ID_HYBRID_PROFILE 0x6 -#define ID_SHAPING_WEIGHTS 0x7 -#define ID_FLOAT_INFO 0x8 -#define ID_INT32_INFO 0x9 -#define ID_WV_BITSTREAM 0xa -#define ID_WVC_BITSTREAM 0xb -#define ID_WVX_BITSTREAM 0xc -#define ID_CHANNEL_INFO 0xd - -#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1) -#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2) -#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3) -#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4) -#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5) -#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6) -#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7) - - -gboolean gst_wavpack_read_header (WavpackHeader * header, guint8 * buf); -gboolean gst_wavpack_read_metadata (GstWavpackMetadata * meta, - guint8 * header_data, guint8 ** p_data); - -#endif diff --git a/ext/wavpack/gstwavpackdec.c b/ext/wavpack/gstwavpackdec.c deleted file mode 100644 index 5adaf1be48..0000000000 --- a/ext/wavpack/gstwavpackdec.c +++ /dev/null @@ -1,497 +0,0 @@ -/* GStreamer Wavpack plugin - * Copyright (c) 2005 Arwed v. Merkatz - * Copyright (c) 2006 Edward Hervey - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackdec.c: raw Wavpack bitstream decoder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-wavpackdec - * - * - * WavpackDec decodes framed (for example by the WavpackParse element) - * Wavpack streams and decodes them to raw audio. - * Wavpack is an open-source - * audio codec that features both lossless and lossy encoding. - * Example launch line - * - * - * gst-launch filesrc location=test.wv ! wavpackparse ! wavpackdec ! audioconvert ! audioresample ! autoaudiosink - * - * This pipeline decodes the Wavpack file test.wv into raw audio buffers and - * tries to play it back using an automatically found audio sink. - * - * - */ - -#include -#include - -#include -#include - -#include -#include "gstwavpackdec.h" -#include "gstwavpackcommon.h" -#include "gstwavpackstreamreader.h" - - -#define WAVPACK_DEC_MAX_ERRORS 16 - -GST_DEBUG_CATEGORY_STATIC (gst_wavpack_dec_debug); -#define GST_CAT_DEFAULT gst_wavpack_dec_debug - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack, " - "width = (int) [ 1, 32 ], " - "channels = (int) [ 1, 2 ], " - "rate = (int) [ 6000, 192000 ], " "framed = (boolean) true") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "width = (int) 32, " - "depth = (int) [ 1, 32 ], " - "channels = (int) [ 1, 2 ], " - "rate = (int) [ 6000, 192000 ], " - "endianness = (int) BYTE_ORDER, " "signed = (boolean) true") - ); - -static GstFlowReturn gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buffer); -static gboolean gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps); -static gboolean gst_wavpack_dec_sink_event (GstPad * pad, GstEvent * event); -static void gst_wavpack_dec_finalize (GObject * object); -static GstStateChangeReturn gst_wavpack_dec_change_state (GstElement * element, - GstStateChange transition); -static gboolean gst_wavpack_dec_sink_event (GstPad * pad, GstEvent * event); -static void gst_wavpack_dec_post_tags (GstWavpackDec * dec); - -GST_BOILERPLATE (GstWavpackDec, gst_wavpack_dec, GstElement, GST_TYPE_ELEMENT); - -static void -gst_wavpack_dec_base_init (gpointer klass) -{ - static const GstElementDetails plugin_details = - GST_ELEMENT_DETAILS ("Wavpack audio decoder", - "Codec/Decoder/Audio", - "Decodes Wavpack audio data", - "Arwed v. Merkatz , " - "Sebastian Dröge "); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &plugin_details); -} - -static void -gst_wavpack_dec_class_init (GstWavpackDecClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GstElementClass *gstelement_class = (GstElementClass *) klass; - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_wavpack_dec_change_state); - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_wavpack_dec_finalize); -} - -static void -gst_wavpack_dec_reset (GstWavpackDec * dec) -{ - dec->wv_id.buffer = NULL; - dec->wv_id.position = dec->wv_id.length = 0; - - dec->error_count = 0; - - dec->channels = 0; - dec->sample_rate = 0; - dec->depth = 0; - - gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED); -} - -static void -gst_wavpack_dec_init (GstWavpackDec * dec, GstWavpackDecClass * gklass) -{ - dec->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); - gst_pad_set_chain_function (dec->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_dec_chain)); - gst_pad_set_setcaps_function (dec->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_dec_sink_set_caps)); - gst_pad_set_event_function (dec->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_dec_sink_event)); - gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad); - - dec->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); - gst_pad_use_fixed_caps (dec->srcpad); - gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); - - dec->context = NULL; - dec->stream_reader = gst_wavpack_stream_reader_new (); - - gst_wavpack_dec_reset (dec); -} - -static void -gst_wavpack_dec_finalize (GObject * object) -{ - GstWavpackDec *dec = GST_WAVPACK_DEC (object); - - g_free (dec->stream_reader); - dec->stream_reader = NULL; - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps) -{ - GstWavpackDec *dec = GST_WAVPACK_DEC (gst_pad_get_parent (pad)); - GstStructure *structure = gst_caps_get_structure (caps, 0); - - /* Check if we can set the caps here already */ - if (gst_structure_get_int (structure, "channels", &dec->channels) && - gst_structure_get_int (structure, "rate", &dec->sample_rate) && - gst_structure_get_int (structure, "width", &dec->depth)) { - GstCaps *caps; - - caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, dec->sample_rate, - "channels", G_TYPE_INT, dec->channels, - "depth", G_TYPE_INT, dec->depth, - "width", G_TYPE_INT, 32, - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "signed", G_TYPE_BOOLEAN, TRUE, NULL); - - GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps); - - /* should always succeed */ - gst_pad_set_caps (dec->srcpad, caps); - gst_caps_unref (caps); - - /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something - * is decoded or after the format has changed */ - gst_wavpack_dec_post_tags (dec); - } - - gst_object_unref (dec); - - return TRUE; -} - -static gboolean -gst_wavpack_dec_clip_outgoing_buffer (GstWavpackDec * dec, GstBuffer * buf) -{ - gint64 start, stop, cstart, cstop, diff; - - if (dec->segment.format != GST_FORMAT_TIME) - return TRUE; - - start = GST_BUFFER_TIMESTAMP (buf); - stop = start + GST_BUFFER_DURATION (buf); - - if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME, - start, stop, &cstart, &cstop)) { - - diff = cstart - start; - if (diff > 0) { - GST_BUFFER_TIMESTAMP (buf) = cstart; - GST_BUFFER_DURATION (buf) -= diff; - - diff = 4 * dec->channels - * GST_CLOCK_TIME_TO_FRAMES (diff, dec->sample_rate); - GST_BUFFER_DATA (buf) += diff; - GST_BUFFER_SIZE (buf) -= diff; - } - - diff = cstop - stop; - if (diff > 0) { - GST_BUFFER_DURATION (buf) -= diff; - - diff = 4 * dec->channels - * GST_CLOCK_TIME_TO_FRAMES (diff, dec->sample_rate); - GST_BUFFER_SIZE (buf) -= diff; - } - } else { - GST_DEBUG_OBJECT (dec, "buffer is outside configured segment"); - return FALSE; - } - - return TRUE; -} - -static void -gst_wavpack_dec_post_tags (GstWavpackDec * dec) -{ - GstTagList *list; - GstFormat format_time = GST_FORMAT_TIME, format_bytes = GST_FORMAT_BYTES; - gint64 duration, size; - - list = gst_tag_list_new (); - - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, "Wavpack", NULL); - - /* try to estimate the average bitrate */ - if (gst_pad_query_peer_duration (dec->sinkpad, &format_bytes, &size) && - gst_pad_query_peer_duration (dec->sinkpad, &format_time, &duration) && - size > 0 && duration > 0) { - guint64 bitrate; - - bitrate = gst_util_uint64_scale (size, 8 * GST_SECOND, duration); - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE, - (guint) bitrate, NULL); - } - - gst_element_post_message (GST_ELEMENT (dec), - gst_message_new_tag (GST_OBJECT (dec), list)); -} - -static GstFlowReturn -gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf) -{ - GstWavpackDec *dec; - GstBuffer *outbuf; - GstFlowReturn ret = GST_FLOW_OK; - WavpackHeader wph; - int32_t decoded, unpacked_size; - gboolean format_changed; - - dec = GST_WAVPACK_DEC (GST_PAD_PARENT (pad)); - - /* check input, we only accept framed input with complete chunks */ - if (GST_BUFFER_SIZE (buf) < sizeof (WavpackHeader)) - goto input_not_framed; - - if (!gst_wavpack_read_header (&wph, GST_BUFFER_DATA (buf))) - goto invalid_header; - - if (GST_BUFFER_SIZE (buf) != wph.ckSize + 4 * 1 + 4) - goto input_not_framed; - - dec->wv_id.buffer = GST_BUFFER_DATA (buf); - dec->wv_id.length = GST_BUFFER_SIZE (buf); - dec->wv_id.position = 0; - - /* create a new wavpack context if there is none yet but if there - * was already one (i.e. caps were set on the srcpad) check whether - * the new one has the same caps */ - if (!dec->context) { - gchar error_msg[80]; - - dec->context = WavpackOpenFileInputEx (dec->stream_reader, - &dec->wv_id, NULL, error_msg, OPEN_STREAMING, 0); - - if (!dec->context) { - GST_WARNING ("Couldn't decode buffer: %s", error_msg); - dec->error_count++; - if (dec->error_count <= WAVPACK_DEC_MAX_ERRORS) { - goto out; /* just return OK for now */ - } else { - goto decode_error; - } - } - } - - g_assert (dec->context != NULL); - - dec->error_count = 0; - - format_changed = - (dec->sample_rate != WavpackGetSampleRate (dec->context)) || - (dec->channels != WavpackGetNumChannels (dec->context)) || - (dec->depth != WavpackGetBitsPerSample (dec->context)); - - if (!GST_PAD_CAPS (dec->srcpad) || format_changed) { - GstCaps *caps; - - dec->sample_rate = WavpackGetSampleRate (dec->context); - dec->channels = WavpackGetNumChannels (dec->context); - dec->depth = WavpackGetBitsPerSample (dec->context); - - caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, dec->sample_rate, - "channels", G_TYPE_INT, dec->channels, - "depth", G_TYPE_INT, dec->depth, - "width", G_TYPE_INT, 32, - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "signed", G_TYPE_BOOLEAN, TRUE, NULL); - - GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps); - - /* should always succeed */ - gst_pad_set_caps (dec->srcpad, caps); - gst_caps_unref (caps); - - /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something - * is decoded or after the format has changed */ - gst_wavpack_dec_post_tags (dec); - } - - /* alloc output buffer */ - unpacked_size = 4 * wph.block_samples * dec->channels; - ret = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET (buf), - unpacked_size, GST_PAD_CAPS (dec->srcpad), &outbuf); - - if (ret != GST_FLOW_OK) - goto out; - - gst_buffer_stamp (outbuf, buf); - /* If we got a DISCONT buffer forward the flag. Nothing else - * has to be done as libwavpack doesn't store state between - * Wavpack blocks */ - if (GST_BUFFER_IS_DISCONT (buf)) - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); - - /* decode */ - decoded = WavpackUnpackSamples (dec->context, - (int32_t *) GST_BUFFER_DATA (outbuf), wph.block_samples); - if (decoded != wph.block_samples) - goto decode_error; - - if (gst_wavpack_dec_clip_outgoing_buffer (dec, outbuf)) { - GST_LOG_OBJECT (dec, "pushing buffer with time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); - ret = gst_pad_push (dec->srcpad, outbuf); - } else { - gst_buffer_unref (outbuf); - } - -out: - - if (G_UNLIKELY (ret != GST_FLOW_OK)) { - GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (ret)); - } - - gst_buffer_unref (buf); - - return ret; - -/* ERRORS */ -input_not_framed: - { - GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Expected framed input")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -invalid_header: - { - GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Invalid wavpack header")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -decode_error: - { - GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), - ("Failed to decode wavpack stream")); - gst_buffer_unref (outbuf); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -} - -static gboolean -gst_wavpack_dec_sink_event (GstPad * pad, GstEvent * event) -{ - GstWavpackDec *dec = GST_WAVPACK_DEC (gst_pad_get_parent (pad)); - - GST_LOG_OBJECT (dec, "Received %s event", GST_EVENT_TYPE_NAME (event)); - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT:{ - GstFormat fmt; - gboolean is_update; - gint64 start, end, base; - gdouble rate; - - gst_event_parse_new_segment (event, &is_update, &rate, &fmt, &start, - &end, &base); - if (fmt == GST_FORMAT_TIME) { - GST_DEBUG ("Got NEWSEGMENT event in GST_FORMAT_TIME, passing on (%" - GST_TIME_FORMAT " - %" GST_TIME_FORMAT ")", GST_TIME_ARGS (start), - GST_TIME_ARGS (end)); - gst_segment_set_newsegment (&dec->segment, is_update, rate, fmt, - start, end, base); - } else { - gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED); - } - break; - } - default: - break; - } - - gst_object_unref (dec); - return gst_pad_event_default (pad, event); -} - -static GstStateChangeReturn -gst_wavpack_dec_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstWavpackDec *dec = GST_WAVPACK_DEC (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - if (dec->context) { - WavpackCloseFile (dec->context); - dec->context = NULL; - } - - gst_wavpack_dec_reset (dec); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - -gboolean -gst_wavpack_dec_plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "wavpackdec", - GST_RANK_PRIMARY, GST_TYPE_WAVPACK_DEC)) - return FALSE; - GST_DEBUG_CATEGORY_INIT (gst_wavpack_dec_debug, "wavpack_dec", 0, - "Wavpack decoder"); - return TRUE; -} diff --git a/ext/wavpack/gstwavpackdec.h b/ext/wavpack/gstwavpackdec.h deleted file mode 100644 index 68380ca5d3..0000000000 --- a/ext/wavpack/gstwavpackdec.h +++ /dev/null @@ -1,78 +0,0 @@ -/* GStreamer Wavpack plugin - * Copyright (c) 2004 Arwed v. Merkatz - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackdec.h: raw Wavpack bitstream decoder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_WAVPACK_DEC_H__ -#define __GST_WAVPACK_DEC_H__ - -#include - -#include - -#include "gstwavpackstreamreader.h" - -G_BEGIN_DECLS -#define GST_TYPE_WAVPACK_DEC \ - (gst_wavpack_dec_get_type()) -#define GST_WAVPACK_DEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAVPACK_DEC,GstWavpackDec)) -#define GST_WAVPACK_DEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAVPACK_DEC,GstWavpackDecClass)) -#define GST_IS_WAVPACK_DEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAVPACK_DEC)) -#define GST_IS_WAVPACK_DEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAVPACK_DEC)) -typedef struct _GstWavpackDec GstWavpackDec; -typedef struct _GstWavpackDecClass GstWavpackDecClass; - -struct _GstWavpackDec -{ - GstElement element; - - /*< private > */ - GstPad *sinkpad; - GstPad *srcpad; - - WavpackContext *context; - WavpackStreamReader *stream_reader; - - read_id wv_id; - - GstSegment segment; /* used for clipping, TIME format */ - - gint sample_rate; - gint depth; - gint channels; - - gint error_count; -}; - -struct _GstWavpackDecClass -{ - GstElementClass parent; -}; - -GType gst_wavpack_dec_get_type (void); - -gboolean gst_wavpack_dec_plugin_init (GstPlugin * plugin); - -G_END_DECLS -#endif /* __GST_WAVPACK_DEC_H__ */ diff --git a/ext/wavpack/gstwavpackenc.c b/ext/wavpack/gstwavpackenc.c deleted file mode 100644 index ad5e8adaad..0000000000 --- a/ext/wavpack/gstwavpackenc.c +++ /dev/null @@ -1,908 +0,0 @@ -/* GStreamer Wavpack encoder plugin - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackdec.c: Wavpack audio encoder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-wavpackenc - * - * - * WavpackEnc encodes raw audio into a framed Wavpack stream. - * Wavpack is an open-source - * audio codec that features both lossless and lossy encoding. - * Example launch line - * - * - * gst-launch audiotestsrc num-buffers=500 ! audioconvert ! wavpackenc ! filesink location=sinewave.wv - * - * This pipeline encodes audio from audiotestsrc into a Wavpack file. The audioconvert element is needed - * as the Wavpack encoder only accepts input with 32 bit width (and every depth between 1 and 32 bits). - * - * - * - * gst-launch cdda://1 ! audioconvert ! wavpackenc ! filesink location=track1.wv - * - * This pipeline encodes audio from an audio CD into a Wavpack file using - * lossless encoding (the file output will be fairly large). - * - * - * - * gst-launch cdda://1 ! audioconvert ! wavpackenc bitrate=128000 ! filesink location=track1.wv - * - * This pipeline encodes audio from an audio CD into a Wavpack file using - * lossy encoding at a certain bitrate (the file will be fairly small). - * - * - */ - -/* - * TODO: - add multichannel handling. channel_mask is: - * front left - * front right - * center - * LFE - * back left - * back right - * front left center - * front right center - * back left - * back center - * side left - * side right - * ... - * - add 32 bit float mode. CONFIG_FLOAT_DATA - */ - -#include -#include -#include - -#include -#include "gstwavpackenc.h" -#include "gstwavpackcommon.h" -#include "md5.h" - -static GstFlowReturn gst_wavpack_enc_chain (GstPad * pad, GstBuffer * buffer); -static gboolean gst_wavpack_enc_sink_set_caps (GstPad * pad, GstCaps * caps); -static int gst_wavpack_enc_push_block (void *id, void *data, int32_t count); -static gboolean gst_wavpack_enc_sink_event (GstPad * pad, GstEvent * event); -static GstStateChangeReturn gst_wavpack_enc_change_state (GstElement * element, - GstStateChange transition); -static void gst_wavpack_enc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_wavpack_enc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -enum -{ - ARG_0, - ARG_MODE, - ARG_BITRATE, - ARG_BITSPERSAMPLE, - ARG_CORRECTION_MODE, - ARG_MD5, - ARG_EXTRA_PROCESSING, - ARG_JOINT_STEREO_MODE -}; - -GST_DEBUG_CATEGORY_STATIC (gst_wavpack_enc_debug); -#define GST_CAT_DEFAULT gst_wavpack_enc_debug - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "width = (int) 32, " - "depth = (int) [ 1, 32], " - "endianness = (int) BYTE_ORDER, " - "channels = (int) [ 1, 2 ], " - "rate = (int) [ 6000, 192000 ]," "signed = (boolean) TRUE") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack, " - "width = (int) [ 1, 32 ], " - "channels = (int) [ 1, 2 ], " - "rate = (int) [ 6000, 192000 ], " "framed = (boolean) TRUE") - ); - -static GstStaticPadTemplate wvcsrc_factory = GST_STATIC_PAD_TEMPLATE ("wvcsrc", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("audio/x-wavpack-correction, " "framed = (boolean) TRUE") - ); - -enum -{ - GST_WAVPACK_ENC_MODE_VERY_FAST = 0, - GST_WAVPACK_ENC_MODE_FAST, - GST_WAVPACK_ENC_MODE_DEFAULT, - GST_WAVPACK_ENC_MODE_HIGH, - GST_WAVPACK_ENC_MODE_VERY_HIGH -}; - -#define GST_TYPE_WAVPACK_ENC_MODE (gst_wavpack_enc_mode_get_type ()) -static GType -gst_wavpack_enc_mode_get_type (void) -{ - static GType qtype = 0; - - if (qtype == 0) { - static const GEnumValue values[] = { -#if 0 - /* Very Fast Compression is not supported yet, but will be supported - * in future wavpack versions */ - {GST_WAVPACK_ENC_MODE_VERY_FAST, "Very Fast Compression", "veryfast"}, -#endif - {GST_WAVPACK_ENC_MODE_FAST, "Fast Compression", "fast"}, - {GST_WAVPACK_ENC_MODE_DEFAULT, "Normal Compression", "normal"}, - {GST_WAVPACK_ENC_MODE_HIGH, "High Compression", "high"}, -#ifndef WAVPACK_OLD_API - {GST_WAVPACK_ENC_MODE_VERY_HIGH, "Very High Compression", "veryhigh"}, -#endif - {0, NULL, NULL} - }; - - qtype = g_enum_register_static ("GstWavpackEncMode", values); - } - return qtype; -} - -enum -{ - GST_WAVPACK_CORRECTION_MODE_OFF = 0, - GST_WAVPACK_CORRECTION_MODE_ON, - GST_WAVPACK_CORRECTION_MODE_OPTIMIZED -}; - -#define GST_TYPE_WAVPACK_ENC_CORRECTION_MODE (gst_wavpack_enc_correction_mode_get_type ()) -static GType -gst_wavpack_enc_correction_mode_get_type (void) -{ - static GType qtype = 0; - - if (qtype == 0) { - static const GEnumValue values[] = { - {GST_WAVPACK_CORRECTION_MODE_OFF, "Create no correction file", "off"}, - {GST_WAVPACK_CORRECTION_MODE_ON, "Create correction file", "on"}, - {GST_WAVPACK_CORRECTION_MODE_OPTIMIZED, - "Create optimized correction file", "optimized"}, - {0, NULL, NULL} - }; - - qtype = g_enum_register_static ("GstWavpackEncCorrectionMode", values); - } - return qtype; -} - -enum -{ - GST_WAVPACK_JS_MODE_AUTO = 0, - GST_WAVPACK_JS_MODE_LEFT_RIGHT, - GST_WAVPACK_JS_MODE_MID_SIDE -}; - -#define GST_TYPE_WAVPACK_ENC_JOINT_STEREO_MODE (gst_wavpack_enc_joint_stereo_mode_get_type ()) -static GType -gst_wavpack_enc_joint_stereo_mode_get_type (void) -{ - static GType qtype = 0; - - if (qtype == 0) { - static const GEnumValue values[] = { - {GST_WAVPACK_JS_MODE_AUTO, "auto", "auto"}, - {GST_WAVPACK_JS_MODE_LEFT_RIGHT, "left/right", "leftright"}, - {GST_WAVPACK_JS_MODE_MID_SIDE, "mid/side", "midside"}, - {0, NULL, NULL} - }; - - qtype = g_enum_register_static ("GstWavpackEncJSMode", values); - } - return qtype; -} - -GST_BOILERPLATE (GstWavpackEnc, gst_wavpack_enc, GstElement, GST_TYPE_ELEMENT); - -static void -gst_wavpack_enc_base_init (gpointer klass) -{ - static const GstElementDetails element_details = { - "Wavpack audio encoder", - "Codec/Encoder/Audio", - "Encodes audio with the Wavpack lossless/lossy audio codec", - "Sebastian Dröge " - }; - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - /* add pad templates */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&wvcsrc_factory)); - - /* set element details */ - gst_element_class_set_details (element_class, &element_details); -} - - -static void -gst_wavpack_enc_class_init (GstWavpackEncClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GstElementClass *gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - /* set state change handler */ - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_wavpack_enc_change_state); - - /* set property handlers */ - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_wavpack_enc_set_property); - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_wavpack_enc_get_property); - - /* install all properties */ - g_object_class_install_property (gobject_class, ARG_MODE, - g_param_spec_enum ("mode", "Encoding mode", - "Speed versus compression tradeoff.", - GST_TYPE_WAVPACK_ENC_MODE, GST_WAVPACK_ENC_MODE_DEFAULT, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_BITRATE, - g_param_spec_uint ("bitrate", "Bitrate", - "Try to encode with this average bitrate (bits/sec). " - "This enables lossy encoding, values smaller than 24000 disable it again.", - 0, 9600000, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_BITSPERSAMPLE, - g_param_spec_double ("bits-per-sample", "Bits per sample", - "Try to encode with this amount of bits per sample. " - "This enables lossy encoding, values smaller than 2.0 disable it again.", - 0.0, 24.0, 0.0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_CORRECTION_MODE, - g_param_spec_enum ("correction-mode", "Correction stream mode", - "Use this mode for the correction stream. Only works in lossy mode!", - GST_TYPE_WAVPACK_ENC_CORRECTION_MODE, GST_WAVPACK_CORRECTION_MODE_OFF, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_MD5, - g_param_spec_boolean ("md5", "MD5", - "Store MD5 hash of raw samples within the file.", FALSE, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_EXTRA_PROCESSING, - g_param_spec_uint ("extra-processing", "Extra processing", - "Use better but slower filters for better compression/quality.", - 0, 6, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_JOINT_STEREO_MODE, - g_param_spec_enum ("joint-stereo-mode", "Joint-Stereo mode", - "Use this joint-stereo mode.", GST_TYPE_WAVPACK_ENC_JOINT_STEREO_MODE, - GST_WAVPACK_JS_MODE_AUTO, G_PARAM_READWRITE)); -} - -static void -gst_wavpack_enc_reset (GstWavpackEnc * enc) -{ - /* close and free everything stream related if we already did something */ - if (enc->wp_context) { - WavpackCloseFile (enc->wp_context); - enc->wp_context = NULL; - } - if (enc->wp_config) { - g_free (enc->wp_config); - enc->wp_config = NULL; - } - if (enc->first_block) { - g_free (enc->first_block); - enc->first_block = NULL; - } - enc->first_block_size = 0; - if (enc->md5_context) { - g_free (enc->md5_context); - enc->md5_context = NULL; - } - - /* reset the last returns to GST_FLOW_OK. This is only set to something else - * while WavpackPackSamples() or more specific gst_wavpack_enc_push_block() - * so not valid anymore */ - enc->srcpad_last_return = enc->wvcsrcpad_last_return = GST_FLOW_OK; - - /* reset stream information */ - enc->samplerate = 0; - enc->depth = 0; - enc->channels = 0; -} - -static void -gst_wavpack_enc_init (GstWavpackEnc * enc, GstWavpackEncClass * gclass) -{ - enc->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); - gst_pad_set_setcaps_function (enc->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_enc_sink_set_caps)); - gst_pad_set_chain_function (enc->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_enc_chain)); - gst_pad_set_event_function (enc->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_enc_sink_event)); - gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad); - - /* setup src pad */ - enc->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); - gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad); - - /* initialize object attributes */ - enc->wp_config = NULL; - enc->wp_context = NULL; - enc->first_block = NULL; - enc->md5_context = NULL; - gst_wavpack_enc_reset (enc); - - enc->wv_id.correction = FALSE; - enc->wv_id.wavpack_enc = enc; - enc->wvc_id.correction = TRUE; - enc->wvc_id.wavpack_enc = enc; - - /* set default values of params */ - enc->mode = GST_WAVPACK_ENC_MODE_DEFAULT; - enc->bitrate = 0; - enc->bps = 0.0; - enc->correction_mode = GST_WAVPACK_CORRECTION_MODE_OFF; - enc->md5 = FALSE; - enc->extra_processing = 0; - enc->joint_stereo_mode = GST_WAVPACK_JS_MODE_AUTO; -} - -static gboolean -gst_wavpack_enc_sink_set_caps (GstPad * pad, GstCaps * caps) -{ - GstWavpackEnc *enc = GST_WAVPACK_ENC (gst_pad_get_parent (pad)); - GstStructure *structure = gst_caps_get_structure (caps, 0); - - /* FIXME: Workaround for bug #421543: calls gst_pad_accept_caps() */ - /* check caps and put relevant parts into our object attributes */ - if (!gst_pad_accept_caps (pad, caps) || - !gst_structure_get_int (structure, "channels", &enc->channels) || - !gst_structure_get_int (structure, "rate", &enc->samplerate) || - !gst_structure_get_int (structure, "depth", &enc->depth)) { - GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), - ("got invalid caps: %" GST_PTR_FORMAT, caps)); - gst_object_unref (enc); - return FALSE; - } - - /* set fixed src pad caps now that we know what we will get */ - caps = gst_caps_new_simple ("audio/x-wavpack", - "channels", G_TYPE_INT, enc->channels, - "rate", G_TYPE_INT, enc->samplerate, - "width", G_TYPE_INT, enc->depth, "framed", G_TYPE_BOOLEAN, TRUE, NULL); - - if (!gst_pad_set_caps (enc->srcpad, caps)) { - GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), - ("setting caps failed: %" GST_PTR_FORMAT, caps)); - gst_caps_unref (caps); - gst_object_unref (enc); - return FALSE; - } - gst_pad_use_fixed_caps (enc->srcpad); - - gst_caps_unref (caps); - gst_object_unref (enc); - return TRUE; -} - -static void -gst_wavpack_enc_set_wp_config (GstWavpackEnc * enc) -{ - enc->wp_config = g_new0 (WavpackConfig, 1); - /* set general stream informations in the WavpackConfig */ - enc->wp_config->bytes_per_sample = GST_ROUND_UP_8 (enc->depth) / 8; - enc->wp_config->bits_per_sample = enc->depth; - enc->wp_config->num_channels = enc->channels; - - /* TODO: handle more than 2 channels correctly! */ - if (enc->channels == 1) { - enc->wp_config->channel_mask = 0x4; - } else if (enc->channels == 2) { - enc->wp_config->channel_mask = 0x2 | 0x1; - } - enc->wp_config->sample_rate = enc->samplerate; - - /* - * Set parameters in WavpackConfig - */ - - /* Encoding mode */ - switch (enc->mode) { -#if 0 - case GST_WAVPACK_ENC_MODE_VERY_FAST: - enc->wp_config->flags |= CONFIG_VERY_FAST_FLAG; - enc->wp_config->flags |= CONFIG_FAST_FLAG; - break; -#endif - case GST_WAVPACK_ENC_MODE_FAST: - enc->wp_config->flags |= CONFIG_FAST_FLAG; - break; - case GST_WAVPACK_ENC_MODE_DEFAULT: - break; - case GST_WAVPACK_ENC_MODE_HIGH: - enc->wp_config->flags |= CONFIG_HIGH_FLAG; - break; -#ifndef WAVPACK_OLD_API - case GST_WAVPACK_ENC_MODE_VERY_HIGH: - enc->wp_config->flags |= CONFIG_HIGH_FLAG; - enc->wp_config->flags |= CONFIG_VERY_HIGH_FLAG; - break; -#endif - } - - /* Bitrate, enables lossy mode */ - if (enc->bitrate) { - enc->wp_config->flags |= CONFIG_HYBRID_FLAG; - enc->wp_config->flags |= CONFIG_BITRATE_KBPS; - enc->wp_config->bitrate = enc->bitrate / 1000.0; - } else if (enc->bps) { - enc->wp_config->flags |= CONFIG_HYBRID_FLAG; - enc->wp_config->bitrate = enc->bps; - } - - /* Correction Mode, only in lossy mode */ - if (enc->wp_config->flags & CONFIG_HYBRID_FLAG) { - if (enc->correction_mode > GST_WAVPACK_CORRECTION_MODE_OFF) { - enc->wvcsrcpad = - gst_pad_new_from_static_template (&wvcsrc_factory, "wvcsrc"); - - /* try to add correction src pad, don't set correction mode on failure */ - GstCaps *caps = gst_caps_new_simple ("audio/x-wavpack-correction", - "framed", G_TYPE_BOOLEAN, TRUE, NULL); - - GST_DEBUG_OBJECT (enc, "Adding correction pad with caps %" - GST_PTR_FORMAT, caps); - if (!gst_pad_set_caps (enc->wvcsrcpad, caps)) { - enc->correction_mode = 0; - GST_WARNING_OBJECT (enc, "setting correction caps failed"); - } else { - gst_pad_use_fixed_caps (enc->wvcsrcpad); - gst_pad_set_active (enc->wvcsrcpad, TRUE); - gst_element_add_pad (GST_ELEMENT (enc), enc->wvcsrcpad); - enc->wp_config->flags |= CONFIG_CREATE_WVC; - if (enc->correction_mode == GST_WAVPACK_CORRECTION_MODE_OPTIMIZED) { - enc->wp_config->flags |= CONFIG_OPTIMIZE_WVC; - } - } - gst_caps_unref (caps); - } - } else { - if (enc->correction_mode > GST_WAVPACK_CORRECTION_MODE_OFF) { - enc->correction_mode = 0; - GST_WARNING_OBJECT (enc, "setting correction mode only has " - "any effect if a bitrate is provided."); - } - } - gst_element_no_more_pads (GST_ELEMENT (enc)); - - /* MD5, setup MD5 context */ - if ((enc->md5) && !(enc->md5_context)) { - enc->wp_config->flags |= CONFIG_MD5_CHECKSUM; - enc->md5_context = g_new0 (MD5_CTX, 1); - MD5Init (enc->md5_context); - } - - /* Extra encode processing */ - if (enc->extra_processing) { - enc->wp_config->flags |= CONFIG_EXTRA_MODE; - enc->wp_config->xmode = enc->extra_processing; - } - - /* Joint stereo mode */ - switch (enc->joint_stereo_mode) { - case GST_WAVPACK_JS_MODE_AUTO: - break; - case GST_WAVPACK_JS_MODE_LEFT_RIGHT: - enc->wp_config->flags |= CONFIG_JOINT_OVERRIDE; - enc->wp_config->flags &= ~CONFIG_JOINT_STEREO; - break; - case GST_WAVPACK_JS_MODE_MID_SIDE: - enc->wp_config->flags |= (CONFIG_JOINT_OVERRIDE | CONFIG_JOINT_STEREO); - break; - } -} - -static int -gst_wavpack_enc_push_block (void *id, void *data, int32_t count) -{ - GstWavpackEncWriteID *wid = (GstWavpackEncWriteID *) id; - GstWavpackEnc *enc = GST_WAVPACK_ENC (wid->wavpack_enc); - GstFlowReturn *flow; - GstBuffer *buffer; - GstPad *pad; - guchar *block = (guchar *) data; - - pad = (wid->correction) ? enc->wvcsrcpad : enc->srcpad; - flow = - (wid->correction) ? &enc->wvcsrcpad_last_return : &enc-> - srcpad_last_return; - - *flow = gst_pad_alloc_buffer_and_set_caps (pad, GST_BUFFER_OFFSET_NONE, - count, GST_PAD_CAPS (pad), &buffer); - - if (*flow != GST_FLOW_OK) { - GST_WARNING_OBJECT (enc, "flow on %s:%s = %s", - GST_DEBUG_PAD_NAME (pad), gst_flow_get_name (*flow)); - return FALSE; - } - - g_memmove (GST_BUFFER_DATA (buffer), block, count); - - if (count > sizeof (WavpackHeader) && memcmp (block, "wvpk", 4) == 0) { - /* if it's a Wavpack block set buffer timestamp and duration, etc */ - WavpackHeader wph; - - GST_LOG_OBJECT (enc, "got %d bytes of encoded wavpack %sdata", - count, (wid->correction) ? "correction " : ""); - - gst_wavpack_read_header (&wph, block); - - /* if it's the first wavpack block, send a NEW_SEGMENT event */ - if (wph.block_index == 0) { - gst_pad_push_event (pad, - gst_event_new_new_segment (FALSE, - 1.0, GST_FORMAT_TIME, 0, GST_BUFFER_OFFSET_NONE, 0)); - - /* save header for later reference, so we can re-send it later on - * EOS with fixed up values for total sample count etc. */ - if (enc->first_block == NULL && !wid->correction) { - enc->first_block = g_memdup (block, count); - enc->first_block_size = count; - } - } - - /* set buffer timestamp, duration, offset, offset_end from - * the wavpack header */ - GST_BUFFER_TIMESTAMP (buffer) = - gst_util_uint64_scale_int (GST_SECOND, wph.block_index, - enc->samplerate); - GST_BUFFER_DURATION (buffer) = - gst_util_uint64_scale_int (GST_SECOND, wph.block_samples, - enc->samplerate); - GST_BUFFER_OFFSET (buffer) = wph.block_index; - GST_BUFFER_OFFSET_END (buffer) = wph.block_index + wph.block_samples; - } else { - /* if it's something else set no timestamp and duration on the buffer */ - GST_DEBUG_OBJECT (enc, "got %d bytes of unknown data", count); - - GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE; - GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE; - } - - /* push the buffer and forward errors */ - *flow = gst_pad_push (pad, buffer); - - if (*flow != GST_FLOW_OK) { - GST_WARNING_OBJECT (enc, "flow on %s:%s = %s", - GST_DEBUG_PAD_NAME (pad), gst_flow_get_name (*flow)); - return FALSE; - } - - return TRUE; -} - -static GstFlowReturn -gst_wavpack_enc_chain (GstPad * pad, GstBuffer * buf) -{ - GstWavpackEnc *enc = GST_WAVPACK_ENC (gst_pad_get_parent (pad)); - uint32_t sample_count = GST_BUFFER_SIZE (buf) / 4; - GstFlowReturn ret; - - /* reset the last returns to GST_FLOW_OK. This is only set to something else - * while WavpackPackSamples() or more specific gst_wavpack_enc_push_block() - * so not valid anymore */ - enc->srcpad_last_return = enc->wvcsrcpad_last_return = GST_FLOW_OK; - - GST_DEBUG ("got %u raw samples", sample_count); - - /* check if we already have a valid WavpackContext, otherwise make one */ - if (!enc->wp_context) { - /* create raw context */ - enc->wp_context = - WavpackOpenFileOutput (gst_wavpack_enc_push_block, &enc->wv_id, - (enc->correction_mode > 0) ? &enc->wvc_id : NULL); - if (!enc->wp_context) { - GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), - ("error creating Wavpack context")); - gst_object_unref (enc); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } - - /* set the WavpackConfig according to our parameters */ - gst_wavpack_enc_set_wp_config (enc); - - /* set the configuration to the context now that we know everything - * and initialize the encoder */ - if (!WavpackSetConfiguration (enc->wp_context, - enc->wp_config, (uint32_t) (-1)) - || !WavpackPackInit (enc->wp_context)) { - GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), - ("error setting up wavpack encoding context")); - WavpackCloseFile (enc->wp_context); - gst_object_unref (enc); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } - GST_DEBUG ("setup of encoding context successfull"); - } - - /* if we want to append the MD5 sum to the stream update it here - * with the current raw samples */ - if (enc->md5) { - MD5Update (enc->md5_context, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - } - - /* encode and handle return values from encoding */ - if (WavpackPackSamples (enc->wp_context, (int32_t *) GST_BUFFER_DATA (buf), - sample_count / enc->channels)) { - GST_DEBUG ("encoding samples successful"); - ret = GST_FLOW_OK; - } else { - if ((enc->srcpad_last_return == GST_FLOW_RESEND) || - (enc->wvcsrcpad_last_return == GST_FLOW_RESEND)) { - ret = GST_FLOW_RESEND; - } else if ((enc->srcpad_last_return == GST_FLOW_OK) || - (enc->wvcsrcpad_last_return == GST_FLOW_OK)) { - ret = GST_FLOW_OK; - } else if ((enc->srcpad_last_return == GST_FLOW_NOT_LINKED) && - (enc->wvcsrcpad_last_return == GST_FLOW_NOT_LINKED)) { - ret = GST_FLOW_NOT_LINKED; - } else if ((enc->srcpad_last_return == GST_FLOW_WRONG_STATE) && - (enc->wvcsrcpad_last_return == GST_FLOW_WRONG_STATE)) { - ret = GST_FLOW_WRONG_STATE; - } else { - GST_ELEMENT_ERROR (enc, LIBRARY, ENCODE, (NULL), - ("encoding samples failed")); - ret = GST_FLOW_ERROR; - } - } - - gst_buffer_unref (buf); - gst_object_unref (enc); - return ret; -} - -static void -gst_wavpack_enc_rewrite_first_block (GstWavpackEnc * enc) -{ - GstEvent *event = gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, - 0, GST_BUFFER_OFFSET_NONE, 0); - gboolean ret; - - g_return_if_fail (enc); - g_return_if_fail (enc->first_block); - - /* update the sample count in the first block */ - WavpackUpdateNumSamples (enc->wp_context, enc->first_block); - - /* try to seek to the beginning of the output */ - ret = gst_pad_push_event (enc->srcpad, event); - if (ret) { - /* try to rewrite the first block */ - GST_DEBUG_OBJECT (enc, "rewriting first block ..."); - ret = gst_wavpack_enc_push_block (&enc->wv_id, - enc->first_block, enc->first_block_size); - } else { - GST_WARNING_OBJECT (enc, "rewriting of first block failed. " - "Seeking to first block failed!"); - } -} - -static gboolean -gst_wavpack_enc_sink_event (GstPad * pad, GstEvent * event) -{ - GstWavpackEnc *enc = GST_WAVPACK_ENC (gst_pad_get_parent (pad)); - gboolean ret = TRUE; - - GST_DEBUG ("Received %s event on sinkpad", GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - /* Encode all remaining samples and flush them to the src pads */ - WavpackFlushSamples (enc->wp_context); - - /* write the MD5 sum if we have to write one */ - if ((enc->md5) && (enc->md5_context)) { - guchar md5_digest[16]; - - MD5Final (md5_digest, enc->md5_context); - WavpackStoreMD5Sum (enc->wp_context, md5_digest); - } - - /* Try to rewrite the first frame with the correct sample number */ - if (enc->first_block) - gst_wavpack_enc_rewrite_first_block (enc); - - /* close the context if not already happened */ - if (enc->wp_context) { - WavpackCloseFile (enc->wp_context); - enc->wp_context = NULL; - } - - ret = gst_pad_event_default (pad, event); - break; - case GST_EVENT_NEWSEGMENT: - if (enc->wp_context) { - GST_WARNING_OBJECT (enc, "got NEWSEGMENT after encoding " - "already started"); - } - /* drop NEWSEGMENT events, we create our own when pushing - * the first buffer to the pads */ - gst_event_unref (event); - ret = TRUE; - break; - default: - ret = gst_pad_event_default (pad, event); - break; - } - - gst_object_unref (enc); - return ret; -} - -static GstStateChangeReturn -gst_wavpack_enc_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstWavpackEnc *enc = GST_WAVPACK_ENC (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - /* set the last returned GstFlowReturns of the two pads to GST_FLOW_OK - * as they're only set to something else in WavpackPackSamples() or more - * specific gst_wavpack_enc_push_block() and nothing happened there yet */ - enc->srcpad_last_return = enc->wvcsrcpad_last_return = GST_FLOW_OK; - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_wavpack_enc_reset (enc); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - -static void -gst_wavpack_enc_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstWavpackEnc *enc = GST_WAVPACK_ENC (object); - - switch (prop_id) { - case ARG_MODE: - enc->mode = g_value_get_enum (value); - break; - case ARG_BITRATE:{ - guint val = g_value_get_uint (value); - - if ((val >= 24000) && (val <= 9600000)) { - enc->bitrate = val; - enc->bps = 0.0; - } else { - enc->bitrate = 0; - enc->bps = 0.0; - } - break; - } - case ARG_BITSPERSAMPLE:{ - gdouble val = g_value_get_double (value); - - if ((val >= 2.0) && (val <= 24.0)) { - enc->bps = val; - enc->bitrate = 0; - } else { - enc->bps = 0.0; - enc->bitrate = 0; - } - break; - } - case ARG_CORRECTION_MODE: - enc->correction_mode = g_value_get_enum (value); - break; - case ARG_MD5: - enc->md5 = g_value_get_boolean (value); - break; - case ARG_EXTRA_PROCESSING: - enc->extra_processing = g_value_get_uint (value); - break; - case ARG_JOINT_STEREO_MODE: - enc->joint_stereo_mode = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_wavpack_enc_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstWavpackEnc *enc = GST_WAVPACK_ENC (object); - - switch (prop_id) { - case ARG_MODE: - g_value_set_enum (value, enc->mode); - break; - case ARG_BITRATE: - if (enc->bps == 0.0) { - g_value_set_uint (value, enc->bitrate); - } else { - g_value_set_uint (value, 0); - } - break; - case ARG_BITSPERSAMPLE: - if (enc->bitrate == 0) { - g_value_set_double (value, enc->bps); - } else { - g_value_set_double (value, 0.0); - } - break; - case ARG_CORRECTION_MODE: - g_value_set_enum (value, enc->correction_mode); - break; - case ARG_MD5: - g_value_set_boolean (value, enc->md5); - break; - case ARG_EXTRA_PROCESSING: - g_value_set_uint (value, enc->extra_processing); - break; - case ARG_JOINT_STEREO_MODE: - g_value_set_enum (value, enc->joint_stereo_mode); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -gboolean -gst_wavpack_enc_plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "wavpackenc", - GST_RANK_NONE, GST_TYPE_WAVPACK_ENC)) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (gst_wavpack_enc_debug, "wavpack_enc", 0, - "Wavpack encoder"); - - return TRUE; -} diff --git a/ext/wavpack/gstwavpackenc.h b/ext/wavpack/gstwavpackenc.h deleted file mode 100644 index 243e8d7b10..0000000000 --- a/ext/wavpack/gstwavpackenc.h +++ /dev/null @@ -1,95 +0,0 @@ -/* GStreamer Wavpack encoder plugin - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackenc.h: Wavpack audio encoder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_WAVPACK_ENC_H__ -#define __GST_WAVPACK_ENC_H__ - -#include - -#include -#include "md5.h" - -G_BEGIN_DECLS -#define GST_TYPE_WAVPACK_ENC \ - (gst_wavpack_enc_get_type()) -#define GST_WAVPACK_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAVPACK_ENC,GstWavpackEnc)) -#define GST_WAVPACK_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAVPACK_ENC,GstWavpackEnc)) -#define GST_IS_WAVPACK_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAVPACK_ENC)) -#define GST_IS_WAVPACK_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAVPACK_ENC)) -typedef struct _GstWavpackEnc GstWavpackEnc; -typedef struct _GstWavpackEncClass GstWavpackEncClass; - -typedef struct -{ - gboolean correction; - GstWavpackEnc *wavpack_enc; -} GstWavpackEncWriteID; - - -struct _GstWavpackEnc -{ - GstElement element; - - /*< private > */ - GstPad *sinkpad, *srcpad; - GstPad *wvcsrcpad; - - GstFlowReturn srcpad_last_return; - GstFlowReturn wvcsrcpad_last_return; - - WavpackConfig *wp_config; - WavpackContext *wp_context; - - gint samplerate; - gint channels; - gint depth; - - GstWavpackEncWriteID wv_id; - GstWavpackEncWriteID wvc_id; - - guint mode; - guint bitrate; - gdouble bps; - guint correction_mode; - gboolean md5; - MD5_CTX *md5_context; - guint extra_processing; - guint joint_stereo_mode; - - void *first_block; - int32_t first_block_size; -}; - -struct _GstWavpackEncClass -{ - GstElementClass parent; -}; - -GType gst_wavpack_enc_get_type (void); - -gboolean gst_wavpack_enc_plugin_init (GstPlugin * plugin); - -G_END_DECLS -#endif /* __GST_WAVPACK_ENC_H__ */ diff --git a/ext/wavpack/gstwavpackparse.c b/ext/wavpack/gstwavpackparse.c deleted file mode 100644 index 61c94f1e30..0000000000 --- a/ext/wavpack/gstwavpackparse.c +++ /dev/null @@ -1,1221 +0,0 @@ -/* GStreamer wavpack plugin - * Copyright (c) 2005 Arwed v. Merkatz - * Copyright (c) 2006 Tim-Philipp Müller - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackparse.c: wavpack file parser - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-wavpackparse - * - * - * WavpackParse takes raw, unframed Wavpack streams and splits them into - * single Wavpack chunks with information like bit depth and the position - * in the stream. - * Wavpack is an open-source - * audio codec that features both lossless and lossy encoding. - * Example launch line - * - * - * gst-launch filesrc location=test.wv ! wavpackparse ! wavpackdec ! fakesink - * - * This pipeline decodes the Wavpack file test.wv into raw audio buffers. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include - -#include -#include - -#include -#include "gstwavpackparse.h" -#include "gstwavpackstreamreader.h" -#include "gstwavpackcommon.h" - -GST_DEBUG_CATEGORY_STATIC (gst_wavpack_parse_debug); -#define GST_CAT_DEFAULT gst_wavpack_parse_debug - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack, " - "framed = (boolean) false; " - "audio/x-wavpack-correction, " "framed = (boolean) false") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("audio/x-wavpack, " - "width = (int) [ 1, 32 ], " - "channels = (int) [ 1, 2 ], " - "rate = (int) [ 6000, 192000 ], " "framed = (boolean) true") - ); - -static GstStaticPadTemplate wvc_src_factory = GST_STATIC_PAD_TEMPLATE ("wvcsrc", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("audio/x-wavpack-correction, " "framed = (boolean) true") - ); - -static gboolean gst_wavpack_parse_sink_activate (GstPad * sinkpad); -static gboolean -gst_wavpack_parse_sink_activate_pull (GstPad * sinkpad, gboolean active); - -static void gst_wavpack_parse_loop (GstElement * element); -static GstStateChangeReturn gst_wavpack_parse_change_state (GstElement * - element, GstStateChange transition); -static void gst_wavpack_parse_reset (GstWavpackParse * parse); -static gint64 gst_wavpack_parse_get_upstream_length (GstWavpackParse * wvparse); -static GstBuffer *gst_wavpack_parse_pull_buffer (GstWavpackParse * wvparse, - gint64 offset, guint size, GstFlowReturn * flow); -static GstFlowReturn gst_wavpack_parse_chain (GstPad * pad, GstBuffer * buf); - -GST_BOILERPLATE (GstWavpackParse, gst_wavpack_parse, GstElement, - GST_TYPE_ELEMENT); - -static void -gst_wavpack_parse_base_init (gpointer klass) -{ - static const GstElementDetails plugin_details = - GST_ELEMENT_DETAILS ("Wavpack parser", - "Codec/Demuxer/Audio", - "Parses Wavpack files", - "Arwed v. Merkatz , " - "Sebastian Dröge "); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&wvc_src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &plugin_details); -} - -static void -gst_wavpack_parse_finalize (GObject * object) -{ - gst_wavpack_parse_reset (GST_WAVPACK_PARSE (object)); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_wavpack_parse_class_init (GstWavpackParseClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_wavpack_parse_finalize); - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_wavpack_parse_change_state); -} - -static GstWavpackParseIndexEntry * -gst_wavpack_parse_index_get_last_entry (GstWavpackParse * wvparse) -{ - gint last; - - g_assert (wvparse->entries != NULL); - g_assert (wvparse->entries->len > 0); - - last = wvparse->entries->len - 1; - return &g_array_index (wvparse->entries, GstWavpackParseIndexEntry, last); -} - -static GstWavpackParseIndexEntry * -gst_wavpack_parse_index_get_entry_from_sample (GstWavpackParse * wvparse, - gint64 sample_offset) -{ - gint i; - - if (wvparse->entries == NULL || wvparse->entries->len == 0) - return NULL; - - for (i = wvparse->entries->len - 1; i >= 0; --i) { - GstWavpackParseIndexEntry *entry; - - entry = &g_array_index (wvparse->entries, GstWavpackParseIndexEntry, i); - - GST_LOG_OBJECT (wvparse, "Index entry %03u: sample %" G_GINT64_FORMAT " @" - " byte %" G_GINT64_FORMAT, i, entry->sample_offset, entry->byte_offset); - - if (entry->sample_offset <= sample_offset && - sample_offset < entry->sample_offset_end) { - GST_LOG_OBJECT (wvparse, "found match"); - return entry; - } - - /* as the list is sorted and we first look at the latest entry - * we can abort searching for an entry if the sample we want is - * after the latest one */ - if (sample_offset >= entry->sample_offset_end) - break; - } - GST_LOG_OBJECT (wvparse, "no match in index"); - return NULL; -} - -static void -gst_wavpack_parse_index_append_entry (GstWavpackParse * wvparse, - gint64 byte_offset, gint64 sample_offset, gint64 num_samples) -{ - GstWavpackParseIndexEntry entry; - - if (wvparse->entries == NULL) { - wvparse->entries = g_array_new (FALSE, TRUE, - sizeof (GstWavpackParseIndexEntry)); - } else { - /* do we have this one already? */ - entry = *gst_wavpack_parse_index_get_last_entry (wvparse); - if (entry.byte_offset >= byte_offset) - return; - } - - GST_LOG_OBJECT (wvparse, "Adding index entry %8" G_GINT64_FORMAT " - %" - GST_TIME_FORMAT " @ offset 0x%08" G_GINT64_MODIFIER "x", sample_offset, - GST_TIME_ARGS (gst_util_uint64_scale_int (sample_offset, - GST_SECOND, wvparse->samplerate)), byte_offset); - - entry.byte_offset = byte_offset; - entry.sample_offset = sample_offset; - entry.sample_offset_end = sample_offset + num_samples; - g_array_append_val (wvparse->entries, entry); -} - -static void -gst_wavpack_parse_reset (GstWavpackParse * parse) -{ - parse->total_samples = -1; - parse->samplerate = 0; - parse->channels = 0; - - gst_segment_init (&parse->segment, GST_FORMAT_UNDEFINED); - - parse->current_offset = 0; - parse->need_newsegment = TRUE; - parse->discont = TRUE; - parse->upstream_length = -1; - - if (parse->entries) { - g_array_free (parse->entries, TRUE); - parse->entries = NULL; - } - - if (parse->adapter) { - gst_adapter_clear (parse->adapter); - g_object_unref (parse->adapter); - parse->adapter = NULL; - } - - if (parse->srcpad != NULL) { - gboolean res; - - GST_DEBUG_OBJECT (parse, "Removing src pad"); - res = gst_element_remove_pad (GST_ELEMENT (parse), parse->srcpad); - g_return_if_fail (res != FALSE); - gst_object_unref (parse->srcpad); - parse->srcpad = NULL; - } - - g_list_foreach (parse->queued_events, (GFunc) gst_mini_object_unref, NULL); - g_list_free (parse->queued_events); - parse->queued_events = NULL; -} - -static const GstQueryType * -gst_wavpack_parse_get_src_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_SEEKING, - 0 - }; - - return types; -} - -static gboolean -gst_wavpack_parse_src_query (GstPad * pad, GstQuery * query) -{ - GstWavpackParse *parse = GST_WAVPACK_PARSE (gst_pad_get_parent (pad)); - GstFormat format; - gboolean ret = FALSE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_POSITION:{ - gint64 cur, len; - guint rate; - - GST_OBJECT_LOCK (parse); - cur = parse->segment.last_stop; - len = parse->total_samples; - rate = parse->samplerate; - GST_OBJECT_UNLOCK (parse); - - if (len < 0 || rate == 0) { - GST_DEBUG_OBJECT (parse, "haven't read header yet"); - break; - } - - gst_query_parse_position (query, &format, NULL); - - switch (format) { - case GST_FORMAT_TIME: - cur = gst_util_uint64_scale_int (cur, GST_SECOND, rate); - gst_query_set_position (query, GST_FORMAT_TIME, cur); - ret = TRUE; - break; - case GST_FORMAT_DEFAULT: - gst_query_set_position (query, GST_FORMAT_DEFAULT, cur); - ret = TRUE; - break; - default: - GST_DEBUG_OBJECT (parse, "cannot handle position query in " - "%s format. Forwarding upstream.", gst_format_get_name (format)); - ret = gst_pad_query_default (pad, query); - break; - } - break; - } - case GST_QUERY_DURATION:{ - gint64 len; - guint rate; - - GST_OBJECT_LOCK (parse); - rate = parse->samplerate; - /* FIXME: return 0 if we work in push based mode to let totem - * recognize that we can't seek */ - len = (parse->adapter) ? 0 : parse->total_samples; - GST_OBJECT_UNLOCK (parse); - - if (len < 0 || rate == 0) { - GST_DEBUG_OBJECT (parse, "haven't read header yet"); - break; - } - - gst_query_parse_duration (query, &format, NULL); - - switch (format) { - case GST_FORMAT_TIME: - len = gst_util_uint64_scale_int (len, GST_SECOND, rate); - gst_query_set_duration (query, GST_FORMAT_TIME, len); - ret = TRUE; - break; - case GST_FORMAT_DEFAULT: - gst_query_set_duration (query, GST_FORMAT_DEFAULT, len); - ret = TRUE; - break; - default: - GST_DEBUG_OBJECT (parse, "cannot handle duration query in " - "%s format. Forwarding upstream.", gst_format_get_name (format)); - ret = gst_pad_query_default (pad, query); - break; - } - break; - } - case GST_QUERY_SEEKING:{ - gst_query_parse_seeking (query, &format, NULL, NULL, NULL); - if (format == GST_FORMAT_TIME || format == GST_FORMAT_DEFAULT) { - gboolean seekable; - gint64 duration = -1; - - /* only fails if we didn't read the headers yet and can't say - * anything about our seeking capabilities */ - if (!gst_pad_query_duration (pad, &format, &duration)) - break; - - /* can't seek in streaming mode yet */ - GST_OBJECT_LOCK (parse); - seekable = (parse->adapter == NULL); - GST_OBJECT_UNLOCK (parse); - - gst_query_set_seeking (query, format, seekable, 0, duration); - ret = TRUE; - } - break; - } - default:{ - ret = gst_pad_query_default (pad, query); - break; - } - } - - gst_object_unref (parse); - return ret; - -} - -/* returns TRUE on success, with byte_offset set to the offset of the - * wavpack chunk containing the sample requested. start_sample will be - * set to the first sample in the chunk starting at byte_offset. - * Scanning from the last known header offset to the wanted position - * when seeking forward isn't very clever, but seems fast enough in - * practice and has the nice side effect of populating our index - * table */ -static gboolean -gst_wavpack_parse_scan_to_find_sample (GstWavpackParse * parse, - gint64 sample, gint64 * byte_offset, gint64 * start_sample) -{ - GstWavpackParseIndexEntry *entry; - GstFlowReturn ret; - gint64 off = 0; - - /* first, check if we have to scan at all */ - entry = gst_wavpack_parse_index_get_entry_from_sample (parse, sample); - if (entry) { - *byte_offset = entry->byte_offset; - *start_sample = entry->sample_offset; - GST_LOG_OBJECT (parse, "Found index entry: sample %" G_GINT64_FORMAT - " @ offset %" G_GINT64_FORMAT, entry->sample_offset, - entry->byte_offset); - return TRUE; - } - - GST_LOG_OBJECT (parse, "No matching entry in index, scanning file ..."); - - /* if we have an index, we can start scanning from the last known offset - * in there, after all we know our wanted sample is not in the index */ - if (parse->entries && parse->entries->len > 0) { - GstWavpackParseIndexEntry *entry; - - entry = gst_wavpack_parse_index_get_last_entry (parse); - off = entry->byte_offset; - } - - /* now scan forward until we find the chunk we're looking for or hit EOS */ - do { - WavpackHeader header; - GstBuffer *buf; - - buf = gst_wavpack_parse_pull_buffer (parse, off, sizeof (WavpackHeader), - &ret); - - if (buf == NULL) - break; - - gst_wavpack_read_header (&header, GST_BUFFER_DATA (buf)); - gst_buffer_unref (buf); - - gst_wavpack_parse_index_append_entry (parse, off, header.block_index, - header.block_samples); - - if (header.block_index <= sample && - sample < (header.block_index + header.block_samples)) { - *byte_offset = off; - *start_sample = header.block_index; - return TRUE; - } - - off += header.ckSize + 8; - } while (1); - - GST_DEBUG_OBJECT (parse, "scan failed: %s (off=0x%08" G_GINT64_MODIFIER "x)", - gst_flow_get_name (ret), off); - - return FALSE; -} - -static gboolean -gst_wavpack_parse_send_newsegment (GstWavpackParse * wvparse, gboolean update) -{ - GstSegment *s = &wvparse->segment; - gboolean ret; - gint64 stop_time = -1; - gint64 start_time = 0; - gint64 cur_pos_time; - gint64 diff; - - /* segment is in DEFAULT format, but we want to send a TIME newsegment */ - start_time = gst_util_uint64_scale_int (s->start, GST_SECOND, - wvparse->samplerate); - - if (s->stop != -1) { - stop_time = gst_util_uint64_scale_int (s->stop, GST_SECOND, - wvparse->samplerate); - } - - GST_DEBUG_OBJECT (wvparse, "sending newsegment from %" GST_TIME_FORMAT - " to %" GST_TIME_FORMAT, GST_TIME_ARGS (start_time), - GST_TIME_ARGS (stop_time)); - - /* after a seek, s->last_stop will point to a chunk boundary, ie. from - * which sample we will start sending data again, while s->start will - * point to the sample we actually want to seek to and want to start - * playing right after the seek. Adjust clock-time for the difference - * so we start playing from start_time */ - cur_pos_time = gst_util_uint64_scale_int (s->last_stop, GST_SECOND, - wvparse->samplerate); - diff = start_time - cur_pos_time; - - ret = gst_pad_push_event (wvparse->srcpad, - gst_event_new_new_segment (update, s->rate, GST_FORMAT_TIME, - start_time, stop_time, start_time - diff)); - - return ret; -} - -static gboolean -gst_wavpack_parse_handle_seek_event (GstWavpackParse * wvparse, - GstEvent * event) -{ - GstSeekFlags seek_flags; - GstSeekType start_type; - GstSeekType stop_type; - GstSegment segment; - GstFormat format; - gboolean only_update; - gboolean flush, ret; - gdouble speed; - gint64 stop; - gint64 start; /* sample we want to seek to */ - gint64 byte_offset; /* byte offset the chunk we seek to starts at */ - gint64 chunk_start; /* first sample in chunk we seek to */ - guint rate; - gint64 last_stop; - - if (wvparse->adapter) { - GST_DEBUG_OBJECT (wvparse, "seeking in streaming mode not implemented yet"); - return FALSE; - } - - gst_event_parse_seek (event, &speed, &format, &seek_flags, &start_type, - &start, &stop_type, &stop); - - if (format != GST_FORMAT_DEFAULT && format != GST_FORMAT_TIME) { - GST_DEBUG ("seeking is only supported in TIME or DEFAULT format"); - return FALSE; - } - - if (speed < 0.0) { - GST_DEBUG ("only forward playback supported, rate %f not allowed", speed); - return FALSE; - } - - GST_OBJECT_LOCK (wvparse); - - rate = wvparse->samplerate; - if (rate == 0) { - GST_OBJECT_UNLOCK (wvparse); - GST_DEBUG ("haven't read header yet"); - return FALSE; - } - - /* figure out the last position we need to play. If it's configured (stop != - * -1), use that, else we play until the total duration of the file */ - if (stop == -1) - stop = wvparse->segment.duration; - - /* convert from time to samples if necessary */ - if (format == GST_FORMAT_TIME) { - if (start_type != GST_SEEK_TYPE_NONE) - start = gst_util_uint64_scale_int (start, rate, GST_SECOND); - if (stop_type != GST_SEEK_TYPE_NONE) - stop = gst_util_uint64_scale_int (stop, rate, GST_SECOND); - } - - if (start < 0) { - GST_OBJECT_UNLOCK (wvparse); - GST_DEBUG_OBJECT (wvparse, "Invalid start sample %" G_GINT64_FORMAT, start); - return FALSE; - } - - flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) != 0); - - /* operate on segment copy until we know the seek worked */ - segment = wvparse->segment; - - gst_segment_set_seek (&segment, speed, GST_FORMAT_DEFAULT, - seek_flags, start_type, start, stop_type, stop, &only_update); - -#if 0 - if (only_update) { - wvparse->segment = segment; - gst_wavpack_parse_send_newsegment (wvparse, TRUE); - goto done; - } -#endif - - gst_pad_push_event (wvparse->sinkpad, gst_event_new_flush_start ()); - - if (flush) { - gst_pad_push_event (wvparse->srcpad, gst_event_new_flush_start ()); - } else { - gst_pad_pause_task (wvparse->sinkpad); - } - - GST_PAD_STREAM_LOCK (wvparse->sinkpad); - - /* Save current position */ - last_stop = wvparse->segment.last_stop; - - gst_pad_push_event (wvparse->sinkpad, gst_event_new_flush_stop ()); - - if (flush) { - gst_pad_push_event (wvparse->srcpad, gst_event_new_flush_stop ()); - } - - GST_DEBUG_OBJECT (wvparse, "Performing seek to %" GST_TIME_FORMAT " sample %" - G_GINT64_FORMAT, GST_TIME_ARGS (segment.start * GST_SECOND / rate), - start); - - ret = gst_wavpack_parse_scan_to_find_sample (wvparse, segment.start, - &byte_offset, &chunk_start); - - if (ret) { - GST_DEBUG_OBJECT (wvparse, "new offset: %" G_GINT64_FORMAT, byte_offset); - wvparse->current_offset = byte_offset; - /* we want to send a newsegment event with the actual seek position - * as start, even though our first buffer might start before the - * configured segment. We leave it up to the decoder or sink to crop - * the output buffers accordingly */ - wvparse->segment = segment; - wvparse->segment.last_stop = chunk_start; - wvparse->need_newsegment = TRUE; - wvparse->discont = (last_stop != chunk_start) ? TRUE : FALSE; - - /* if we're doing a segment seek, post a SEGMENT_START message */ - if (wvparse->segment.flags & GST_SEEK_FLAG_SEGMENT) { - gst_element_post_message (GST_ELEMENT_CAST (wvparse), - gst_message_new_segment_start (GST_OBJECT_CAST (wvparse), - wvparse->segment.format, wvparse->segment.last_stop)); - } - } else { - GST_DEBUG_OBJECT (wvparse, "seek failed: don't know where to seek to"); - } - - GST_PAD_STREAM_UNLOCK (wvparse->sinkpad); - GST_OBJECT_UNLOCK (wvparse); - - gst_pad_start_task (wvparse->sinkpad, - (GstTaskFunction) gst_wavpack_parse_loop, wvparse); - - return ret; -} - -static gboolean -gst_wavpack_parse_sink_event (GstPad * pad, GstEvent * event) -{ - GstWavpackParse *parse; - gboolean ret = TRUE; - - parse = GST_WAVPACK_PARSE (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP:{ - if (parse->adapter) { - gst_adapter_clear (parse->adapter); - } - ret = gst_pad_push_event (parse->srcpad, event); - break; - } - case GST_EVENT_NEWSEGMENT:{ - parse->need_newsegment = TRUE; - gst_event_unref (event); - ret = TRUE; - break; - } - case GST_EVENT_EOS:{ - if (parse->adapter) { - /* remove all bytes that are left in the adapter after EOS. They can't - * be a complete Wavpack block and we can't do anything with them */ - gst_adapter_clear (parse->adapter); - } - ret = gst_pad_push_event (parse->srcpad, event); - break; - } - default:{ - /* stream lock is recursive, should be fine for all events */ - GST_PAD_STREAM_LOCK (pad); - if (parse->srcpad == NULL) { - parse->queued_events = g_list_append (parse->queued_events, event); - } else { - ret = gst_pad_push_event (parse->srcpad, event); - } - GST_PAD_STREAM_UNLOCK (pad); - } - } - - - gst_object_unref (parse); - return ret; -} - -static gboolean -gst_wavpack_parse_src_event (GstPad * pad, GstEvent * event) -{ - GstWavpackParse *parse; - gboolean ret; - - parse = GST_WAVPACK_PARSE (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - ret = gst_wavpack_parse_handle_seek_event (parse, event); - break; - default: - ret = gst_pad_event_default (pad, event); - break; - } - - gst_object_unref (parse); - return ret; -} - -static void -gst_wavpack_parse_init (GstWavpackParse * parse, GstWavpackParseClass * gclass) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (parse); - GstPadTemplate *tmpl; - - tmpl = gst_element_class_get_pad_template (klass, "sink"); - parse->sinkpad = gst_pad_new_from_template (tmpl, "sink"); - - gst_pad_set_activate_function (parse->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_sink_activate)); - gst_pad_set_activatepull_function (parse->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_sink_activate_pull)); - gst_pad_set_event_function (parse->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_sink_event)); - gst_pad_set_chain_function (parse->sinkpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_chain)); - - gst_element_add_pad (GST_ELEMENT (parse), parse->sinkpad); - - parse->srcpad = NULL; - gst_wavpack_parse_reset (parse); -} - -static gint64 -gst_wavpack_parse_get_upstream_length (GstWavpackParse * parse) -{ - gint64 length = -1; - - GstFormat format = GST_FORMAT_BYTES; - - if (!gst_pad_query_peer_duration (parse->sinkpad, &format, &length)) { - length = -1; - } else { - GST_DEBUG ("upstream length: %" G_GINT64_FORMAT, length); - } - return length; -} - -static GstBuffer * -gst_wavpack_parse_pull_buffer (GstWavpackParse * wvparse, gint64 offset, - guint size, GstFlowReturn * flow) -{ - GstFlowReturn flow_ret; - GstBuffer *buf = NULL; - - if (offset + size >= wvparse->upstream_length) { - wvparse->upstream_length = gst_wavpack_parse_get_upstream_length (wvparse); - if (offset + size >= wvparse->upstream_length) { - GST_DEBUG_OBJECT (wvparse, "EOS: %" G_GINT64_FORMAT " + %u > %" - G_GINT64_FORMAT, offset, size, wvparse->upstream_length); - flow_ret = GST_FLOW_UNEXPECTED; - goto done; - } - } - - flow_ret = gst_pad_pull_range (wvparse->sinkpad, offset, size, &buf); - - if (flow_ret != GST_FLOW_OK) { - GST_DEBUG_OBJECT (wvparse, "pull_range (%" G_GINT64_FORMAT ", %u) " - "failed, flow: %s", offset, size, gst_flow_get_name (flow_ret)); - buf = NULL; - goto done; - } - - if (GST_BUFFER_SIZE (buf) < size) { - GST_DEBUG_OBJECT (wvparse, "Short read at offset %" G_GINT64_FORMAT - ", got only %u of %u bytes", offset, GST_BUFFER_SIZE (buf), size); - gst_buffer_unref (buf); - buf = NULL; - flow_ret = GST_FLOW_UNEXPECTED; - } - -done: - if (flow) - *flow = flow_ret; - return buf; -} - -static gboolean -gst_wavpack_parse_create_src_pad (GstWavpackParse * wvparse, GstBuffer * buf, - WavpackHeader * header) -{ - GstWavpackMetadata meta; - GstCaps *caps = NULL; - guchar *bufptr; - - g_assert (wvparse->srcpad == NULL); - - bufptr = GST_BUFFER_DATA (buf) + sizeof (WavpackHeader); - - while (gst_wavpack_read_metadata (&meta, GST_BUFFER_DATA (buf), &bufptr)) { - switch (meta.id) { - case ID_WVC_BITSTREAM:{ - caps = gst_caps_new_simple ("audio/x-wavpack-correction", - "framed", G_TYPE_BOOLEAN, TRUE, NULL); - wvparse->srcpad = - gst_pad_new_from_template (gst_element_class_get_pad_template - (GST_ELEMENT_GET_CLASS (wvparse), "wvcsrc"), "wvcsrc"); - break; - } - case ID_WV_BITSTREAM: - case ID_WVX_BITSTREAM:{ - WavpackStreamReader *stream_reader = gst_wavpack_stream_reader_new (); - WavpackContext *wpc; - gchar error_msg[80]; - read_id rid; - - rid.buffer = GST_BUFFER_DATA (buf); - rid.length = GST_BUFFER_SIZE (buf); - rid.position = 0; - - wpc = - WavpackOpenFileInputEx (stream_reader, &rid, NULL, error_msg, 0, 0); - - if (!wpc) - return FALSE; - - wvparse->samplerate = WavpackGetSampleRate (wpc); - wvparse->channels = WavpackGetNumChannels (wpc); - wvparse->total_samples = header->total_samples; - if (wvparse->total_samples == (int32_t) - 1) - wvparse->total_samples = 0; - - caps = gst_caps_new_simple ("audio/x-wavpack", - "width", G_TYPE_INT, WavpackGetBitsPerSample (wpc), - "channels", G_TYPE_INT, wvparse->channels, - "rate", G_TYPE_INT, wvparse->samplerate, - "framed", G_TYPE_BOOLEAN, TRUE, NULL); - wvparse->srcpad = - gst_pad_new_from_template (gst_element_class_get_pad_template - (GST_ELEMENT_GET_CLASS (wvparse), "src"), "src"); - WavpackCloseFile (wpc); - g_free (stream_reader); - break; - } - default:{ - GST_LOG_OBJECT (wvparse, "unhandled ID: 0x%02x", meta.id); - break; - } - } - if (caps != NULL) - break; - } - - if (caps == NULL || wvparse->srcpad == NULL) - return FALSE; - - GST_DEBUG_OBJECT (wvparse, "Added src pad with caps %" GST_PTR_FORMAT, caps); - - gst_pad_set_query_function (wvparse->srcpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_src_query)); - gst_pad_set_query_type_function (wvparse->srcpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_get_src_query_types)); - gst_pad_set_event_function (wvparse->srcpad, - GST_DEBUG_FUNCPTR (gst_wavpack_parse_src_event)); - - gst_pad_set_caps (wvparse->srcpad, caps); - gst_caps_unref (caps); - gst_pad_use_fixed_caps (wvparse->srcpad); - - gst_object_ref (wvparse->srcpad); - gst_pad_set_active (wvparse->srcpad, TRUE); - gst_element_add_pad (GST_ELEMENT (wvparse), wvparse->srcpad); - gst_element_no_more_pads (GST_ELEMENT (wvparse)); - - return TRUE; -} - -static GstFlowReturn -gst_wavpack_parse_push_buffer (GstWavpackParse * wvparse, GstBuffer * buf, - WavpackHeader * header) -{ - wvparse->current_offset += header->ckSize + 8; - - wvparse->segment.last_stop = header->block_index; - - if (wvparse->need_newsegment) { - if (gst_wavpack_parse_send_newsegment (wvparse, FALSE)) - wvparse->need_newsegment = FALSE; - } - - /* send any queued events */ - if (wvparse->queued_events) { - GList *l; - - for (l = wvparse->queued_events; l != NULL; l = l->next) { - gst_pad_push_event (wvparse->srcpad, GST_EVENT (l->data)); - } - g_list_free (wvparse->queued_events); - wvparse->queued_events = NULL; - } - - GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (header->block_index, - GST_SECOND, wvparse->samplerate); - GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (header->block_samples, - GST_SECOND, wvparse->samplerate); - GST_BUFFER_OFFSET (buf) = header->block_index; - GST_BUFFER_OFFSET_END (buf) = header->block_index + header->block_samples; - - if (wvparse->discont) { - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - wvparse->discont = FALSE; - } - - gst_buffer_set_caps (buf, GST_PAD_CAPS (wvparse->srcpad)); - - GST_LOG_OBJECT (wvparse, "Pushing buffer with time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); - - return gst_pad_push (wvparse->srcpad, buf); -} - -static guint8 * -gst_wavpack_parse_find_marker (guint8 * buf, guint size) -{ - int i; - guint8 *ret = NULL; - - if (G_UNLIKELY (size < 4)) - return NULL; - - for (i = 0; i < size - 4; i++) { - if (memcmp (buf + i, "wvpk", 4) == 0) { - ret = buf + i; - break; - } - } - return ret; -} - -static GstFlowReturn -gst_wavpack_parse_resync_loop (GstWavpackParse * parse, WavpackHeader * header) -{ - GstFlowReturn flow_ret = GST_FLOW_UNEXPECTED; - GstBuffer *buf = NULL; - - /* loop until we have a frame header or reach the end of the stream */ - while (1) { - guint8 *data, *marker; - guint len, size; - - if (buf) { - gst_buffer_unref (buf); - buf = NULL; - } - - if (parse->upstream_length == 0 || - parse->upstream_length <= parse->current_offset) { - parse->upstream_length = gst_wavpack_parse_get_upstream_length (parse); - if (parse->upstream_length == 0 || - parse->upstream_length <= parse->current_offset) { - break; - } - } - - len = MIN (parse->upstream_length - parse->current_offset, 2048); - - GST_LOG_OBJECT (parse, "offset: %" G_GINT64_FORMAT, parse->current_offset); - - buf = gst_wavpack_parse_pull_buffer (parse, parse->current_offset, - len, &flow_ret); - - /* whatever the problem is, there's nothing more for us to do for now */ - if (flow_ret != GST_FLOW_OK) - break; - - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); - - /* not enough data for a header? */ - if (size < sizeof (WavpackHeader)) - break; - - /* got a header right where we are at now? */ - if (gst_wavpack_read_header (header, data)) - break; - - /* nope, let's see if we can find one */ - marker = gst_wavpack_parse_find_marker (data + 1, size - 1); - - if (marker) { - parse->current_offset += marker - data; - /* do one more loop iteration to make sure we pull enough - * data for a full header, we'll bail out then */ - } else { - parse->current_offset += len - 4; - } - } - - if (buf) - gst_buffer_unref (buf); - - return flow_ret; -} - -static void -gst_wavpack_parse_loop (GstElement * element) -{ - GstWavpackParse *parse = GST_WAVPACK_PARSE (element); - GstFlowReturn flow_ret; - WavpackHeader header = { {0,}, 0, }; - GstBuffer *buf = NULL; - - flow_ret = gst_wavpack_parse_resync_loop (parse, &header); - - if (flow_ret != GST_FLOW_OK) - goto pause; - - GST_LOG_OBJECT (parse, "Read header at offset %" G_GINT64_FORMAT - ": chunk size = %u+8", parse->current_offset, header.ckSize); - - buf = gst_wavpack_parse_pull_buffer (parse, parse->current_offset, - header.ckSize + 8, &flow_ret); - - if (flow_ret != GST_FLOW_OK) - goto pause; - - if (parse->srcpad == NULL) { - if (!gst_wavpack_parse_create_src_pad (parse, buf, &header)) { - GST_ERROR_OBJECT (parse, "Failed to create src pad"); - flow_ret = GST_FLOW_ERROR; - goto pause; - } - } - - gst_wavpack_parse_index_append_entry (parse, parse->current_offset, - header.block_index, header.block_samples); - - flow_ret = gst_wavpack_parse_push_buffer (parse, buf, &header); - if (flow_ret != GST_FLOW_OK) - goto pause; - - return; - -pause: - { - const gchar *reason = gst_flow_get_name (flow_ret); - - GST_LOG_OBJECT (parse, "pausing task, reason %s", reason); - gst_pad_pause_task (parse->sinkpad); - - if (GST_FLOW_IS_FATAL (flow_ret) || flow_ret == GST_FLOW_NOT_LINKED) { - if (flow_ret == GST_FLOW_UNEXPECTED && parse->srcpad) { - if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) { - GstClockTime stop; - - GST_LOG_OBJECT (parse, "Sending segment done"); - - if ((stop = parse->segment.stop) == -1) - stop = parse->segment.duration; - - gst_element_post_message (GST_ELEMENT_CAST (parse), - gst_message_new_segment_done (GST_OBJECT_CAST (parse), - parse->segment.format, stop)); - } else { - GST_LOG_OBJECT (parse, "Sending EOS, at end of stream"); - gst_pad_push_event (parse->srcpad, gst_event_new_eos ()); - } - } else { - GST_ELEMENT_ERROR (parse, STREAM, FAILED, - (_("Internal data stream error.")), - ("stream stopped, reason %s", reason)); - if (parse->srcpad) - gst_pad_push_event (parse->srcpad, gst_event_new_eos ()); - } - } - return; - } -} - -static gboolean -gst_wavpack_parse_resync_adapter (GstAdapter * adapter) -{ - const guint8 *buf, *marker; - guint avail = gst_adapter_available (adapter); - - if (avail < 4) - return FALSE; - - /* if the marker is at the beginning don't do the expensive search */ - buf = gst_adapter_peek (adapter, 4); - if (memcmp (buf, "wvpk", 4) == 0) - return TRUE; - - if (avail == 4) - return FALSE; - - /* search for the marker in the complete content of the adapter */ - buf = gst_adapter_peek (adapter, avail); - if (buf && (marker = gst_wavpack_parse_find_marker ((guint8 *) buf, avail))) { - gst_adapter_flush (adapter, marker - buf); - return TRUE; - } - - /* flush everything except the last 4 bytes. they could contain - * the start of a new marker */ - gst_adapter_flush (adapter, avail - 4); - - return FALSE; -} - -static GstFlowReturn -gst_wavpack_parse_chain (GstPad * pad, GstBuffer * buf) -{ - GstWavpackParse *wvparse = GST_WAVPACK_PARSE (GST_PAD_PARENT (pad)); - GstFlowReturn ret = GST_FLOW_OK; - WavpackHeader wph; - const guint8 *tmp_buf; - - if (!wvparse->adapter) { - wvparse->adapter = gst_adapter_new (); - } - - if (GST_BUFFER_IS_DISCONT (buf)) { - gst_adapter_clear (wvparse->adapter); - wvparse->discont = TRUE; - } - - gst_adapter_push (wvparse->adapter, buf); - - if (gst_adapter_available (wvparse->adapter) < sizeof (WavpackHeader)) - return ret; - - if (!gst_wavpack_parse_resync_adapter (wvparse->adapter)) - return ret; - - tmp_buf = gst_adapter_peek (wvparse->adapter, sizeof (WavpackHeader)); - gst_wavpack_read_header (&wph, (guint8 *) tmp_buf); - - while (gst_adapter_available (wvparse->adapter) >= wph.ckSize + 4 * 1 + 4) { - GstBuffer *outbuf = - gst_adapter_take_buffer (wvparse->adapter, wph.ckSize + 4 * 1 + 4); - - if (!outbuf) - return GST_FLOW_ERROR; - - if (wvparse->srcpad == NULL) { - if (!gst_wavpack_parse_create_src_pad (wvparse, outbuf, &wph)) { - GST_ERROR_OBJECT (wvparse, "Failed to create src pad"); - ret = GST_FLOW_ERROR; - break; - } - } - - ret = gst_wavpack_parse_push_buffer (wvparse, outbuf, &wph); - - if (ret != GST_FLOW_OK) - break; - - if (gst_adapter_available (wvparse->adapter) >= sizeof (WavpackHeader)) { - tmp_buf = gst_adapter_peek (wvparse->adapter, sizeof (WavpackHeader)); - - if (!gst_wavpack_parse_resync_adapter (wvparse->adapter)) - break; - - gst_wavpack_read_header (&wph, (guint8 *) tmp_buf); - } - } - - return ret; -} - -static GstStateChangeReturn -gst_wavpack_parse_change_state (GstElement * element, GstStateChange transition) -{ - GstWavpackParse *wvparse = GST_WAVPACK_PARSE (element); - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_segment_init (&wvparse->segment, GST_FORMAT_DEFAULT); - wvparse->segment.last_stop = 0; - default: - break; - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_wavpack_parse_reset (wvparse); - break; - default: - break; - } - - return ret; -} - -static gboolean -gst_wavpack_parse_sink_activate (GstPad * sinkpad) -{ - if (gst_pad_check_pull_range (sinkpad)) { - return gst_pad_activate_pull (sinkpad, TRUE); - } else { - return gst_pad_activate_push (sinkpad, TRUE); - } -} - -static gboolean -gst_wavpack_parse_sink_activate_pull (GstPad * sinkpad, gboolean active) -{ - gboolean result; - - if (active) { - result = gst_pad_start_task (sinkpad, - (GstTaskFunction) gst_wavpack_parse_loop, GST_PAD_PARENT (sinkpad)); - } else { - result = gst_pad_stop_task (sinkpad); - } - - return result; -} - -gboolean -gst_wavpack_parse_plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "wavpackparse", - GST_RANK_PRIMARY, GST_TYPE_WAVPACK_PARSE)) { - return FALSE; - } - - GST_DEBUG_CATEGORY_INIT (gst_wavpack_parse_debug, "wavpack_parse", 0, - "Wavpack file parser"); - - return TRUE; -} diff --git a/ext/wavpack/gstwavpackparse.h b/ext/wavpack/gstwavpackparse.h deleted file mode 100644 index c1d6feea54..0000000000 --- a/ext/wavpack/gstwavpackparse.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GStreamer wavpack plugin - * (c) 2005 Arwed v. Merkatz - * - * gstwavpackparse.h: wavpack file parser - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_WAVPACK_PARSE_H__ -#define __GST_WAVPACK_PARSE_H__ - -#include -#include - -G_BEGIN_DECLS -#define GST_TYPE_WAVPACK_PARSE \ - (gst_wavpack_parse_get_type()) -#define GST_WAVPACK_PARSE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAVPACK_PARSE,GstWavpackParse)) -#define GST_WAVPACK_PARSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAVPACK_PARSE,GstWavpackParseClass)) -#define GST_IS_WAVPACK_PARSE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAVPACK_PARSE)) -#define GST_IS_WAVPACK_PARSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAVPACK_PARSE)) -typedef struct _GstWavpackParse GstWavpackParse; -typedef struct _GstWavpackParseClass GstWavpackParseClass; -typedef struct _GstWavpackParseIndexEntry GstWavpackParseIndexEntry; - -struct _GstWavpackParseIndexEntry -{ - gint64 byte_offset; /* byte offset of this chunk */ - gint64 sample_offset; /* first sample in this chunk */ - gint64 sample_offset_end; /* first sample in next chunk */ -}; - -struct _GstWavpackParse -{ - GstElement element; - - /*< private > */ - GstPad *sinkpad; - GstPad *srcpad; - - guint samplerate; - guint channels; - guint total_samples; - - gboolean need_newsegment; - gboolean discont; - - gint64 current_offset; /* byte offset on sink pad */ - gint64 upstream_length; /* length of file in bytes */ - - GstSegment segment; /* the currently configured segment, in - * samples/audio frames (DEFAULT format) */ - - GstAdapter *adapter; /* when operating chain-based, otherwise NULL */ - - /* Array of GstWavpackParseIndexEntry structs, mapping known - * sample offsets to byte offsets. Is kept increasing without - * gaps (ie. append only and consecutive entries must always - * map to consecutive chunks in the file). */ - GArray *entries; - - /* Queued events (e.g. tag events we receive before we create the src pad) */ - GList *queued_events; /* STREAM_LOCK */ -}; - -struct _GstWavpackParseClass -{ - GstElementClass parent; -}; - -GType gst_wavpack_parse_get_type (void); - -gboolean gst_wavpack_parse_plugin_init (GstPlugin * plugin); - -G_END_DECLS -#endif /* __GST_WAVPACK_PARSE_H__ */ diff --git a/ext/wavpack/gstwavpackstreamreader.c b/ext/wavpack/gstwavpackstreamreader.c deleted file mode 100644 index 9b6260b86b..0000000000 --- a/ext/wavpack/gstwavpackstreamreader.c +++ /dev/null @@ -1,112 +0,0 @@ -/* GStreamer Wavpack plugin - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackstreamreader.c: stream reader used for decoding - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include -#include - -#include "gstwavpackstreamreader.h" - -GST_DEBUG_CATEGORY_EXTERN (wavpack_debug); -#define GST_CAT_DEFAULT wavpack_debug - -static int32_t -gst_wavpack_stream_reader_read_bytes (void *id, void *data, int32_t bcount) -{ - read_id *rid = (read_id *) id; - uint32_t left = rid->length - rid->position; - uint32_t to_read = MIN (left, bcount); - - if (to_read > 0) { - g_memmove (data, rid->buffer + rid->position, to_read); - rid->position += to_read; - return to_read; - } else { - return 0; - } -} - -static uint32_t -gst_wavpack_stream_reader_get_pos (void *id) -{ - return ((read_id *) id)->position; -} - -static int -gst_wavpack_stream_reader_set_pos_abs (void *id, uint32_t pos) -{ - GST_DEBUG ("should not be called"); - return -1; -} - -static int -gst_wavpack_stream_reader_set_pos_rel (void *id, int32_t delta, int mode) -{ - GST_DEBUG ("should not be called"); - return -1; -} - -static int -gst_wavpack_stream_reader_push_back_byte (void *id, int c) -{ - read_id *rid = (read_id *) id; - - rid->position -= 1; - if (rid->position < 0) - rid->position = 0; - return rid->position; -} - -static uint32_t -gst_wavpack_stream_reader_get_length (void *id) -{ - return ((read_id *) id)->length; -} - -static int -gst_wavpack_stream_reader_can_seek (void *id) -{ - return FALSE; -} - -static int32_t -gst_wavpack_stream_reader_write_bytes (void *id, void *data, int32_t bcount) -{ - GST_DEBUG ("should not be called"); - return 0; -} - -WavpackStreamReader * -gst_wavpack_stream_reader_new () -{ - WavpackStreamReader *stream_reader = - (WavpackStreamReader *) g_malloc0 (sizeof (WavpackStreamReader)); - stream_reader->read_bytes = gst_wavpack_stream_reader_read_bytes; - stream_reader->get_pos = gst_wavpack_stream_reader_get_pos; - stream_reader->set_pos_abs = gst_wavpack_stream_reader_set_pos_abs; - stream_reader->set_pos_rel = gst_wavpack_stream_reader_set_pos_rel; - stream_reader->push_back_byte = gst_wavpack_stream_reader_push_back_byte; - stream_reader->get_length = gst_wavpack_stream_reader_get_length; - stream_reader->can_seek = gst_wavpack_stream_reader_can_seek; - stream_reader->write_bytes = gst_wavpack_stream_reader_write_bytes; - - return stream_reader; -} diff --git a/ext/wavpack/gstwavpackstreamreader.h b/ext/wavpack/gstwavpackstreamreader.h deleted file mode 100644 index e9ffd70a4b..0000000000 --- a/ext/wavpack/gstwavpackstreamreader.h +++ /dev/null @@ -1,36 +0,0 @@ -/* GStreamer Wavpack plugin - * Copyright (c) 2006 Sebastian Dröge - * - * gstwavpackstreamreader.h: stream reader used for decoding - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_WAVPACK_STREAM_READER_H__ -#define __GST_WAVPACK_STREAM_READER_H__ - -#include - -typedef struct -{ - guint8 *buffer; - uint32_t length; - uint32_t position; -} read_id; - -WavpackStreamReader *gst_wavpack_stream_reader_new (); - -#endif diff --git a/ext/wavpack/md5.c b/ext/wavpack/md5.c deleted file mode 100644 index 1889c37792..0000000000 --- a/ext/wavpack/md5.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -/* Brutally hacked by John Walker back from ANSI C to K&R (no - prototypes) to maintain the tradition that Netfone will compile - with Sun's original "cc". */ - -#include /* for memcpy() */ -#include -#include "md5.h" - -#if G_BYTE_ORDER == G_BIG_ENDIAN -#define HIGHFIRST -#endif - -#ifndef HIGHFIRST -#define byteReverse(buf, len) /* Nothing */ -#else -/* - * Note: this code is harmless on little-endian machines. - */ -void -byteReverse (buf, longs) - unsigned char *buf; - unsigned longs; -{ - uint32 t; - - do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; - } while (--longs); -} -#endif - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void -MD5Init (ctx) - struct MD5Context *ctx; -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void -MD5Update (ctx, buf, len) - struct MD5Context *ctx; - unsigned char *buf; - unsigned len; -{ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy (p, buf, len); - return; - } - memcpy (p, buf, t); - byteReverse (ctx->in, 16); - MD5Transform (ctx->buf, (uint32 *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy (ctx->in, buf, 64); - byteReverse (ctx->in, 16); - MD5Transform (ctx->buf, (uint32 *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy (ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void -MD5Final (digest, ctx) - unsigned char digest[16]; - struct MD5Context *ctx; -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset (p, 0, count); - byteReverse (ctx->in, 16); - MD5Transform (ctx->buf, (uint32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset (ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset (p, 0, count - 8); - } - byteReverse (ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32 *) ctx->in)[14] = ctx->bits[0]; - ((uint32 *) ctx->in)[15] = ctx->bits[1]; - - MD5Transform (ctx->buf, (uint32 *) ctx->in); - byteReverse ((unsigned char *) ctx->buf, 4); - memcpy (digest, ctx->buf, 16); - memset (ctx, 0, sizeof (ctx)); /* In case it's sensitive */ -} - - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void -MD5Transform (buf, in) - uint32 buf[4]; - uint32 in[16]; -{ - register uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP (F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP (F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP (F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP (F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP (F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP (F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP (F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP (F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP (F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP (F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP (F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP (F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP (F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP (F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP (F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP (F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP (F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP (F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP (F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP (F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP (F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP (F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP (F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP (F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP (F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP (F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP (F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP (F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP (F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP (F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP (F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP (F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP (F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP (F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP (F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP (F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP (F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP (F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP (F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP (F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP (F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP (F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP (F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP (F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP (F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP (F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP (F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP (F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP (F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP (F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP (F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP (F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP (F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} diff --git a/ext/wavpack/md5.h b/ext/wavpack/md5.h deleted file mode 100644 index 6f8102213f..0000000000 --- a/ext/wavpack/md5.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef MD5_H -#define MD5_H - -#include "_stdint.h" - -#ifndef uint32 -typedef uint32_t uint32; -#endif - -struct MD5Context -{ - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -extern void MD5Init (struct MD5Context *ctx); -extern void MD5Update (struct MD5Context *ctx, unsigned char *buf, - unsigned len); -extern void MD5Final (unsigned char digest[16], struct MD5Context *ctx); -extern void MD5Transform (uint32 buf[4], uint32 in[16]); - -/* - * This is needed to make RSAREF happy on some MS-DOS compilers. - */ -typedef struct MD5Context MD5_CTX; - -#endif /* !MD5_H */ diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 998e6a1553..6db6685054 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -38,15 +38,6 @@ else check_neon = endif -if USE_WAVPACK -check_wavpack = \ - elements/wavpackparse \ - elements/wavpackdec \ - elements/wavpackenc -else -check_wavpack = -endif - VALGRIND_TO_FIX = \ elements/mpeg2enc @@ -63,7 +54,6 @@ check_PROGRAMS = \ elements/rglimiter \ elements/rgvolume \ elements/videocrop \ - $(check_wavpack) \ elements/y4menc TESTS = $(check_PROGRAMS) diff --git a/tests/check/elements/wavpackdec.c b/tests/check/elements/wavpackdec.c deleted file mode 100644 index 812944cf7c..0000000000 --- a/tests/check/elements/wavpackdec.c +++ /dev/null @@ -1,254 +0,0 @@ -/* GStreamer - * - * unit test for wavpackdec - * - * Copyright (c) 2006 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include - -#include - -/* For ease of programming we use globals to keep refs for our floating - * src and sink pads we create; otherwise we always have to do get_pad, - * get_peer, and then remove references in every test function */ -static GstPad *mysrcpad, *mysinkpad; - -guint8 test_frame[] = { - 0x77, 0x76, 0x70, 0x6B, /* "wvpk" */ - 0x2E, 0x00, 0x00, 0x00, /* ckSize */ - 0x04, 0x04, /* version */ - 0x00, /* track_no */ - 0x00, /* index_no */ - 0x00, 0x64, 0x00, 0x00, /* total_samples */ - 0x00, 0x00, 0x00, 0x00, /* block_index */ - 0x00, 0x64, 0x00, 0x00, /* block_samples */ - 0x05, 0x18, 0x80, 0x04, /* flags */ - 0xFF, 0xAF, 0x80, 0x60, /* crc */ - 0x02, 0x00, 0x03, 0x00, /* data */ - 0x04, 0x00, 0x05, 0x03, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x8A, 0x02, - 0x00, 0x00, 0xFF, 0x7F, - 0x00, 0xE4, -}; - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "width = (int) 32, " - "depth = (int) 16, " - "channels = (int) 1, " - "rate = (int) 44100, " - "endianness = (int) BYTE_ORDER, " "signed = (boolean) true") - ); -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack, " - "width = (int) 16, " - "channels = (int) 1, " "rate = (int) 44100, " "framed = (boolean) true") - ); - -GstElement * -setup_wavpackdec () -{ - GstElement *wavpackdec; - - GST_DEBUG ("setup_wavpackdec"); - wavpackdec = gst_check_setup_element ("wavpackdec"); - mysrcpad = gst_check_setup_src_pad (wavpackdec, &srctemplate, NULL); - mysinkpad = gst_check_setup_sink_pad (wavpackdec, &sinktemplate, NULL); - gst_pad_set_active (mysrcpad, TRUE); - gst_pad_set_active (mysinkpad, TRUE); - - return wavpackdec; -} - -void -cleanup_wavpackdec (GstElement * wavpackdec) -{ - GST_DEBUG ("cleanup_wavpackdec"); - gst_element_set_state (wavpackdec, GST_STATE_NULL); - - gst_pad_set_active (mysrcpad, FALSE); - gst_pad_set_active (mysinkpad, FALSE); - gst_check_teardown_src_pad (wavpackdec); - gst_check_teardown_sink_pad (wavpackdec); - gst_check_teardown_element (wavpackdec); -} - -GST_START_TEST (test_decode_frame) -{ - GstElement *wavpackdec; - GstBuffer *inbuffer, *outbuffer; - GstBus *bus; - int i; - - wavpackdec = setup_wavpackdec (); - - fail_unless (gst_element_set_state (wavpackdec, - GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, - "could not set to playing"); - bus = gst_bus_new (); - - inbuffer = gst_buffer_new_and_alloc (sizeof (test_frame)); - memcpy (GST_BUFFER_DATA (inbuffer), test_frame, sizeof (test_frame)); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_ref (inbuffer); - - gst_element_set_bus (wavpackdec, bus); - - /* should decode the buffer without problems */ - fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); - - outbuffer = GST_BUFFER (buffers->data); - - fail_if (outbuffer == NULL); - /* uncompressed data should be 102400 bytes */ - fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), 102400); - - /* and all 102400 bytes must be 0, i.e. silence */ - for (i = 0; i < 102400; i++) - fail_unless_equals_int (GST_BUFFER_DATA (outbuffer)[i], 0); - - ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); - gst_buffer_unref (outbuffer); - outbuffer = NULL; - - g_list_free (buffers); - buffers = NULL; - - gst_bus_set_flushing (bus, TRUE); - gst_element_set_bus (wavpackdec, NULL); - gst_object_unref (GST_OBJECT (bus)); - cleanup_wavpackdec (wavpackdec); -} - -GST_END_TEST; - -GST_START_TEST (test_decode_frame_with_broken_header) -{ - GstElement *wavpackdec; - GstBuffer *inbuffer, *outbuffer; - GstBus *bus; - GstMessage *message; - - wavpackdec = setup_wavpackdec (); - - fail_unless (gst_element_set_state (wavpackdec, - GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, - "could not set to playing"); - bus = gst_bus_new (); - - inbuffer = gst_buffer_new_and_alloc (sizeof (test_frame)); - memcpy (GST_BUFFER_DATA (inbuffer), test_frame, sizeof (test_frame)); - /* break header */ - GST_BUFFER_DATA (inbuffer)[2] = 'e'; - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_ref (inbuffer); - - gst_element_set_bus (wavpackdec, bus); - - /* should fail gracefully */ - fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_ERROR); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); - - fail_if ((message = gst_bus_pop (bus)) == NULL); - fail_unless_message_error (message, STREAM, DECODE); - gst_message_unref (message); - - gst_element_set_bus (wavpackdec, NULL); - gst_object_unref (GST_OBJECT (bus)); - cleanup_wavpackdec (wavpackdec); -} - -GST_END_TEST; - -GST_START_TEST (test_decode_frame_with_incomplete_frame) -{ - GstElement *wavpackdec; - GstBuffer *inbuffer, *outbuffer; - GstBus *bus; - GstMessage *message; - - wavpackdec = setup_wavpackdec (); - - fail_unless (gst_element_set_state (wavpackdec, - GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, - "could not set to playing"); - bus = gst_bus_new (); - - inbuffer = gst_buffer_new_and_alloc (sizeof (test_frame) - 2); - memcpy (GST_BUFFER_DATA (inbuffer), test_frame, sizeof (test_frame) - 2); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_ref (inbuffer); - - gst_element_set_bus (wavpackdec, bus); - - /* should fail gracefully */ - fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_ERROR); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); - - fail_if ((message = gst_bus_pop (bus)) == NULL); - fail_unless_message_error (message, STREAM, DECODE); - gst_message_unref (message); - - - gst_element_set_bus (wavpackdec, NULL); - gst_object_unref (GST_OBJECT (bus)); - cleanup_wavpackdec (wavpackdec); -} - -GST_END_TEST; - -Suite * -wavpackdec_suite (void) -{ - Suite *s = suite_create ("wavpackdec"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_decode_frame); - tcase_add_test (tc_chain, test_decode_frame_with_broken_header); - tcase_add_test (tc_chain, test_decode_frame_with_incomplete_frame); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = wavpackdec_suite (); - SRunner *sr = srunner_create (s); - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -} diff --git a/tests/check/elements/wavpackenc.c b/tests/check/elements/wavpackenc.c deleted file mode 100644 index a22d2ac8b6..0000000000 --- a/tests/check/elements/wavpackenc.c +++ /dev/null @@ -1,197 +0,0 @@ -/* GStreamer - * - * unit test for wavpackenc - * - * Copyright (c) 2006 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include - -#include - -/* For ease of programming we use globals to keep refs for our floating - * src and sink pads we create; otherwise we always have to do get_pad, - * get_peer, and then remove references in every test function */ -static GstPad *mysrcpad, *mysinkpad; -static GstBus *bus; - -#define RAW_CAPS_STRING "audio/x-raw-int, " \ - "width = (int) 32, " \ - "depth = (int) 16, " \ - "channels = (int) 1, " \ - "rate = (int) 44100, " \ - "endianness = (int) BYTE_ORDER, " \ - "signed = (boolean) true" - -#define WAVPACK_CAPS_STRING "audio/x-wavpack, " \ - "width = (int) 16, " \ - "channels = (int) 1, " \ - "rate = (int) 44100, " \ - "framed = (boolean) true" - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack, " - "width = (int) 16, " - "channels = (int) 1, " - "rate = (int) 44100, " "framed = (boolean) true")); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "width = (int) 32, " - "depth = (int) 16, " - "channels = (int) 1, " - "rate = (int) 44100, " - "endianness = (int) BYTE_ORDER, " "signed = (boolean) true")); - -GstElement * -setup_wavpackenc () -{ - GstElement *wavpackenc; - - GST_DEBUG ("setup_wavpackenc"); - wavpackenc = gst_check_setup_element ("wavpackenc"); - mysrcpad = gst_check_setup_src_pad (wavpackenc, &srctemplate, NULL); - mysinkpad = gst_check_setup_sink_pad (wavpackenc, &sinktemplate, NULL); - gst_pad_set_active (mysrcpad, TRUE); - gst_pad_set_active (mysinkpad, TRUE); - - fail_unless (gst_element_set_state (wavpackenc, - GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, - "could not set to playing"); - bus = gst_bus_new (); - - return wavpackenc; -} - -void -cleanup_wavpackenc (GstElement * wavpackenc) -{ - GST_DEBUG ("cleanup_wavpackenc"); - - gst_bus_set_flushing (bus, TRUE); - gst_element_set_bus (wavpackenc, NULL); - gst_object_unref (GST_OBJECT (bus)); - - gst_element_set_state (wavpackenc, GST_STATE_NULL); - - gst_pad_set_active (mysrcpad, FALSE); - gst_pad_set_active (mysinkpad, FALSE); - gst_check_teardown_src_pad (wavpackenc); - gst_check_teardown_sink_pad (wavpackenc); - gst_check_teardown_element (wavpackenc); -} - -GST_START_TEST (test_encode_silence) -{ - GstElement *wavpackenc; - GstBuffer *inbuffer, *outbuffer; - GstCaps *caps; - GstEvent *eos = gst_event_new_eos (); - int i, num_buffers; - - wavpackenc = setup_wavpackenc (); - - inbuffer = gst_buffer_new_and_alloc (1000); - for (i = 0; i < 1000; i++) - GST_BUFFER_DATA (inbuffer)[i] = 0; - caps = gst_caps_from_string (RAW_CAPS_STRING); - gst_buffer_set_caps (inbuffer, caps); - gst_caps_unref (caps); - GST_BUFFER_TIMESTAMP (inbuffer) = 0; - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_ref (inbuffer); - - gst_element_set_bus (wavpackenc, bus); - - fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); - - fail_if (gst_pad_push_event (mysrcpad, eos) != TRUE); - - /* check first buffer */ - outbuffer = GST_BUFFER (buffers->data); - - fail_if (outbuffer == NULL); - - fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 0); - fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 0); - fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 5668934); - fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 250); - - fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), "wvpk", 4) == 0, - "Failed to encode to valid Wavpack frames"); - - caps = gst_caps_from_string (WAVPACK_CAPS_STRING); - fail_unless (gst_caps_is_equal (caps, GST_BUFFER_CAPS (outbuffer)) == TRUE, - "Wrong caps"); - gst_caps_unref (caps); - - /* free all buffers */ - num_buffers = g_list_length (buffers); - - for (i = 0; i < num_buffers; ++i) { - outbuffer = GST_BUFFER (buffers->data); - fail_if (outbuffer == NULL); - - buffers = g_list_remove (buffers, outbuffer); - - gst_buffer_unref (outbuffer); - outbuffer = NULL; - } - - g_list_free (buffers); - buffers = NULL; - - cleanup_wavpackenc (wavpackenc); -} - -GST_END_TEST; - -Suite * -wavpackenc_suite (void) -{ - Suite *s = suite_create ("wavpackenc"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_encode_silence); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = wavpackenc_suite (); - SRunner *sr = srunner_create (s); - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -} diff --git a/tests/check/elements/wavpackparse.c b/tests/check/elements/wavpackparse.c deleted file mode 100644 index 7a3b8cc1a7..0000000000 --- a/tests/check/elements/wavpackparse.c +++ /dev/null @@ -1,295 +0,0 @@ -/* GStreamer - * - * unit test for wavpackparse - * - * Copyright (c) 2006 Sebastian Dröge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include - -#include - -/* For ease of programming we use globals to keep refs for our floating - * src and sink pads we create; otherwise we always have to do get_pad, - * get_peer, and then remove references in every test function */ -static GstPad *mysrcpad, *mysinkpad; -static GstBus *bus; -static GstElement *wavpackparse; - -/* Wavpack file with 2 frames of silence */ -guint8 test_file[] = { - 0x77, 0x76, 0x70, 0x6B, 0x62, 0x00, 0x00, 0x00, /* first frame */ - 0x04, 0x04, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, /* include RIFF header */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, - 0x05, 0x18, 0x80, 0x04, 0xFF, 0xAF, 0x80, 0x60, - 0x21, 0x16, 0x52, 0x49, 0x46, 0x46, 0x24, 0x90, - 0x01, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, - 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x88, 0x58, - 0x01, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, - 0x74, 0x61, 0x00, 0x90, 0x01, 0x00, 0x02, 0x00, - 0x03, 0x00, 0x04, 0x00, 0x05, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x65, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x8A, 0x02, 0x00, 0x00, 0xFF, 0x7F, - 0x00, 0xE4, - 0x77, 0x76, 0x70, 0x6B, 0x2E, 0x00, 0x00, 0x00, /* second frame */ - 0x04, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, - 0x05, 0x18, 0x80, 0x04, 0xFF, 0xAF, 0x80, 0x60, - 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x02, - 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xE4, -}; - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack, " - "width = (int) 16, " - "channels = (int) 1, " - "rate = (int) 44100, " "framed = (boolean) TRUE")); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-wavpack")); - -static void -wavpackparse_found_pad (GstElement * src, GstPad * pad, gpointer data) -{ - GstPad *srcpad; - - mysinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); - fail_if (mysinkpad == NULL, "Couldn't create sinkpad"); - srcpad = gst_element_get_pad (wavpackparse, "src"); - fail_if (srcpad == NULL, "Failed to get srcpad from wavpackparse"); - gst_pad_set_chain_function (mysinkpad, gst_check_chain_func); - fail_unless (gst_pad_link (srcpad, mysinkpad) == GST_PAD_LINK_OK, - "Failed to link pads"); - gst_pad_set_active (mysinkpad, TRUE); - gst_object_unref (srcpad); -} - -void -setup_wavpackparse () -{ - GstPad *sinkpad; - - GST_DEBUG ("setup_wavpackparse"); - - wavpackparse = gst_element_factory_make ("wavpackparse", "wavpackparse"); - fail_if (wavpackparse == NULL, "Could not create wavpackparse"); - - mysrcpad = gst_pad_new_from_static_template (&srctemplate, "src"); - fail_if (mysrcpad == NULL, "Could not create srcpad"); - - sinkpad = gst_element_get_pad (wavpackparse, "sink"); - fail_if (sinkpad == NULL, "Failed to get sinkpad from wavpackparse"); - fail_unless (gst_pad_link (mysrcpad, sinkpad) == GST_PAD_LINK_OK, - "Failed to link pads"); - gst_object_unref (sinkpad); - - g_signal_connect (wavpackparse, "pad-added", - G_CALLBACK (wavpackparse_found_pad), NULL); - - bus = gst_bus_new (); - gst_element_set_bus (wavpackparse, bus); - - fail_unless (gst_element_set_state (wavpackparse, - GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, - "could not set to playing"); -} - -void -cleanup_wavpackparse () -{ - GstPad *sinkpad, *srcpad; - - GST_DEBUG ("cleanup_wavpackparse"); - - gst_bus_set_flushing (bus, TRUE); - gst_element_set_bus (wavpackparse, NULL); - gst_object_unref (GST_OBJECT (bus)); - - sinkpad = gst_element_get_pad (wavpackparse, "sink"); - fail_if (sinkpad == NULL, "Failed to get sinkpad from wavpackparse"); - fail_unless (gst_pad_unlink (mysrcpad, sinkpad), "Failed to unlink pads"); - gst_pad_set_caps (mysrcpad, NULL); - gst_object_unref (sinkpad); - gst_object_unref (mysrcpad); - - srcpad = gst_element_get_pad (wavpackparse, "src"); - fail_if (srcpad == NULL, "Failed to get srcpad from wavpackparse"); - fail_unless (gst_pad_unlink (srcpad, mysinkpad), "Failed to unlink pads"); - gst_pad_set_caps (mysinkpad, NULL); - gst_object_unref (srcpad); - gst_object_unref (mysinkpad); - - fail_unless (gst_element_set_state (wavpackparse, GST_STATE_NULL) == - GST_STATE_CHANGE_SUCCESS, "could not set to null"); - - gst_object_unref (wavpackparse); -} - -GST_START_TEST (test_parsing_valid_frames) -{ - GstBuffer *inbuffer, *outbuffer; - int i, num_buffers; - GstFormat format = GST_FORMAT_DEFAULT; - gint64 pos; - - setup_wavpackparse (); - - inbuffer = gst_buffer_new_and_alloc (sizeof (test_file)); - memcpy (GST_BUFFER_DATA (inbuffer), test_file, sizeof (test_file)); - gst_buffer_ref (inbuffer); - - /* should decode the buffer without problems */ - fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK); - gst_buffer_unref (inbuffer); - - num_buffers = g_list_length (buffers); - /* should get 2 buffers, each one complete wavpack frame */ - fail_unless_equals_int (num_buffers, 2); - - for (i = 0; i < num_buffers; ++i) { - outbuffer = GST_BUFFER (buffers->data); - fail_if (outbuffer == NULL); - - fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), "wvpk", 4) == 0, - "Buffer contains no Wavpack frame"); - fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 580498866); - - switch (i) { - case 0:{ - fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 0); - fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 0); - fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 25600); - break; - } - case 1:{ - fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 580498866); - fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 25600); - fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 51200); - break; - } - } - - buffers = g_list_remove (buffers, outbuffer); - - gst_buffer_unref (outbuffer); - outbuffer = NULL; - } - - fail_unless (gst_element_query_position (wavpackparse, &format, &pos), - "Position query failed"); - fail_unless_equals_int (pos, 25600); - fail_unless (gst_element_query_duration (wavpackparse, &format, NULL), - "Duration query failed"); - - g_list_free (buffers); - buffers = NULL; - - cleanup_wavpackparse (); -} - -GST_END_TEST; - -GST_START_TEST (test_parsing_invalid_first_header) -{ - GstBuffer *inbuffer, *outbuffer; - int i, num_buffers; - GstFormat format = GST_FORMAT_DEFAULT; - gint64 pos; - - setup_wavpackparse (); - - inbuffer = gst_buffer_new_and_alloc (sizeof (test_file)); - memcpy (GST_BUFFER_DATA (inbuffer), test_file, sizeof (test_file)); - GST_BUFFER_DATA (inbuffer)[0] = 'k'; - gst_buffer_ref (inbuffer); - - /* should decode the buffer without problems */ - fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK); - gst_buffer_unref (inbuffer); - - num_buffers = g_list_length (buffers); - - /* should get 1 buffers, the second non-broken one */ - fail_unless_equals_int (num_buffers, 1); - - for (i = 0; i < num_buffers; ++i) { - outbuffer = GST_BUFFER (buffers->data); - fail_if (outbuffer == NULL); - - fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), "wvpk", 4) == 0, - "Buffer contains no Wavpack frame"); - fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 580498866); - - switch (i) { - case 0:{ - fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 580498866); - fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 25600); - break; - } - } - - buffers = g_list_remove (buffers, outbuffer); - - gst_buffer_unref (outbuffer); - outbuffer = NULL; - } - - g_list_free (buffers); - buffers = NULL; - - cleanup_wavpackparse (); -} - -GST_END_TEST; - - -Suite * -wavpackparse_suite (void) -{ - Suite *s = suite_create ("wavpackparse"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_parsing_valid_frames); - tcase_add_test (tc_chain, test_parsing_invalid_first_header); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = wavpackparse_suite (); - SRunner *sr = srunner_create (s); - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -}