/* GStreamer * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * * 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., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** * SECTION:element-mulawdec * * This element decodes mulaw audio. Mulaw coding is also known as G.711. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <gst/gst.h> #include "mulaw-decode.h" #include "mulaw-conversion.h" extern GstStaticPadTemplate mulaw_dec_src_factory; extern GstStaticPadTemplate mulaw_dec_sink_factory; static gboolean gst_mulawdec_set_format (GstAudioDecoder * dec, GstCaps * caps); static GstFlowReturn gst_mulawdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer); /* Stereo signals and args */ enum { /* FILL ME */ LAST_SIGNAL }; enum { ARG_0 }; #define gst_mulawdec_parent_class parent_class G_DEFINE_TYPE (GstMuLawDec, gst_mulawdec, GST_TYPE_AUDIO_DECODER); static gboolean gst_mulawdec_set_format (GstAudioDecoder * dec, GstCaps * caps) { GstMuLawDec *mulawdec = GST_MULAWDEC (dec); GstStructure *structure; int rate, channels; GstAudioInfo info; structure = gst_caps_get_structure (caps, 0); if (!structure) { GST_ERROR ("failed to get structure from caps"); goto error_failed_get_structure; } if (!gst_structure_get_int (structure, "rate", &rate)) { GST_ERROR ("failed to find field rate in input caps"); goto error_failed_find_rate; } if (!gst_structure_get_int (structure, "channels", &channels)) { GST_ERROR ("failed to find field channels in input caps"); goto error_failed_find_channel; } gst_audio_info_init (&info); gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S16, rate, channels, NULL); GST_DEBUG_OBJECT (mulawdec, "rate=%d, channels=%d", rate, channels); return gst_audio_decoder_set_output_format (dec, &info); error_failed_find_channel: error_failed_find_rate: error_failed_get_structure: return FALSE; } static GstFlowReturn gst_mulawdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer) { GstMapInfo inmap, outmap; gint16 *linear_data; guint8 *mulaw_data; gsize mulaw_size, linear_size; GstBuffer *outbuf; if (!buffer) { return GST_FLOW_OK; } if (!gst_buffer_map (buffer, &inmap, GST_MAP_READ)) { GST_ERROR ("failed to map input buffer"); goto error_failed_map_input_buffer; } mulaw_data = inmap.data; mulaw_size = inmap.size; linear_size = mulaw_size * 2; outbuf = gst_audio_decoder_allocate_output_buffer (dec, linear_size); if (!gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE)) { GST_ERROR ("failed to map input buffer"); goto error_failed_map_output_buffer; } linear_data = (gint16 *) outmap.data; mulaw_decode (mulaw_data, linear_data, mulaw_size); gst_buffer_unmap (outbuf, &outmap); gst_buffer_unmap (buffer, &inmap); return gst_audio_decoder_finish_frame (dec, outbuf, -1); error_failed_map_output_buffer: gst_buffer_unref (outbuf); error_failed_map_input_buffer: return GST_FLOW_ERROR; } static void gst_mulawdec_class_init (GstMuLawDecClass * klass) { GstElementClass *element_class = (GstElementClass *) klass; GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&mulaw_dec_src_factory)); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&mulaw_dec_sink_factory)); audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_mulawdec_set_format); audiodec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mulawdec_handle_frame); gst_element_class_set_static_metadata (element_class, "Mu Law audio decoder", "Codec/Decoder/Audio", "Convert 8bit mu law to 16bit PCM", "Zaheer Abbas Merali <zaheerabbas at merali dot org>"); } static void gst_mulawdec_init (GstMuLawDec * mulawdec) { gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (mulawdec), TRUE); }