gstrtpgsmpay.c 5.33 KB
Newer Older
Zeeshan Ali's avatar
Zeeshan Ali committed
1 2
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3
 * Copyright (C) <2005> Zeeshan Ali <zeenix@gmail.com>
Zeeshan Ali's avatar
Zeeshan Ali committed
4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 * 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
17 18
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
Zeeshan Ali's avatar
Zeeshan Ali committed
19 20
 */

21 22 23 24
#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

25
#include <stdlib.h>
Zeeshan Ali's avatar
Zeeshan Ali committed
26
#include <string.h>
27
#include <gst/rtp/gstrtpbuffer.h>
28
#include <gst/audio/audio.h>
29

30
#include "gstrtpgsmpay.h"
31
#include "gstrtputils.h"
Zeeshan Ali's avatar
Zeeshan Ali committed
32

33 34 35
GST_DEBUG_CATEGORY_STATIC (rtpgsmpay_debug);
#define GST_CAT_DEFAULT (rtpgsmpay_debug)

36
static GstStaticPadTemplate gst_rtp_gsm_pay_sink_template =
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
37
GST_STATIC_PAD_TEMPLATE ("sink",
David Schleef's avatar
David Schleef committed
38 39
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
40
    GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
41
    );
David Schleef's avatar
David Schleef committed
42

43
static GstStaticPadTemplate gst_rtp_gsm_pay_src_template =
44
    GST_STATIC_PAD_TEMPLATE ("src",
David Schleef's avatar
David Schleef committed
45 46
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
47 48
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
49
        "payload = (int) " GST_RTP_PAYLOAD_GSM_STRING ", "
50 51 52 53
        "clock-rate = (int) 8000, " "encoding-name = (string) \"GSM\"; "
        "application/x-rtp, "
        "media = (string) \"audio\", "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
54
        "clock-rate = (int) 8000, " "encoding-name = (string) \"GSM\"")
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
55
    );
David Schleef's avatar
David Schleef committed
56

57
static gboolean gst_rtp_gsm_pay_setcaps (GstRTPBasePayload * payload,
58
    GstCaps * caps);
59
static GstFlowReturn gst_rtp_gsm_pay_handle_buffer (GstRTPBasePayload * payload,
60 61
    GstBuffer * buffer);

Wim Taymans's avatar
Wim Taymans committed
62
#define gst_rtp_gsm_pay_parent_class parent_class
63
G_DEFINE_TYPE (GstRTPGSMPay, gst_rtp_gsm_pay, GST_TYPE_RTP_BASE_PAYLOAD);
Zeeshan Ali's avatar
Zeeshan Ali committed
64

Ronald S. Bultje's avatar
Ronald S. Bultje committed
65
static void
Wim Taymans's avatar
Wim Taymans committed
66
gst_rtp_gsm_pay_class_init (GstRTPGSMPayClass * klass)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
67
{
Wim Taymans's avatar
Wim Taymans committed
68
  GstElementClass *gstelement_class;
69
  GstRTPBasePayloadClass *gstrtpbasepayload_class;
Wim Taymans's avatar
Wim Taymans committed
70 71 72

  GST_DEBUG_CATEGORY_INIT (rtpgsmpay_debug, "rtpgsmpay", 0,
      "GSM Audio RTP Payloader");
Ronald S. Bultje's avatar
Ronald S. Bultje committed
73

Wim Taymans's avatar
Wim Taymans committed
74
  gstelement_class = (GstElementClass *) klass;
75
  gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;
Wim Taymans's avatar
Wim Taymans committed
76

77 78 79 80
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_gsm_pay_sink_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_gsm_pay_src_template);
Wim Taymans's avatar
Wim Taymans committed
81

82
  gst_element_class_set_static_metadata (gstelement_class, "RTP GSM payloader",
83
      "Codec/Payloader/Network/RTP",
84 85
      "Payload-encodes GSM audio into a RTP packet",
      "Zeeshan Ali <zeenix@gmail.com>");
Zeeshan Ali's avatar
Zeeshan Ali committed
86

87 88
  gstrtpbasepayload_class->set_caps = gst_rtp_gsm_pay_setcaps;
  gstrtpbasepayload_class->handle_buffer = gst_rtp_gsm_pay_handle_buffer;
Zeeshan Ali's avatar
Zeeshan Ali committed
89 90 91
}

static void
Wim Taymans's avatar
Wim Taymans committed
92
gst_rtp_gsm_pay_init (GstRTPGSMPay * rtpgsmpay)
Zeeshan Ali's avatar
Zeeshan Ali committed
93
{
94 95
  GST_RTP_BASE_PAYLOAD (rtpgsmpay)->clock_rate = 8000;
  GST_RTP_BASE_PAYLOAD_PT (rtpgsmpay) = GST_RTP_PAYLOAD_GSM;
Zeeshan Ali's avatar
Zeeshan Ali committed
96 97
}

98
static gboolean
99
gst_rtp_gsm_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
Zeeshan Ali's avatar
Zeeshan Ali committed
100
{
101
  const char *stname;
David Schleef's avatar
David Schleef committed
102
  GstStructure *structure;
103
  gboolean res;
Zeeshan Ali's avatar
Zeeshan Ali committed
104

David Schleef's avatar
David Schleef committed
105 106
  structure = gst_caps_get_structure (caps, 0);

107 108
  stname = gst_structure_get_name (structure);

109 110 111
  if (strcmp ("audio/x-gsm", stname))
    goto invalid_type;

112 113
  gst_rtp_base_payload_set_options (payload, "audio",
      payload->pt != GST_RTP_PAYLOAD_GSM, "GSM", 8000);
114
  res = gst_rtp_base_payload_set_outcaps (payload, NULL);
Zeeshan Ali's avatar
Zeeshan Ali committed
115

116
  return res;
Zeeshan Ali's avatar
Zeeshan Ali committed
117

118 119 120 121 122 123
  /* ERRORS */
invalid_type:
  {
    GST_WARNING_OBJECT (payload, "invalid media type received");
    return FALSE;
  }
Zeeshan Ali's avatar
Zeeshan Ali committed
124 125
}

126
static GstFlowReturn
127
gst_rtp_gsm_pay_handle_buffer (GstRTPBasePayload * basepayload,
128
    GstBuffer * buffer)
Zeeshan Ali's avatar
Zeeshan Ali committed
129
{
130
  GstRTPGSMPay *rtpgsmpay;
Wim Taymans's avatar
Wim Taymans committed
131
  guint payload_len;
Zeeshan Ali's avatar
Zeeshan Ali committed
132
  GstBuffer *outbuf;
133
  GstClockTime timestamp, duration;
134
  GstFlowReturn ret;
Zeeshan Ali's avatar
Zeeshan Ali committed
135

136
  rtpgsmpay = GST_RTP_GSM_PAY (basepayload);
Zeeshan Ali's avatar
Zeeshan Ali committed
137

138
  timestamp = GST_BUFFER_PTS (buffer);
139
  duration = GST_BUFFER_DURATION (buffer);
Zeeshan Ali's avatar
Zeeshan Ali committed
140

141
  /* FIXME, only one GSM frame per RTP packet for now */
142
  payload_len = gst_buffer_get_size (buffer);
Zeeshan Ali's avatar
Zeeshan Ali committed
143

144
  /* FIXME, just error out for now */
145
  if (payload_len > GST_RTP_BASE_PAYLOAD_MTU (rtpgsmpay))
Wim Taymans's avatar
Wim Taymans committed
146
    goto too_big;
147

148
  outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
Zeeshan Ali's avatar
Zeeshan Ali committed
149

150
  /* copy timestamp and duration */
151
  GST_BUFFER_PTS (outbuf) = timestamp;
152
  GST_BUFFER_DURATION (outbuf) = duration;
Zeeshan Ali's avatar
Zeeshan Ali committed
153

154
  gst_rtp_copy_audio_meta (rtpgsmpay, outbuf, buffer);
155

156 157
  /* append payload */
  outbuf = gst_buffer_append (outbuf, buffer);
Zeeshan Ali's avatar
Zeeshan Ali committed
158

159
  GST_DEBUG ("gst_rtp_gsm_pay_chain: pushing buffer of size %" G_GSIZE_FORMAT,
Wim Taymans's avatar
Wim Taymans committed
160
      gst_buffer_get_size (outbuf));
Zeeshan Ali's avatar
Zeeshan Ali committed
161

162
  ret = gst_rtp_base_payload_push (basepayload, outbuf);
Zeeshan Ali's avatar
Zeeshan Ali committed
163

164
  return ret;
Wim Taymans's avatar
Wim Taymans committed
165 166 167 168 169 170

  /* ERRORS */
too_big:
  {
    GST_ELEMENT_ERROR (rtpgsmpay, STREAM, ENCODE, (NULL),
        ("payload_len %u > mtu %u", payload_len,
171
            GST_RTP_BASE_PAYLOAD_MTU (rtpgsmpay)));
Wim Taymans's avatar
Wim Taymans committed
172 173
    return GST_FLOW_ERROR;
  }
Zeeshan Ali's avatar
Zeeshan Ali committed
174 175 176
}

gboolean
177
gst_rtp_gsm_pay_plugin_init (GstPlugin * plugin)
Zeeshan Ali's avatar
Zeeshan Ali committed
178
{
179
  return gst_element_register (plugin, "rtpgsmpay",
180
      GST_RANK_SECONDARY, GST_TYPE_RTP_GSM_PAY);
Zeeshan Ali's avatar
Zeeshan Ali committed
181
}