gstrtpspeexdepay.c 6.38 KB
Newer Older
1
/* GStreamer
Edgard Lima's avatar
Edgard Lima committed
2
 * Copyright (C) <2005> Edgard Lima <edgard.lima@gmail.com>
3 4 5 6 7 8 9 10 11
 *
 * 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
12 13 14 15
 * 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.
18 19 20 21 22 23 24
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <string.h>
25
#include <stdlib.h>
26
#include <gst/rtp/gstrtpbuffer.h>
27
#include <gst/audio/audio.h>
28

29
#include "gstrtpspeexdepay.h"
30
#include "gstrtputils.h"
31

32
/* RtpSPEEXDepay signals and args */
33 34 35 36 37 38 39 40
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
41
  PROP_0
42 43
};

44
static GstStaticPadTemplate gst_rtp_speex_depay_sink_template =
45 46 47 48 49 50
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "clock-rate =  (int) [6000, 48000], "
51
        "encoding-name = (string) \"SPEEX\"")
52
    /*  "encoding-params = (string) \"1\"" */
53 54
    );

55
static GstStaticPadTemplate gst_rtp_speex_depay_src_template =
56 57 58 59 60 61
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-speex")
    );

Wim Taymans's avatar
Wim Taymans committed
62
static GstBuffer *gst_rtp_speex_depay_process (GstRTPBaseDepayload * depayload,
63
    GstRTPBuffer * rtp);
Wim Taymans's avatar
Wim Taymans committed
64
static gboolean gst_rtp_speex_depay_setcaps (GstRTPBaseDepayload * depayload,
65 66
    GstCaps * caps);

Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
67
G_DEFINE_TYPE (GstRtpSPEEXDepay, gst_rtp_speex_depay,
Wim Taymans's avatar
Wim Taymans committed
68
    GST_TYPE_RTP_BASE_DEPAYLOAD);
69 70

static void
71
gst_rtp_speex_depay_class_init (GstRtpSPEEXDepayClass * klass)
72
{
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
73
  GstElementClass *gstelement_class;
Wim Taymans's avatar
Wim Taymans committed
74
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
75

Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
76
  gstelement_class = (GstElementClass *) klass;
Wim Taymans's avatar
Wim Taymans committed
77
  gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
78

79
  gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_speex_depay_process;
Wim Taymans's avatar
Wim Taymans committed
80
  gstrtpbasedepayload_class->set_caps = gst_rtp_speex_depay_setcaps;
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
81

82 83 84 85
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_speex_depay_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_speex_depay_sink_template);
86
  gst_element_class_set_static_metadata (gstelement_class,
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
87 88
      "RTP Speex depayloader", "Codec/Depayloader/Network/RTP",
      "Extracts Speex audio from RTP packets",
Edgard Lima's avatar
Edgard Lima committed
89
      "Edgard Lima <edgard.lima@gmail.com>");
90 91 92
}

static void
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
93
gst_rtp_speex_depay_init (GstRtpSPEEXDepay * rtpspeexdepay)
94 95 96
{
}

97 98
static gint
gst_rtp_speex_depay_get_mode (gint rate)
99
{
100 101 102 103 104 105 106
  if (rate > 25000)
    return 2;
  else if (rate > 12500)
    return 1;
  else
    return 0;
}
107

108 109 110 111 112 113
/* len 4 bytes LE,
 * vendor string (len bytes),
 * user_len 4 (0) bytes LE
 */
static const gchar gst_rtp_speex_comment[] =
    "\045\0\0\0Depayloaded with GStreamer speexdepay\0\0\0\0";
114

115
static gboolean
Wim Taymans's avatar
Wim Taymans committed
116
gst_rtp_speex_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
117 118 119 120 121
{
  GstStructure *structure;
  GstRtpSPEEXDepay *rtpspeexdepay;
  gint clock_rate, nb_channels;
  GstBuffer *buf;
Wim Taymans's avatar
Wim Taymans committed
122 123
  GstMapInfo map;
  guint8 *data;
124
  const gchar *params;
125 126
  GstCaps *srccaps;
  gboolean res;
127 128 129 130 131

  rtpspeexdepay = GST_RTP_SPEEX_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

132 133
  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    goto no_clockrate;
134 135 136 137 138 139 140 141 142 143
  depayload->clock_rate = clock_rate;

  if (!(params = gst_structure_get_string (structure, "encoding-params")))
    nb_channels = 1;
  else {
    nb_channels = atoi (params);
  }

  /* construct minimal header and comment packet for the decoder */
  buf = gst_buffer_new_and_alloc (80);
Wim Taymans's avatar
Wim Taymans committed
144 145
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  data = map.data;
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
  memcpy (data, "Speex   ", 8);
  data += 8;
  memcpy (data, "1.1.12", 7);
  data += 20;
  GST_WRITE_UINT32_LE (data, 1);        /* version */
  data += 4;
  GST_WRITE_UINT32_LE (data, 80);       /* header_size */
  data += 4;
  GST_WRITE_UINT32_LE (data, clock_rate);       /* rate */
  data += 4;
  GST_WRITE_UINT32_LE (data, gst_rtp_speex_depay_get_mode (clock_rate));        /* mode */
  data += 4;
  GST_WRITE_UINT32_LE (data, 4);        /* mode_bitstream_version */
  data += 4;
  GST_WRITE_UINT32_LE (data, nb_channels);      /* nb_channels */
  data += 4;
  GST_WRITE_UINT32_LE (data, -1);       /* bitrate */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0xa0);     /* frame_size */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* VBR */
  data += 4;
  GST_WRITE_UINT32_LE (data, 1);        /* frames_per_packet */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* extra_headers */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* reserved1 */
  data += 4;
  GST_WRITE_UINT32_LE (data, 0);        /* reserved2 */
Wim Taymans's avatar
Wim Taymans committed
175
  gst_buffer_unmap (buf, &map);
176

177
  srccaps = gst_caps_new_empty_simple ("audio/x-speex");
178 179 180
  res = gst_pad_set_caps (depayload->srcpad, srccaps);
  gst_caps_unref (srccaps);

Wim Taymans's avatar
Wim Taymans committed
181
  gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtpspeexdepay), buf);
182 183

  buf = gst_buffer_new_and_alloc (sizeof (gst_rtp_speex_comment));
Wim Taymans's avatar
Wim Taymans committed
184 185
  gst_buffer_fill (buf, 0, gst_rtp_speex_comment,
      sizeof (gst_rtp_speex_comment));
186

Wim Taymans's avatar
Wim Taymans committed
187
  gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtpspeexdepay), buf);
188

189 190 191 192 193 194 195 196
  return res;

  /* ERRORS */
no_clockrate:
  {
    GST_DEBUG_OBJECT (depayload, "no clock-rate specified");
    return FALSE;
  }
197 198 199
}

static GstBuffer *
200 201
gst_rtp_speex_depay_process (GstRTPBaseDepayload * depayload,
    GstRTPBuffer * rtp)
202 203 204
{
  GstBuffer *outbuf = NULL;

205
  GST_DEBUG ("process : got %" G_GSIZE_FORMAT " bytes, mark %d ts %u seqn %d",
206 207 208
      gst_buffer_get_size (rtp->buffer),
      gst_rtp_buffer_get_marker (rtp),
      gst_rtp_buffer_get_timestamp (rtp), gst_rtp_buffer_get_seq (rtp));
209

210
  /* nothing special to be done */
211
  outbuf = gst_rtp_buffer_get_payload_buffer (rtp);
212

213
  if (outbuf) {
214
    GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
215
    gst_rtp_drop_non_audio_meta (depayload, outbuf);
216
  }
217

218 219 220 221
  return outbuf;
}

gboolean
222
gst_rtp_speex_depay_plugin_init (GstPlugin * plugin)
223
{
224
  return gst_element_register (plugin, "rtpspeexdepay",
225
      GST_RANK_SECONDARY, GST_TYPE_RTP_SPEEX_DEPAY);
226
}