From: <wt...@fr...> - 2004-09-28 16:44:35
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: wtay Date: Tue Sep 28 2004 09:44:24 PDT Log message: * ext/speex/gstspeex.c: (plugin_init): * ext/speex/gstspeexdec.c: (gst_speex_dec_base_init), (gst_speex_dec_class_init), (speex_dec_get_formats), (speex_get_event_masks), (speex_get_query_types), (gst_speex_dec_init), (speex_dec_convert), (speex_dec_src_query), (speex_dec_src_event), (speex_dec_event), (speex_dec_chain), (gst_speexdec_get_property), (gst_speexdec_set_property), (speex_dec_change_state): * ext/speex/gstspeexdec.h: * ext/speex/gstspeexenc.c: (gst_speexenc_get_formats), (gst_speexenc_get_type), (speex_caps_factory), (raw_caps_factory), (gst_speexenc_base_init), (gst_speexenc_class_init), (gst_speexenc_sinkconnect), (gst_speexenc_convert_src), (gst_speexenc_convert_sink), (gst_speexenc_get_query_types), (gst_speexenc_src_query), (gst_speexenc_init), (gst_speexenc_get_tag_value), (comment_init), (comment_add), (gst_speexenc_metadata_set1), (gst_speexenc_set_metadata), (gst_speexenc_setup), (gst_speexenc_buffer_from_data), (gst_speexenc_push_buffer), (gst_speexenc_set_header_on_caps), (gst_speexenc_chain), (gst_speexenc_get_property), (gst_speexenc_set_property), (gst_speexenc_change_state): * ext/speex/gstspeexenc.h: Rewrote speex encoder, make sure it can be embedded in ogg. Implemented speex decoder. Modified files: . : ChangeLog ext/speex : gstspeex.c gstspeexdec.c gstspeexdec.h gstspeexenc.c gstspeexenc.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1095&r2=1.1096 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeex.c.diff?r1=1.7&r2=1.8 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexdec.c.diff?r1=1.16&r2=1.17 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexdec.h.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexenc.c.diff?r1=1.21&r2=1.22 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexenc.h.diff?r1=1.4&r2=1.5 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1095 retrieving revision 1.1096 diff -u -d -r1.1095 -r1.1096 --- ChangeLog 28 Sep 2004 11:01:10 -0000 1.1095 +++ ChangeLog 28 Sep 2004 16:44:12 -0000 1.1096 @@ -1,3 +1,30 @@ +2004-09-28 Wim Taymans <wi...@fl...> + + * ext/speex/gstspeex.c: (plugin_init): + * ext/speex/gstspeexdec.c: (gst_speex_dec_base_init), + (gst_speex_dec_class_init), (speex_dec_get_formats), + (speex_get_event_masks), (speex_get_query_types), + (gst_speex_dec_init), (speex_dec_convert), (speex_dec_src_query), + (speex_dec_src_event), (speex_dec_event), (speex_dec_chain), + (gst_speexdec_get_property), (gst_speexdec_set_property), + (speex_dec_change_state): + * ext/speex/gstspeexdec.h: + * ext/speex/gstspeexenc.c: (gst_speexenc_get_formats), + (gst_speexenc_get_type), (speex_caps_factory), (raw_caps_factory), + (gst_speexenc_base_init), (gst_speexenc_class_init), + (gst_speexenc_sinkconnect), (gst_speexenc_convert_src), + (gst_speexenc_convert_sink), (gst_speexenc_get_query_types), + (gst_speexenc_src_query), (gst_speexenc_init), + (gst_speexenc_get_tag_value), (comment_init), (comment_add), + (gst_speexenc_metadata_set1), (gst_speexenc_set_metadata), + (gst_speexenc_setup), (gst_speexenc_buffer_from_data), + (gst_speexenc_push_buffer), (gst_speexenc_set_header_on_caps), + (gst_speexenc_chain), (gst_speexenc_get_property), + (gst_speexenc_set_property), (gst_speexenc_change_state): + * ext/speex/gstspeexenc.h: + Rewrote speex encoder, make sure it can be embedded in ogg. + Implemented speex decoder. 2004-09-28 Christian Schaller <chr...@fl...> * configure.ac: Index: gstspeex.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeex.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gstspeex.c 15 Mar 2004 19:31:57 -0000 1.7 +++ gstspeex.c 28 Sep 2004 16:44:12 -0000 1.8 @@ -26,6 +26,12 @@ static gboolean plugin_init (GstPlugin * plugin) { + if (!gst_library_load ("gstbytestream")) + return FALSE; + if (!gst_library_load ("gsttags")) if (!gst_element_register (plugin, "speexenc", GST_RANK_NONE, GST_TYPE_SPEEXENC)) return FALSE; Index: gstspeexdec.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexdec.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- gstspeexdec.c 21 May 2004 23:28:57 -0000 1.16 +++ gstspeexdec.c 28 Sep 2004 16:44:12 -0000 1.17 @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) <1999> Erik Walthinsen <om...@cs...> + * Copyright (C) 2004 Wim Taymans <wi...@fl...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,177 +17,579 @@ * Boston, MA 02111-1307, USA. */ - #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif -#include <string.h> #include "gstspeexdec.h" +#include <string.h> +#include <gst/tag/tag.h> -/* elementfactory information */ -GstElementDetails gst_speexdec_details = { - "speex audio decoder", +GST_DEBUG_CATEGORY (speexdec_debug); +#define GST_CAT_DEFAULT speexdec_debug +static GstElementDetails speex_dec_details = { + "SpeexDec", "Codec/Decoder/Audio", - ".speex", - "Wim Taymans <wim...@ch...>", + "decode speex streams to audio", + "Wim Taymans <wi...@fl...>", }; -/* SpeexDec signals and args */ +/* Filter signals and args */ enum /* FILL ME */ LAST_SIGNAL +#define DEFAULT_ENH TRUE - ARG_0 - /* FILL ME */ + ARG_0, + ARG_ENH -static void gst_speexdec_base_init (gpointer g_class); -static void gst_speexdec_class_init (GstSpeexDec * klass); -static void gst_speexdec_init (GstSpeexDec * speexdec); -static void gst_speexdec_chain (GstPad * pad, GstData * _data); -static GstPadLinkReturn gst_speexdec_sinkconnect (GstPad * pad, - const GstCaps * caps); -static GstElementClass *parent_class = NULL; -/*static guint gst_speexdec_signals[LAST_SIGNAL] = { 0 }; */ -GType -gst_speexdec_get_type (void) -{ - static GType speexdec_type = 0; - if (!speexdec_type) { - static const GTypeInfo speexdec_info = { - sizeof (GstSpeexDecClass), - gst_speexdec_base_init, - NULL, - (GClassInitFunc) gst_speexdec_class_init, - sizeof (GstSpeexDec), - 0, - (GInstanceInitFunc) gst_speexdec_init, - }; - speexdec_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstSpeexDec", &speexdec_info, - 0); - } - return speexdec_type; -} -static GstStaticPadTemplate speexdec_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-speex, " - "rate = (int) [ 1000, 48000 ], " "channels = (int) 1") - ); -static GstStaticPadTemplate speexdec_src_template = +static GstStaticPadTemplate speex_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw-int, " + "rate = (int) [ 6000, 48000 ], " + "channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, " - "signed = (boolean) true, " - "width = (int) 16, " - "depth = (int) 16, " + "signed = (boolean) true, " "width = (int) 16, " "depth = (int) 16") + ); +static GstStaticPadTemplate speex_dec_sink_factory = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-speex") ); +GST_BOILERPLATE (GstSpeexDec, gst_speex_dec, GstElement, GST_TYPE_ELEMENT); +static void speex_dec_chain (GstPad * pad, GstData * data); +static GstElementStateReturn speex_dec_change_state (GstElement * element); +static const GstFormat *speex_dec_get_formats (GstPad * pad); +static gboolean speex_dec_src_event (GstPad * pad, GstEvent * event); +static gboolean speex_dec_src_query (GstPad * pad, + GstQueryType query, GstFormat * format, gint64 * value); +static gboolean speex_dec_convert (GstPad * pad, + GstFormat src_format, gint64 src_value, + GstFormat * dest_format, gint64 * dest_value); +static void gst_speexdec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_speexdec_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); static void -gst_speexdec_base_init (gpointer g_class) +gst_speex_dec_base_init (gpointer g_class) GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&speexdec_src_template)); + gst_static_pad_template_get (&speex_dec_src_factory)); - gst_static_pad_template_get (&speexdec_sink_template)); - gst_element_class_set_details (element_class, &gst_speexdec_details); + gst_static_pad_template_get (&speex_dec_sink_factory)); + gst_element_class_set_details (element_class, &speex_dec_details); } -gst_speexdec_class_init (GstSpeexDec * klass) +gst_speex_dec_class_init (GstSpeexDecClass * klass) + GObjectClass *gobject_class; GstElementClass *gstelement_class; + gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ENH, + g_param_spec_boolean ("enh", "Enh", "Enable perceptual enhancement", + DEFAULT_ENH, G_PARAM_READWRITE)); + gstelement_class->change_state = speex_dec_change_state; + gobject_class->set_property = gst_speexdec_set_property; + gobject_class->get_property = gst_speexdec_get_property; + GST_DEBUG_CATEGORY_INIT (speexdec_debug, "speexdec", 0, + "speex decoding element"); -static void -gst_speexdec_init (GstSpeexDec * speexdec) +static const GstFormat * +speex_dec_get_formats (GstPad * pad) - GST_DEBUG ("gst_speexdec_init: initializing"); + static GstFormat src_formats[] = { + GST_FORMAT_BYTES, + GST_FORMAT_DEFAULT, /* samples in the audio case */ + GST_FORMAT_TIME, + 0 + }; + static GstFormat sink_formats[] = { + GST_FORMAT_DEFAULT, /* samples */ - /* create the sink and src pads */ - speexdec->sinkpad = + return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats); +} +static const GstEventMask * +speex_get_event_masks (GstPad * pad) +{ + static const GstEventMask speex_dec_src_event_masks[] = { + {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH}, + {0,} + return speex_dec_src_event_masks; +static const GstQueryType * +speex_get_query_types (GstPad * pad) + static const GstQueryType speex_dec_src_query_types[] = { + GST_QUERY_TOTAL, + GST_QUERY_POSITION, + return speex_dec_src_query_types; +static void +gst_speex_dec_init (GstSpeexDec * dec) + dec->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get - (&speexdec_sink_template), "sink"); - gst_element_add_pad (GST_ELEMENT (speexdec), speexdec->sinkpad); - gst_pad_set_chain_function (speexdec->sinkpad, gst_speexdec_chain); - gst_pad_set_link_function (speexdec->sinkpad, gst_speexdec_sinkconnect); + (&speex_dec_sink_factory), "sink"); + gst_pad_set_chain_function (dec->sinkpad, speex_dec_chain); + gst_pad_set_formats_function (dec->sinkpad, speex_dec_get_formats); + gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad); - speexdec->srcpad = + dec->srcpad = - (&speexdec_src_template), "src"); - gst_pad_use_explicit_caps (speexdec->srcpad); - gst_element_add_pad (GST_ELEMENT (speexdec), speexdec->srcpad); + (&speex_dec_src_factory), "src"); + gst_pad_use_explicit_caps (dec->srcpad); + gst_pad_set_event_mask_function (dec->srcpad, speex_get_event_masks); + gst_pad_set_event_function (dec->srcpad, speex_dec_src_event); + gst_pad_set_query_type_function (dec->srcpad, speex_get_query_types); + gst_pad_set_query_function (dec->srcpad, speex_dec_src_query); + gst_pad_set_formats_function (dec->srcpad, speex_dec_get_formats); + gst_pad_set_convert_function (dec->srcpad, speex_dec_convert); + gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); + dec->enh = DEFAULT_ENH; + GST_FLAG_SET (dec, GST_ELEMENT_EVENT_AWARE); -static GstPadLinkReturn -gst_speexdec_sinkconnect (GstPad * pad, const GstCaps * caps) +static gboolean +speex_dec_convert (GstPad * pad, + GstFormat * dest_format, gint64 * dest_value) + gboolean res = TRUE; + GstSpeexDec *dec; + guint64 scale = 1; + dec = GST_SPEEXDEC (gst_pad_get_parent (pad)); + if (dec->packetno < 1) + switch (src_format) { + case GST_FORMAT_TIME: + switch (*dest_format) { + case GST_FORMAT_BYTES: + scale = sizeof (float) * dec->header->nb_channels; + case GST_FORMAT_DEFAULT: + *dest_value = scale * (src_value * dec->header->rate / GST_SECOND); + break; + default: + res = FALSE; + } + break; + case GST_FORMAT_DEFAULT: + *dest_value = src_value * sizeof (float) * dec->header->nb_channels; + case GST_FORMAT_TIME: + *dest_value = src_value * GST_SECOND / dec->header->rate; + case GST_FORMAT_BYTES: + *dest_value = src_value / (sizeof (float) * dec->header->nb_channels); + *dest_value = src_value * GST_SECOND / + (dec->header->rate * sizeof (float) * dec->header->nb_channels); + default: + res = FALSE; + } + return res; +speex_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format, + gint64 * value) + gint64 samples_out = 0; + GstSpeexDec *dec = GST_SPEEXDEC (gst_pad_get_parent (pad)); + GstFormat my_format = GST_FORMAT_DEFAULT; + if (query == GST_QUERY_POSITION) { + samples_out = dec->samples_out; + } else { + /* query peer in default format */ + if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, + &samples_out)) + return FALSE; + /* and convert to the final format */ + if (!gst_pad_convert (pad, GST_FORMAT_DEFAULT, samples_out, format, value)) + GST_LOG_OBJECT (dec, + "query %u: peer returned samples_out: %llu - we return %llu (format %u)\n", + query, samples_out, *value, *format); + return TRUE; +speex_dec_src_event (GstPad * pad, GstEvent * event) + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK:{ + guint64 value; + GstFormat my_format = GST_FORMAT_DEFAULT; + /* convert to samples_out */ + res = speex_dec_convert (pad, GST_EVENT_SEEK_FORMAT (event), + GST_EVENT_SEEK_OFFSET (event), &my_format, &value); + if (res) { + GstEvent *real_seek = gst_event_new_seek ( + (GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) | + GST_FORMAT_DEFAULT, + value); + res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek); + gst_event_unref (event); + } + res = gst_pad_event_default (pad, event); +speex_dec_event (GstSpeexDec * dec, GstEvent * event) + guint64 value, time, bytes; + GST_LOG_OBJECT (dec, "handling event"); + case GST_EVENT_DISCONTINUOUS: + if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, + (gint64 *) & value)) { + dec->samples_out = value; + GST_DEBUG_OBJECT (dec, + "setting samples_out to %" G_GUINT64_FORMAT " after discont", + } else { + GST_WARNING_OBJECT (dec, + "discont event didn't include offset, we might set it wrong now"); + if (dec->packetno < 2) { + if (dec->samples_out != 0) + GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), + ("can't handle discont before parsing first 2 packets")); + dec->packetno = 0; + gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, + GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT, + (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0))); + GstFormat time_format, default_format, bytes_format; + time_format = GST_FORMAT_TIME; + default_format = GST_FORMAT_DEFAULT; + bytes_format = GST_FORMAT_BYTES; + dec->packetno = 2; + /* if one of them works, all of them work */ + if (speex_dec_convert (dec->srcpad, GST_FORMAT_DEFAULT, + dec->samples_out, &time_format, &time) + && speex_dec_convert (dec->srcpad, GST_FORMAT_DEFAULT, + dec->samples_out, &bytes_format, &bytes)) { + gst_pad_push (dec->srcpad, + GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, + time, GST_FORMAT_DEFAULT, dec->samples_out, + GST_FORMAT_BYTES, bytes, 0))); + } else { + GST_ERROR_OBJECT (dec, + "failed to parse data for DISCONT event, not sending any"); + } + gst_data_unref (GST_DATA (event)); + gst_pad_event_default (dec->sinkpad, event); +speex_dec_chain (GstPad * pad, GstData * data) + GstBuffer *buf; + if (GST_IS_EVENT (data)) { + speex_dec_event (dec, GST_EVENT (data)); + return; + buf = GST_BUFFER (data); + if (dec->packetno == 0) { + GstCaps *caps; + /* get the header */ + dec->header = + speex_packet_to_header (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + gst_data_unref (data); + if (!dec->header) { + GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE, + (NULL), ("couldn't read header")); + return; + if (dec->header->mode >= SPEEX_NB_MODES) { + (NULL), + ("Mode number %d does not (yet/any longer) exist in this version", + dec->header->mode)); + dec->mode = speex_mode_list[dec->header->mode]; + /* initialize the decoder */ + dec->state = speex_decoder_init (dec->mode); + if (!dec->state) { + (NULL), ("couldn't initialize decoder")); + gst_data_unref (data); + speex_decoder_ctl (dec->state, SPEEX_SET_ENH, &dec->enh); + speex_decoder_ctl (dec->state, SPEEX_GET_FRAME_SIZE, &dec->frame_size); + if (dec->header->nb_channels != 1) { + dec->callback.callback_id = SPEEX_INBAND_STEREO; + dec->callback.func = speex_std_stereo_request_handler; + dec->callback.data = &dec->stereo; + speex_decoder_ctl (dec->state, SPEEX_SET_HANDLER, &dec->callback); + speex_decoder_ctl (dec->state, SPEEX_SET_SAMPLING_RATE, &dec->header->rate); + speex_bits_init (&dec->bits); + /* set caps */ + caps = gst_caps_new_simple ("audio/x-raw-int", + "rate", G_TYPE_INT, dec->header->rate, + "channels", G_TYPE_INT, dec->header->nb_channels, + "signed", G_TYPE_BOOLEAN, TRUE, + "endianness", G_TYPE_INT, G_BYTE_ORDER, + "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL); + if (!gst_pad_set_explicit_caps (dec->srcpad, caps)) { + gst_caps_free (caps); + gst_caps_free (caps); + } else if (dec->packetno == 1) { + gchar *encoder = NULL; + /* FIXME parse comments */ + GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf, "", 1, + &encoder); + if (!list) { + GST_WARNING_OBJECT (dec, "couldn't decode comments"); + list = gst_tag_list_new (); + if (encoder) { + gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, + GST_TAG_ENCODER, encoder, NULL); + g_free (encoder); + /* + gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, + GST_TAG_ENCODER_VERSION, dec->vi.version, NULL); + if (dec->vi.bitrate_upper > 0) + GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL); + if (vd->vi.bitrate_nominal > 0) + GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL); + if (vd->vi.bitrate_lower > 0) + GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL); + */ + gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, 0, list); + gint i; + /* send data to the bitstream */ + speex_bits_read_from (&dec->bits, GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + /* now decode each frame */ + for (i = 0; i < dec->header->frames_per_packet; i++) { + gint ret; + GstBuffer *outbuf; + gint16 *out_data; + ret = speex_decode (dec->state, &dec->bits, dec->output); + if (ret == -1) { + /* FIXME emit warning */ + break; + } else if (ret == -2) { + if (speex_bits_remaining (&dec->bits) < 0) { + fprintf (stderr, "Decoding overflow: corrupted stream?\n"); + if (dec->header->nb_channels == 2) + speex_decode_stereo (dec->output, dec->frame_size, &dec->stereo); + outbuf = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE, + dec->frame_size * dec->header->nb_channels * 2); + out_data = (gint16 *) GST_BUFFER_DATA (outbuf); + /*PCM saturation (just in case) */ + for (i = 0; i < dec->frame_size * dec->header->nb_channels; i++) { + if (dec->output[i] > 32000.0) + out_data[i] = 32000; + else if (dec->output[i] < -32000.0) + out_data[i] = -32000; + else + out_data[i] = (gint16) dec->output[i]; + GST_BUFFER_OFFSET (outbuf) = dec->samples_out; + GST_BUFFER_OFFSET_END (outbuf) = dec->samples_out + dec->frame_size; + GST_BUFFER_TIMESTAMP (outbuf) = + dec->samples_out * GST_SECOND / dec->header->rate; + GST_BUFFER_DURATION (outbuf) = + dec->frame_size * GST_SECOND / dec->header->rate; + gst_pad_push (dec->srcpad, GST_DATA (outbuf)); + dec->samples_out += dec->frame_size; + dec->packetno++; +gst_speexdec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) GstSpeexDec *speexdec; - gint rate; - GstStructure *structure; - speexdec = GST_SPEEXDEC (gst_pad_get_parent (pad)); + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_SPEEXDEC (object)); - structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "rate", &rate); + speexdec = GST_SPEEXDEC (object); - if (gst_pad_set_explicit_caps (speexdec->srcpad, - gst_caps_new_simple ("audio/x-raw-int", - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "signed", G_TYPE_BOOLEAN, TRUE, - "width", G_TYPE_INT, 16, - "depth", G_TYPE_INT, 16, - "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, 1, NULL))) { - return GST_PAD_LINK_OK; + switch (prop_id) { + case ARG_ENH: + g_value_set_boolean (value, speexdec->enh); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } - return GST_PAD_LINK_REFUSED; -gst_speexdec_chain (GstPad * pad, GstData * _data) +gst_speexdec_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) - GstBuffer *buf = GST_BUFFER (_data); - gchar *data; - guint size; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - /*g_return_if_fail(GST_IS_BUFFER(buf)); */ - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); + speexdec->enh = g_value_get_boolean (value); - gst_buffer_unref (buf); +static GstElementStateReturn +speex_dec_change_state (GstElement * element) + GstSpeexDec *vd = GST_SPEEXDEC (element); + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + case GST_STATE_READY_TO_PAUSED: + case GST_STATE_PAUSED_TO_PLAYING: + case GST_STATE_PLAYING_TO_PAUSED: + case GST_STATE_PAUSED_TO_READY: + vd->packetno = 0; + vd->samples_out = 0; + case GST_STATE_READY_TO_NULL: + return parent_class->change_state (element); Index: gstspeexdec.h RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexdec.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- gstspeexdec.h 15 Mar 2004 16:32:38 -0000 1.4 +++ gstspeexdec.h 28 Sep 2004 16:44:12 -0000 1.5 @@ -23,7 +23,10 @@ #include <gst/gst.h> -#include <speex.h> +#include <speex/speex.h> +#include <speex/speex_callbacks.h> +#include <speex/speex_header.h> +#include <speex/speex_stereo.h> #ifdef __cplusplus extern "C" { @@ -31,7 +34,7 @@ #define GST_TYPE_SPEEXDEC \ - (gst_speexdec_get_type()) + (gst_speex_dec_get_type()) #define GST_SPEEXDEC(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPEEXDEC,GstSpeexDec)) #define GST_SPEEXDEC_CLASS(klass) \ @@ -44,18 +47,35 @@ typedef struct _GstSpeexDec GstSpeexDec; typedef struct _GstSpeexDecClass GstSpeexDecClass; +#define DEC_MAX_FRAME_SIZE 2000 struct _GstSpeexDec { GstElement element; /* pads */ GstPad *sinkpad,*srcpad; + void *state; + SpeexStereoState stereo; + SpeexMode *mode; + SpeexHeader *header; + SpeexCallback callback; + SpeexBits bits; + + gfloat output[DEC_MAX_FRAME_SIZE]; + gboolean enh; + + gint frame_size; + guint64 samples_out; + guint64 packetno; struct _GstSpeexDecClass { GstElementClass parent_class; -GType gst_speexdec_get_type(void); +GType gst_speex_dec_get_type(void); Index: gstspeexenc.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexenc.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- gstspeexenc.c 21 May 2004 23:28:57 -0000 1.21 +++ gstspeexenc.c 28 Sep 2004 16:44:12 -0000 1.22 @@ -21,42 +21,94 @@ #include "config.h" +#include <stdlib.h> #include <string.h> +#include <time.h> +#include <math.h> +#include <gst/gsttaginterface.h> [...1161 lines suppressed...] + speexenc->setup = FALSE; + speexenc->header_sent = FALSE; + gst_tag_list_free (speexenc->tags); + speexenc->tags = gst_tag_list_new (); + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + return GST_STATE_SUCCESS; Index: gstspeexenc.h RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexenc.h,v --- gstspeexenc.h 15 Mar 2004 16:32:38 -0000 1.4 +++ gstspeexenc.h 28 Sep 2004 16:44:12 -0000 1.5 @@ -23,6 +23,7 @@ +#include <gst/bytestream/adapter.h> #include <speex.h> #include <speex_header.h> @@ -43,6 +44,17 @@ #define GST_IS_SPEEXENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPEEXENC)) +#define MAX_FRAME_SIZE 2000*2 +#define MAX_FRAME_BYTES 2000 +typedef enum + GST_SPEEXENC_MODE_AUTO, + GST_SPEEXENC_MODE_UWB, + GST_SPEEXENC_MODE_WB, + GST_SPEEXENC_MODE_NB, +} GstSpeexMode; typedef struct _GstSpeexEnc GstSpeexEnc; typedef struct _GstSpeexEncClass GstSpeexEncClass; @@ -58,14 +70,43 @@ SpeexBits bits; SpeexHeader header; - SpeexMode *mode; + SpeexMode *speex_mode; void *state; + GstSpeexMode mode; + GstAdapter *adapter; + gfloat quality; + gint bitrate; + gboolean vbr; + gint abr; + gboolean vad; + gboolean dtx; + gint complexity; + gint nframes; + gint lookahead; + gint channels; + gint rate; + gboolean setup; + gboolean header_sent; + gboolean eos; + guint64 samples_in; + guint64 bytes_out; + GstTagList *tags; + gchar *last_message; gint frame_size; - gint16 buffer[2000]; - gint bufsize; - guint64 next_ts; + guint64 frameno; - gint rate; + gchar *comments; + gint comment_len; + gfloat input[MAX_FRAME_SIZE]; struct _GstSpeexEncClass { |
From: <wt...@fr...> - 2004-10-01 16:15:38
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: wtay Date: Fri Oct 01 2004 09:15:35 PDT Log message: * ext/speex/gstspeexdec.c: (gst_speex_dec_class_init), (speex_dec_get_formats), (speex_dec_convert), (speex_dec_src_query), (speex_dec_src_event), (speex_dec_event), (speex_dec_chain), (gst_speexdec_get_property), (gst_speexdec_set_property): Small cleanups. Modified files: . : ChangeLog ext/speex : gstspeexdec.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1110&r2=1.1111 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexdec.c.diff?r1=1.17&r2=1.18 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1110 retrieving revision 1.1111 diff -u -d -r1.1110 -r1.1111 --- ChangeLog 1 Oct 2004 16:01:51 -0000 1.1110 +++ ChangeLog 1 Oct 2004 16:15:23 -0000 1.1111 @@ -1,5 +1,14 @@ 2004-10-01 Wim Taymans <wi...@fl...> + * ext/speex/gstspeexdec.c: (gst_speex_dec_class_init), + (speex_dec_get_formats), (speex_dec_convert), + (speex_dec_src_query), (speex_dec_src_event), (speex_dec_event), + (speex_dec_chain), (gst_speexdec_get_property), + (gst_speexdec_set_property): + Small cleanups. + +2004-10-01 Wim Taymans <wi...@fl...> * gst/wavparse/gstwavparse.c: (gst_wavparse_class_init), (gst_wavparse_stream_init), (gst_wavparse_fmt), (gst_wavparse_other), (gst_wavparse_loop), Index: gstspeexdec.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexdec.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- gstspeexdec.c 28 Sep 2004 16:44:12 -0000 1.17 +++ gstspeexdec.c 1 Oct 2004 16:15:23 -0000 1.18 @@ -484,14 +484,15 @@ ret = speex_decode (dec->state, &dec->bits, dec->output); if (ret == -1) { - /* FIXME emit warning */ + /* uh? end of stream */ + GST_WARNING_OBJECT (dec, "Unexpected end of stream found"); break; } else if (ret == -2) { + GST_WARNING_OBJECT (dec, "Decoding error: corrupted stream?"); } if (speex_bits_remaining (&dec->bits) < 0) { - fprintf (stderr, "Decoding overflow: corrupted stream?\n"); + GST_WARNING_OBJECT (dec, "Decoding overflow: corrupted stream?"); if (dec->header->nb_channels == 2) @@ -503,10 +504,10 @@ /*PCM saturation (just in case) */ for (i = 0; i < dec->frame_size * dec->header->nb_channels; i++) { - if (dec->output[i] > 32000.0) - out_data[i] = 32000; - else if (dec->output[i] < -32000.0) - out_data[i] = -32000; + if (dec->output[i] > 32767.0) + out_data[i] = 32767; + else if (dec->output[i] < -32768.0) + out_data[i] = -32768; else out_data[i] = (gint16) dec->output[i]; |
From: <wt...@fr...> - 2004-10-18 10:57:59
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: wtay Date: Mon Oct 18 2004 03:57:57 PDT Log message: * ext/speex/gstspeexenc.c: (gst_speexenc_class_init), (gst_speexenc_chain): Fix speex timestamps so that it gets muxed properly. Modified files: . : ChangeLog ext/speex : gstspeexenc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1170&r2=1.1171 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexenc.c.diff?r1=1.25&r2=1.26 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1170 retrieving revision 1.1171 diff -u -d -r1.1170 -r1.1171 --- ChangeLog 15 Oct 2004 14:35:54 -0000 1.1170 +++ ChangeLog 18 Oct 2004 10:57:45 -0000 1.1171 @@ -1,5 +1,11 @@ 2004-10-15 Wim Taymans <wi...@fl...> + * ext/speex/gstspeexenc.c: (gst_speexenc_class_init), + (gst_speexenc_chain): + Fix speex timestamps so that it gets muxed properly. + +2004-10-15 Wim Taymans <wi...@fl...> * ext/raw1394/gstdv1394src.c: (gst_dv1394src_get_type), (gst_dv1394src_base_init), (gst_dv1394src_class_init), (gst_dv1394src_init), (gst_dv1394src_dispose), Index: gstspeexenc.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexenc.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- gstspeexenc.c 4 Oct 2004 14:54:49 -0000 1.25 +++ gstspeexenc.c 18 Oct 2004 10:57:45 -0000 1.26 @@ -196,7 +196,7 @@ 0.0, 10.0, DEFAULT_QUALITY, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, g_param_spec_int ("bitrate", "Encoding Bit-rate", - "Specify an encoding bit-rate (in bps). ", + "Specify an encoding bit-rate (in bps). (0 = automatic)", 0, G_MAXINT, DEFAULT_BITRATE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR, g_param_spec_boolean ("vbr", "VBR", @@ -952,6 +952,10 @@ g_assert (written == outsize); speex_bits_reset (&speexenc->bits); + GST_BUFFER_TIMESTAMP (outbuf) = + (speexenc->frameno * frame_size - + speexenc->lookahead) * GST_SECOND / speexenc->rate; + GST_BUFFER_DURATION (outbuf) = frame_size * GST_SECOND / speexenc->rate; GST_BUFFER_OFFSET (outbuf) = speexenc->bytes_out; GST_BUFFER_OFFSET_END (outbuf) = speexenc->frameno * frame_size - speexenc->lookahead; |
From: <wt...@fr...> - 2005-08-23 18:25:36
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: wtay Date: Tue Aug 23 2005 11:24:48 PDT Log message: * ext/speex/gstspeexdec.c: (gst_speex_dec_class_init): * ext/speex/gstspeexenc.c: (gst_speexenc_class_init): Fix property warning. Modified files: . : ChangeLog ext/speex : gstspeexdec.c gstspeexenc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1808&r2=1.1809 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexdec.c.diff?r1=1.23&r2=1.24 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/speex/gstspeexenc.c.diff?r1=1.27&r2=1.28 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1808 retrieving revision 1.1809 diff -u -d -r1.1808 -r1.1809 --- ChangeLog 23 Aug 2005 16:54:38 -0000 1.1808 +++ ChangeLog 23 Aug 2005 18:24:36 -0000 1.1809 @@ -1,5 +1,11 @@ 2005-08-23 Wim Taymans <wi...@fl...> + * ext/speex/gstspeexdec.c: (gst_speex_dec_class_init): + * ext/speex/gstspeexenc.c: (gst_speexenc_class_init): + Fix property warning. + +2005-08-23 Wim Taymans <wi...@fl...> * gst/rtp/gstrtpamrdec.c: (gst_rtpamrdec_init), (gst_rtpamrdec_sink_setcaps), (gst_rtpamrdec_chain): * gst/rtp/gstrtpamrenc.c: (gst_rtpamrenc_class_init), Index: gstspeexdec.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexdec.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gstspeexdec.c 23 Aug 2005 15:14:01 -0000 1.23 +++ gstspeexdec.c 23 Aug 2005 18:24:36 -0000 1.24 @@ -99,15 +99,15 @@ gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; + gobject_class->set_property = gst_speexdec_set_property; + gobject_class->get_property = gst_speexdec_get_property; g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ENH, g_param_spec_boolean ("enh", "Enh", "Enable perceptual enhancement", DEFAULT_ENH, G_PARAM_READWRITE)); gstelement_class->change_state = speex_dec_change_state; - gobject_class->set_property = gst_speexdec_set_property; - gobject_class->get_property = gst_speexdec_get_property; - GST_DEBUG_CATEGORY_INIT (speexdec_debug, "speexdec", 0, "speex decoding element"); } Index: gstspeexenc.c RCS file: /cvs/gstreamer/gst-plugins/ext/speex/gstspeexenc.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- gstspeexenc.c 5 Jul 2005 10:51:37 -0000 1.27 +++ gstspeexenc.c 23 Aug 2005 18:24:36 -0000 1.28 @@ -191,6 +191,9 @@ + gobject_class->set_property = gst_speexenc_set_property; + gobject_class->get_property = gst_speexenc_get_property; g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY, g_param_spec_float ("quality", "Quality", "Encoding quality", 0.0, 10.0, DEFAULT_QUALITY, G_PARAM_READWRITE)); @@ -225,9 +228,6 @@ parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - gobject_class->set_property = gst_speexenc_set_property; - gobject_class->get_property = gst_speexenc_get_property; gstelement_class->change_state = gst_speexenc_change_state; |