mulaw-encode.c 5.55 KB
Newer Older
Christian Schaller's avatar
Christian Schaller committed
1
/* GStreamer
Andy Wingo's avatar
Andy Wingo committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15
 * 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
Tim-Philipp Müller's avatar
Tim-Philipp Müller committed
16 17
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
Andy Wingo's avatar
Andy Wingo committed
18
 */
19 20 21 22 23
/**
 * SECTION:element-mulawenc
 *
 * This element encode mulaw audio. Mulaw coding is also known as G.711.
 */
Andy Wingo's avatar
Andy Wingo committed
24

25 26 27
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Andy Wingo's avatar
Andy Wingo committed
28
#include <gst/gst.h>
Wim Taymans's avatar
Wim Taymans committed
29 30
#include <gst/audio/audio.h>

Andy Wingo's avatar
Andy Wingo committed
31 32 33
#include "mulaw-encode.h"
#include "mulaw-conversion.h"

34 35
extern GstStaticPadTemplate mulaw_enc_src_factory;
extern GstStaticPadTemplate mulaw_enc_sink_factory;
Andy Wingo's avatar
Andy Wingo committed
36 37

/* Stereo signals and args */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
38 39
enum
{
Andy Wingo's avatar
Andy Wingo committed
40 41 42 43
  /* FILL ME */
  LAST_SIGNAL
};

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
44 45
enum
{
46
  PROP_0
Andy Wingo's avatar
Andy Wingo committed
47 48
};

49 50 51 52
static gboolean gst_mulawenc_start (GstAudioEncoder * audioenc);
static gboolean gst_mulawenc_set_format (GstAudioEncoder * enc,
    GstAudioInfo * info);
static GstFlowReturn gst_mulawenc_handle_frame (GstAudioEncoder * enc,
Wim Taymans's avatar
Wim Taymans committed
53
    GstBuffer * buffer);
54 55
static void gst_mulawenc_set_tags (GstMuLawEnc * mulawenc);

Andy Wingo's avatar
Andy Wingo committed
56

Wim Taymans's avatar
Wim Taymans committed
57
#define gst_mulawenc_parent_class parent_class
58
G_DEFINE_TYPE (GstMuLawEnc, gst_mulawenc, GST_TYPE_AUDIO_ENCODER);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
59

Christian Schaller's avatar
Christian Schaller committed
60
/*static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; */
Andy Wingo's avatar
Andy Wingo committed
61

62 63
static gboolean
gst_mulawenc_start (GstAudioEncoder * audioenc)
64
{
65
  GstMuLawEnc *mulawenc = GST_MULAWENC (audioenc);
Wim Taymans's avatar
Wim Taymans committed
66

67 68
  mulawenc->channels = 0;
  mulawenc->rate = 0;
Wim Taymans's avatar
Wim Taymans committed
69

70
  return TRUE;
71 72
}

73 74 75

static void
gst_mulawenc_set_tags (GstMuLawEnc * mulawenc)
Wim Taymans's avatar
Wim Taymans committed
76
{
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
  GstTagList *taglist;
  guint bitrate;

  /* bitrate of mulaw is 8 bits/sample * sample rate * number of channels */
  bitrate = 8 * mulawenc->rate * mulawenc->channels;

  taglist = gst_tag_list_new_empty ();
  gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
      GST_TAG_MAXIMUM_BITRATE, bitrate, NULL);
  gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
      GST_TAG_MINIMUM_BITRATE, bitrate, NULL);
  gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
      GST_TAG_BITRATE, bitrate, NULL);

  gst_audio_encoder_merge_tags (GST_AUDIO_ENCODER (mulawenc),
      taglist, GST_TAG_MERGE_REPLACE);

  gst_tag_list_unref (taglist);
Wim Taymans's avatar
Wim Taymans committed
95 96 97
}


98
static gboolean
99
gst_mulawenc_set_format (GstAudioEncoder * audioenc, GstAudioInfo * info)
Andy Wingo's avatar
Andy Wingo committed
100
{
101
  GstCaps *base_caps;
102 103
  GstStructure *structure;
  GstMuLawEnc *mulawenc = GST_MULAWENC (audioenc);
104
  gboolean ret;
105

106 107
  mulawenc->rate = info->rate;
  mulawenc->channels = info->channels;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
108

109 110 111
  base_caps =
      gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (audioenc));
  g_assert (base_caps);
Wim Taymans's avatar
Wim Taymans committed
112
  base_caps = gst_caps_make_writable (base_caps);
113
  g_assert (base_caps);
114 115

  structure = gst_caps_get_structure (base_caps, 0);
116
  g_assert (structure);
117 118 119
  gst_structure_set (structure, "rate", G_TYPE_INT, mulawenc->rate, NULL);
  gst_structure_set (structure, "channels", G_TYPE_INT, mulawenc->channels,
      NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
120

121
  gst_mulawenc_set_tags (mulawenc);
Wim Taymans's avatar
Wim Taymans committed
122

123 124 125 126
  ret = gst_audio_encoder_set_output_format (audioenc, base_caps);
  gst_caps_unref (base_caps);

  return ret;
Wim Taymans's avatar
Wim Taymans committed
127 128
}

129
static GstFlowReturn
130
gst_mulawenc_handle_frame (GstAudioEncoder * audioenc, GstBuffer * buffer)
Andy Wingo's avatar
Andy Wingo committed
131 132
{
  GstMuLawEnc *mulawenc;
Wim Taymans's avatar
Wim Taymans committed
133
  GstMapInfo inmap, outmap;
Andy Wingo's avatar
Andy Wingo committed
134
  gint16 *linear_data;
Wim Taymans's avatar
Wim Taymans committed
135
  gsize linear_size;
Andy Wingo's avatar
Andy Wingo committed
136
  guint8 *mulaw_data;
137
  guint mulaw_size;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
138
  GstBuffer *outbuf;
139
  GstFlowReturn ret;
Andy Wingo's avatar
Andy Wingo committed
140

141 142 143 144 145 146
  if (!buffer) {
    ret = GST_FLOW_OK;
    goto done;
  }

  mulawenc = GST_MULAWENC (audioenc);
Andy Wingo's avatar
Andy Wingo committed
147

148 149 150
  if (!mulawenc->rate || !mulawenc->channels)
    goto not_negotiated;

Wim Taymans's avatar
Wim Taymans committed
151 152 153
  gst_buffer_map (buffer, &inmap, GST_MAP_READ);
  linear_data = (gint16 *) inmap.data;
  linear_size = inmap.size;
154 155 156

  mulaw_size = linear_size / 2;

157
  outbuf = gst_audio_encoder_allocate_output_buffer (audioenc, mulaw_size);
158

159
  g_assert (outbuf);
160

Wim Taymans's avatar
Wim Taymans committed
161 162
  gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
  mulaw_data = outmap.data;
163

164
  mulaw_encode (linear_data, mulaw_data, mulaw_size);
Andy Wingo's avatar
Andy Wingo committed
165

Wim Taymans's avatar
Wim Taymans committed
166 167
  gst_buffer_unmap (outbuf, &outmap);
  gst_buffer_unmap (buffer, &inmap);
168

169
  ret = gst_audio_encoder_finish_frame (audioenc, outbuf, -1);
170 171 172 173

done:

  return ret;
174 175 176

not_negotiated:
  {
177
    GST_DEBUG_OBJECT (mulawenc, "no format negotiated");
178
    ret = GST_FLOW_NOT_NEGOTIATED;
179 180
    goto done;
  }
Andy Wingo's avatar
Andy Wingo committed
181
}
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209



static void
gst_mulawenc_class_init (GstMuLawEncClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstAudioEncoderClass *audio_encoder_class = GST_AUDIO_ENCODER_CLASS (klass);

  audio_encoder_class->start = GST_DEBUG_FUNCPTR (gst_mulawenc_start);
  audio_encoder_class->set_format = GST_DEBUG_FUNCPTR (gst_mulawenc_set_format);
  audio_encoder_class->handle_frame =
      GST_DEBUG_FUNCPTR (gst_mulawenc_handle_frame);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&mulaw_enc_src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&mulaw_enc_sink_factory));

  gst_element_class_set_static_metadata (element_class, "Mu Law audio encoder",
      "Codec/Encoder/Audio",
      "Convert 16bit PCM to 8bit mu law",
      "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
}

static void
gst_mulawenc_init (GstMuLawEnc * mulawenc)
{
210
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (mulawenc));
211
}