Tizen 2.0 Release
[framework/multimedia/gst-plugins-good0.10.git] / gst / rtp / gstrtpmpadepay.c
1 /* GStreamer
2  * Copyright (C) <2005> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <gst/rtp/gstrtpbuffer.h>
25
26 #include <string.h>
27 #include "gstrtpmpadepay.h"
28
29 GST_DEBUG_CATEGORY_STATIC (rtpmpadepay_debug);
30 #define GST_CAT_DEFAULT (rtpmpadepay_debug)
31
32 static GstStaticPadTemplate gst_rtp_mpa_depay_src_template =
33 GST_STATIC_PAD_TEMPLATE ("src",
34     GST_PAD_SRC,
35     GST_PAD_ALWAYS,
36     GST_STATIC_CAPS ("audio/mpeg, " "mpegversion = (int) 1")
37     );
38
39 static GstStaticPadTemplate gst_rtp_mpa_depay_sink_template =
40     GST_STATIC_PAD_TEMPLATE ("sink",
41     GST_PAD_SINK,
42     GST_PAD_ALWAYS,
43     GST_STATIC_CAPS ("application/x-rtp, "
44         "media = (string) \"audio\", "
45         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
46         "clock-rate = (int) 90000, " "encoding-name = (string) \"MPA\";"
47         "application/x-rtp, "
48         "media = (string) \"audio\", "
49         "payload = (int) " GST_RTP_PAYLOAD_MPA_STRING ", "
50         "clock-rate = (int) 90000")
51     );
52
53 GST_BOILERPLATE (GstRtpMPADepay, gst_rtp_mpa_depay, GstBaseRTPDepayload,
54     GST_TYPE_BASE_RTP_DEPAYLOAD);
55
56 static gboolean gst_rtp_mpa_depay_setcaps (GstBaseRTPDepayload * depayload,
57     GstCaps * caps);
58 static GstBuffer *gst_rtp_mpa_depay_process (GstBaseRTPDepayload * depayload,
59     GstBuffer * buf);
60
61 static void
62 gst_rtp_mpa_depay_base_init (gpointer klass)
63 {
64   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
65
66   gst_element_class_add_static_pad_template (element_class,
67       &gst_rtp_mpa_depay_src_template);
68   gst_element_class_add_static_pad_template (element_class,
69       &gst_rtp_mpa_depay_sink_template);
70
71   gst_element_class_set_details_simple (element_class,
72       "RTP MPEG audio depayloader", "Codec/Depayloader/Network/RTP",
73       "Extracts MPEG audio from RTP packets (RFC 2038)",
74       "Wim Taymans <wim.taymans@gmail.com>");
75 }
76
77 static void
78 gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass)
79 {
80   GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
81
82   gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
83
84   gstbasertpdepayload_class->set_caps = gst_rtp_mpa_depay_setcaps;
85   gstbasertpdepayload_class->process = gst_rtp_mpa_depay_process;
86
87   GST_DEBUG_CATEGORY_INIT (rtpmpadepay_debug, "rtpmpadepay", 0,
88       "MPEG Audio RTP Depayloader");
89 }
90
91 static void
92 gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay,
93     GstRtpMPADepayClass * klass)
94 {
95   /* needed because of GST_BOILERPLATE */
96 }
97
98 static gboolean
99 gst_rtp_mpa_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
100 {
101   GstStructure *structure;
102   GstCaps *outcaps;
103   gint clock_rate;
104   gboolean res;
105
106   structure = gst_caps_get_structure (caps, 0);
107
108   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
109     clock_rate = 90000;
110   depayload->clock_rate = clock_rate;
111
112   outcaps =
113       gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, NULL);
114   res = gst_pad_set_caps (depayload->srcpad, outcaps);
115   gst_caps_unref (outcaps);
116
117   return res;
118 }
119
120 static GstBuffer *
121 gst_rtp_mpa_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
122 {
123   GstRtpMPADepay *rtpmpadepay;
124   GstBuffer *outbuf;
125
126   rtpmpadepay = GST_RTP_MPA_DEPAY (depayload);
127
128   {
129     gint payload_len;
130     gboolean marker;
131
132     payload_len = gst_rtp_buffer_get_payload_len (buf);
133
134     if (payload_len <= 4)
135       goto empty_packet;
136
137     /* strip off header
138      *
139      *  0                   1                   2                   3
140      *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
141      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142      * |             MBZ               |          Frag_offset          |
143      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144      */
145     /* frag_offset = (payload[2] << 8) | payload[3]; */
146
147     /* subbuffer skipping the 4 header bytes */
148     outbuf = gst_rtp_buffer_get_payload_subbuffer (buf, 4, -1);
149     marker = gst_rtp_buffer_get_marker (buf);
150
151     if (marker) {
152       /* mark start of talkspurt with discont */
153       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
154     }
155     GST_DEBUG_OBJECT (rtpmpadepay,
156         "gst_rtp_mpa_depay_chain: pushing buffer of size %d",
157         GST_BUFFER_SIZE (outbuf));
158
159     /* FIXME, we can push half mpeg frames when they are split over multiple
160      * RTP packets */
161     return outbuf;
162   }
163
164   return NULL;
165
166   /* ERRORS */
167 empty_packet:
168   {
169     GST_ELEMENT_WARNING (rtpmpadepay, STREAM, DECODE,
170         ("Empty Payload."), (NULL));
171     return NULL;
172   }
173 }
174
175 gboolean
176 gst_rtp_mpa_depay_plugin_init (GstPlugin * plugin)
177 {
178   return gst_element_register (plugin, "rtpmpadepay",
179       GST_RANK_SECONDARY, GST_TYPE_RTP_MPA_DEPAY);
180 }