Merge commit 'f9207722ca8fd8dcc1e7215d8af85efe4debfdf4' into 0.11
[platform/upstream/gstreamer.git] / gst / rtp / gstrtpac3depay.c
1 /* GStreamer
2  * Copyright (C) <2007> 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 "gstrtpac3depay.h"
28
29 GST_DEBUG_CATEGORY_STATIC (rtpac3depay_debug);
30 #define GST_CAT_DEFAULT (rtpac3depay_debug)
31
32 static GstStaticPadTemplate gst_rtp_ac3_depay_src_template =
33 GST_STATIC_PAD_TEMPLATE ("src",
34     GST_PAD_SRC,
35     GST_PAD_ALWAYS,
36     GST_STATIC_CAPS ("audio/ac3")
37     );
38
39 static GstStaticPadTemplate gst_rtp_ac3_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) { 32000, 44100, 48000 }, "
47         "encoding-name = (string) \"AC3\"")
48     );
49
50 G_DEFINE_TYPE (GstRtpAC3Depay, gst_rtp_ac3_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);
51
52 static gboolean gst_rtp_ac3_depay_setcaps (GstRTPBaseDepayload * depayload,
53     GstCaps * caps);
54 static GstBuffer *gst_rtp_ac3_depay_process (GstRTPBaseDepayload * depayload,
55     GstBuffer * buf);
56
57 static void
58 gst_rtp_ac3_depay_class_init (GstRtpAC3DepayClass * klass)
59 {
60   GstElementClass *gstelement_class;
61   GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
62
63   gstelement_class = (GstElementClass *) klass;
64   gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
65
66   gst_element_class_add_pad_template (gstelement_class,
67       gst_static_pad_template_get (&gst_rtp_ac3_depay_src_template));
68   gst_element_class_add_pad_template (gstelement_class,
69       gst_static_pad_template_get (&gst_rtp_ac3_depay_sink_template));
70
71   gst_element_class_set_details_simple (gstelement_class, "RTP AC3 depayloader",
72       "Codec/Depayloader/Network/RTP",
73       "Extracts AC3 audio from RTP packets (RFC 4184)",
74       "Wim Taymans <wim.taymans@gmail.com>");
75
76   gstrtpbasedepayload_class->set_caps = gst_rtp_ac3_depay_setcaps;
77   gstrtpbasedepayload_class->process = gst_rtp_ac3_depay_process;
78
79   GST_DEBUG_CATEGORY_INIT (rtpac3depay_debug, "rtpac3depay", 0,
80       "AC3 Audio RTP Depayloader");
81 }
82
83 static void
84 gst_rtp_ac3_depay_init (GstRtpAC3Depay * rtpac3depay)
85 {
86   /* needed because of G_DEFINE_TYPE */
87 }
88
89 static gboolean
90 gst_rtp_ac3_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
91 {
92   GstStructure *structure;
93   gint clock_rate;
94   GstCaps *srccaps;
95   gboolean res;
96
97   structure = gst_caps_get_structure (caps, 0);
98
99   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
100     clock_rate = 90000;         /* default */
101   depayload->clock_rate = clock_rate;
102
103   srccaps = gst_caps_new_empty_simple ("audio/ac3");
104   res = gst_pad_set_caps (depayload->srcpad, srccaps);
105   gst_caps_unref (srccaps);
106
107   return res;
108 }
109
110 struct frmsize_s
111 {
112   guint16 bit_rate;
113   guint16 frm_size[3];
114 };
115
116 static const struct frmsize_s frmsizecod_tbl[] = {
117   {32, {64, 69, 96}},
118   {32, {64, 70, 96}},
119   {40, {80, 87, 120}},
120   {40, {80, 88, 120}},
121   {48, {96, 104, 144}},
122   {48, {96, 105, 144}},
123   {56, {112, 121, 168}},
124   {56, {112, 122, 168}},
125   {64, {128, 139, 192}},
126   {64, {128, 140, 192}},
127   {80, {160, 174, 240}},
128   {80, {160, 175, 240}},
129   {96, {192, 208, 288}},
130   {96, {192, 209, 288}},
131   {112, {224, 243, 336}},
132   {112, {224, 244, 336}},
133   {128, {256, 278, 384}},
134   {128, {256, 279, 384}},
135   {160, {320, 348, 480}},
136   {160, {320, 349, 480}},
137   {192, {384, 417, 576}},
138   {192, {384, 418, 576}},
139   {224, {448, 487, 672}},
140   {224, {448, 488, 672}},
141   {256, {512, 557, 768}},
142   {256, {512, 558, 768}},
143   {320, {640, 696, 960}},
144   {320, {640, 697, 960}},
145   {384, {768, 835, 1152}},
146   {384, {768, 836, 1152}},
147   {448, {896, 975, 1344}},
148   {448, {896, 976, 1344}},
149   {512, {1024, 1114, 1536}},
150   {512, {1024, 1115, 1536}},
151   {576, {1152, 1253, 1728}},
152   {576, {1152, 1254, 1728}},
153   {640, {1280, 1393, 1920}},
154   {640, {1280, 1394, 1920}}
155 };
156
157 static GstBuffer *
158 gst_rtp_ac3_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
159 {
160   GstRtpAC3Depay *rtpac3depay;
161   GstBuffer *outbuf;
162   GstRTPBuffer rtp = { NULL, };
163   guint8 *payload;
164   guint16 FT, NF;
165
166   rtpac3depay = GST_RTP_AC3_DEPAY (depayload);
167
168   gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
169
170   if (gst_rtp_buffer_get_payload_len (&rtp) < 2)
171     goto empty_packet;
172
173   payload = gst_rtp_buffer_get_payload (&rtp);
174
175   /* strip off header
176    *
177    *  0                   1
178    *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
179    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
180    * |    MBZ    | FT|       NF      |
181    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182    */
183   FT = payload[0] & 0x3;
184   NF = payload[1];
185
186   GST_DEBUG_OBJECT (rtpac3depay, "FT: %d, NF: %d", FT, NF);
187
188   /* We don't bother with fragmented packets yet */
189   outbuf = gst_rtp_buffer_get_payload_subbuffer (&rtp, 2, -1);
190
191   gst_rtp_buffer_unmap (&rtp);
192
193   if (outbuf)
194     GST_DEBUG_OBJECT (rtpac3depay, "pushing buffer of size %" G_GSIZE_FORMAT,
195         gst_buffer_get_size (outbuf));
196
197   return outbuf;
198
199   /* ERRORS */
200 empty_packet:
201   {
202     GST_ELEMENT_WARNING (rtpac3depay, STREAM, DECODE,
203         ("Empty Payload."), (NULL));
204     gst_rtp_buffer_unmap (&rtp);
205     return NULL;
206   }
207 }
208
209 gboolean
210 gst_rtp_ac3_depay_plugin_init (GstPlugin * plugin)
211 {
212   return gst_element_register (plugin, "rtpac3depay",
213       GST_RANK_SECONDARY, GST_TYPE_RTP_AC3_DEPAY);
214 }