webrtc/nice: support consent-freshness RFC7675
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / gst / rtp / gstrtpac3pay.c
1 /* GStreamer
2  * Copyright (C) <2010> 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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * SECTION:element-rtpac3pay
22  * @title: rtpac3pay
23  * @see_also: rtpac3depay
24  *
25  * Payload AC3 audio into RTP packets according to RFC 4184.
26  * For detailed information see: http://www.rfc-editor.org/rfc/rfc4184.txt
27  *
28  * ## Example pipeline
29  * |[
30  * gst-launch-1.0 -v audiotestsrc ! avenc_ac3 ! rtpac3pay ! udpsink
31  * ]| This example pipeline will encode and payload AC3 stream. Refer to
32  * the rtpac3depay example to depayload and decode the RTP stream.
33  *
34  */
35
36 #ifdef HAVE_CONFIG_H
37 #  include "config.h"
38 #endif
39
40 #include <string.h>
41
42 #include <gst/rtp/gstrtpbuffer.h>
43 #include <gst/audio/audio.h>
44
45 #include "gstrtpelements.h"
46 #include "gstrtpac3pay.h"
47 #include "gstrtputils.h"
48
49 GST_DEBUG_CATEGORY_STATIC (rtpac3pay_debug);
50 #define GST_CAT_DEFAULT (rtpac3pay_debug)
51
52 static GstStaticPadTemplate gst_rtp_ac3_pay_sink_template =
53     GST_STATIC_PAD_TEMPLATE ("sink",
54     GST_PAD_SINK,
55     GST_PAD_ALWAYS,
56     GST_STATIC_CAPS ("audio/ac3; " "audio/x-ac3; ")
57     );
58
59 static GstStaticPadTemplate gst_rtp_ac3_pay_src_template =
60 GST_STATIC_PAD_TEMPLATE ("src",
61     GST_PAD_SRC,
62     GST_PAD_ALWAYS,
63     GST_STATIC_CAPS ("application/x-rtp, "
64         "media = (string) \"audio\", "
65         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
66         "clock-rate = (int) { 32000, 44100, 48000 }, "
67         "encoding-name = (string) \"AC3\"")
68     );
69
70 static void gst_rtp_ac3_pay_finalize (GObject * object);
71
72 static GstStateChangeReturn gst_rtp_ac3_pay_change_state (GstElement * element,
73     GstStateChange transition);
74
75 static gboolean gst_rtp_ac3_pay_setcaps (GstRTPBasePayload * payload,
76     GstCaps * caps);
77 static gboolean gst_rtp_ac3_pay_sink_event (GstRTPBasePayload * payload,
78     GstEvent * event);
79 static GstFlowReturn gst_rtp_ac3_pay_flush (GstRtpAC3Pay * rtpac3pay);
80 static GstFlowReturn gst_rtp_ac3_pay_handle_buffer (GstRTPBasePayload * payload,
81     GstBuffer * buffer);
82
83 #define gst_rtp_ac3_pay_parent_class parent_class
84 G_DEFINE_TYPE (GstRtpAC3Pay, gst_rtp_ac3_pay, GST_TYPE_RTP_BASE_PAYLOAD);
85 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (rtpac3pay, "rtpac3pay",
86     GST_RANK_SECONDARY, GST_TYPE_RTP_AC3_PAY, rtp_element_init (plugin));
87
88 static void
89 gst_rtp_ac3_pay_class_init (GstRtpAC3PayClass * klass)
90 {
91   GObjectClass *gobject_class;
92   GstElementClass *gstelement_class;
93   GstRTPBasePayloadClass *gstrtpbasepayload_class;
94
95   GST_DEBUG_CATEGORY_INIT (rtpac3pay_debug, "rtpac3pay", 0,
96       "AC3 Audio RTP Depayloader");
97
98   gobject_class = (GObjectClass *) klass;
99   gstelement_class = (GstElementClass *) klass;
100   gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;
101
102   gobject_class->finalize = gst_rtp_ac3_pay_finalize;
103
104   gstelement_class->change_state = gst_rtp_ac3_pay_change_state;
105
106   gst_element_class_add_static_pad_template (gstelement_class,
107       &gst_rtp_ac3_pay_src_template);
108   gst_element_class_add_static_pad_template (gstelement_class,
109       &gst_rtp_ac3_pay_sink_template);
110
111   gst_element_class_set_static_metadata (gstelement_class,
112       "RTP AC3 audio payloader", "Codec/Payloader/Network/RTP",
113       "Payload AC3 audio as RTP packets (RFC 4184)",
114       "Wim Taymans <wim.taymans@gmail.com>");
115
116   gstrtpbasepayload_class->set_caps = gst_rtp_ac3_pay_setcaps;
117   gstrtpbasepayload_class->sink_event = gst_rtp_ac3_pay_sink_event;
118   gstrtpbasepayload_class->handle_buffer = gst_rtp_ac3_pay_handle_buffer;
119 }
120
121 static void
122 gst_rtp_ac3_pay_init (GstRtpAC3Pay * rtpac3pay)
123 {
124   rtpac3pay->adapter = gst_adapter_new ();
125 }
126
127 static void
128 gst_rtp_ac3_pay_finalize (GObject * object)
129 {
130   GstRtpAC3Pay *rtpac3pay;
131
132   rtpac3pay = GST_RTP_AC3_PAY (object);
133
134   g_object_unref (rtpac3pay->adapter);
135
136   G_OBJECT_CLASS (parent_class)->finalize (object);
137 }
138
139 static void
140 gst_rtp_ac3_pay_reset (GstRtpAC3Pay * pay)
141 {
142   pay->first_ts = -1;
143   pay->duration = 0;
144   gst_adapter_clear (pay->adapter);
145   GST_DEBUG_OBJECT (pay, "reset depayloader");
146 }
147
148 static gboolean
149 gst_rtp_ac3_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
150 {
151   gboolean res;
152   gint rate;
153   GstStructure *structure;
154
155   structure = gst_caps_get_structure (caps, 0);
156
157   if (!gst_structure_get_int (structure, "rate", &rate))
158     rate = 90000;               /* default */
159
160   gst_rtp_base_payload_set_options (payload, "audio", TRUE, "AC3", rate);
161   res = gst_rtp_base_payload_set_outcaps (payload, NULL);
162
163   return res;
164 }
165
166 static gboolean
167 gst_rtp_ac3_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
168 {
169   gboolean res;
170   GstRtpAC3Pay *rtpac3pay;
171
172   rtpac3pay = GST_RTP_AC3_PAY (payload);
173
174   switch (GST_EVENT_TYPE (event)) {
175     case GST_EVENT_EOS:
176       /* make sure we push the last packets in the adapter on EOS */
177       gst_rtp_ac3_pay_flush (rtpac3pay);
178       break;
179     case GST_EVENT_FLUSH_STOP:
180       gst_rtp_ac3_pay_reset (rtpac3pay);
181       break;
182     default:
183       break;
184   }
185
186   res = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);
187
188   return res;
189 }
190
191 struct frmsize_s
192 {
193   guint16 bit_rate;
194   guint16 frm_size[3];
195 };
196
197 static const struct frmsize_s frmsizecod_tbl[] = {
198   {32, {64, 69, 96}},
199   {32, {64, 70, 96}},
200   {40, {80, 87, 120}},
201   {40, {80, 88, 120}},
202   {48, {96, 104, 144}},
203   {48, {96, 105, 144}},
204   {56, {112, 121, 168}},
205   {56, {112, 122, 168}},
206   {64, {128, 139, 192}},
207   {64, {128, 140, 192}},
208   {80, {160, 174, 240}},
209   {80, {160, 175, 240}},
210   {96, {192, 208, 288}},
211   {96, {192, 209, 288}},
212   {112, {224, 243, 336}},
213   {112, {224, 244, 336}},
214   {128, {256, 278, 384}},
215   {128, {256, 279, 384}},
216   {160, {320, 348, 480}},
217   {160, {320, 349, 480}},
218   {192, {384, 417, 576}},
219   {192, {384, 418, 576}},
220   {224, {448, 487, 672}},
221   {224, {448, 488, 672}},
222   {256, {512, 557, 768}},
223   {256, {512, 558, 768}},
224   {320, {640, 696, 960}},
225   {320, {640, 697, 960}},
226   {384, {768, 835, 1152}},
227   {384, {768, 836, 1152}},
228   {448, {896, 975, 1344}},
229   {448, {896, 976, 1344}},
230   {512, {1024, 1114, 1536}},
231   {512, {1024, 1115, 1536}},
232   {576, {1152, 1253, 1728}},
233   {576, {1152, 1254, 1728}},
234   {640, {1280, 1393, 1920}},
235   {640, {1280, 1394, 1920}}
236 };
237
238 static GstFlowReturn
239 gst_rtp_ac3_pay_flush (GstRtpAC3Pay * rtpac3pay)
240 {
241   guint avail, FT, NF, mtu;
242   GstBuffer *outbuf;
243   GstFlowReturn ret;
244
245   /* the data available in the adapter is either smaller
246    * than the MTU or bigger. In the case it is smaller, the complete
247    * adapter contents can be put in one packet. In the case the
248    * adapter has more than one MTU, we need to split the AC3 data
249    * over multiple packets. */
250   avail = gst_adapter_available (rtpac3pay->adapter);
251
252   ret = GST_FLOW_OK;
253
254   FT = 0;
255   /* number of frames */
256   NF = rtpac3pay->NF;
257
258   mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpac3pay);
259
260   GST_LOG_OBJECT (rtpac3pay, "flushing %u bytes", avail);
261
262   while (avail > 0) {
263     guint towrite;
264     guint8 *payload;
265     guint payload_len;
266     guint packet_len;
267     GstRTPBuffer rtp = { NULL, };
268     GstBuffer *payload_buffer;
269
270     /* this will be the total length of the packet */
271     packet_len = gst_rtp_buffer_calc_packet_len (2 + avail, 0, 0);
272
273     /* fill one MTU or all available bytes */
274     towrite = MIN (packet_len, mtu);
275
276     /* this is the payload length */
277     payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
278
279     /* create buffer to hold the payload */
280     outbuf =
281         gst_rtp_base_payload_allocate_output_buffer (GST_RTP_BASE_PAYLOAD
282         (rtpac3pay), 2, 0, 0);
283
284     if (FT == 0) {
285       /* check if it all fits */
286       if (towrite < packet_len) {
287         guint maxlen;
288
289         GST_LOG_OBJECT (rtpac3pay, "we need to fragment");
290         /* check if we will be able to put at least 5/8th of the total
291          * frame in this first frame. */
292         if ((avail * 5) / 8 >= (payload_len - 2))
293           FT = 1;
294         else
295           FT = 2;
296         /* check how many fragments we will need */
297         maxlen = gst_rtp_buffer_calc_payload_len (mtu - 2, 0, 0);
298         NF = (avail + maxlen - 1) / maxlen;
299       }
300     } else if (FT != 3) {
301       /* remaining fragment */
302       FT = 3;
303     }
304
305     /*
306      *  0                   1
307      *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
308      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
309      * |    MBZ    | FT|       NF      |
310      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
311      *
312      * FT: 0: one or more complete frames
313      *     1: initial 5/8 fragment
314      *     2: initial fragment not 5/8
315      *     3: other fragment
316      * NF: amount of frames if FT = 0, else number of fragments.
317      */
318     gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
319     GST_LOG_OBJECT (rtpac3pay, "FT %u, NF %u", FT, NF);
320     payload = gst_rtp_buffer_get_payload (&rtp);
321     payload[0] = (FT & 3);
322     payload[1] = NF;
323     payload_len -= 2;
324
325     if (avail == payload_len) {
326       gst_rtp_buffer_set_marker (&rtp, TRUE);
327       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_MARKER);
328     }
329     gst_rtp_buffer_unmap (&rtp);
330
331     payload_buffer =
332         gst_adapter_take_buffer_fast (rtpac3pay->adapter, payload_len);
333
334     gst_rtp_copy_audio_meta (rtpac3pay, outbuf, payload_buffer);
335
336     outbuf = gst_buffer_append (outbuf, payload_buffer);
337
338     avail -= payload_len;
339
340     GST_BUFFER_PTS (outbuf) = rtpac3pay->first_ts;
341     GST_BUFFER_DURATION (outbuf) = rtpac3pay->duration;
342
343     ret = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtpac3pay), outbuf);
344   }
345
346   return ret;
347 }
348
349 static GstFlowReturn
350 gst_rtp_ac3_pay_handle_buffer (GstRTPBasePayload * basepayload,
351     GstBuffer * buffer)
352 {
353   GstRtpAC3Pay *rtpac3pay;
354   GstFlowReturn ret;
355   gsize avail, left, NF;
356   GstMapInfo map;
357   guint8 *p;
358   guint packet_len;
359   GstClockTime duration, timestamp;
360
361   rtpac3pay = GST_RTP_AC3_PAY (basepayload);
362
363   gst_buffer_map (buffer, &map, GST_MAP_READ);
364   duration = GST_BUFFER_DURATION (buffer);
365   timestamp = GST_BUFFER_PTS (buffer);
366
367   if (GST_BUFFER_IS_DISCONT (buffer)) {
368     GST_DEBUG_OBJECT (rtpac3pay, "DISCONT");
369     gst_rtp_ac3_pay_reset (rtpac3pay);
370   }
371
372   /* count the amount of incoming packets */
373   NF = 0;
374   left = map.size;
375   p = map.data;
376   while (TRUE) {
377     guint bsid, fscod, frmsizecod, frame_size;
378
379     if (left < 6)
380       break;
381
382     if (p[0] != 0x0b || p[1] != 0x77)
383       break;
384
385     bsid = p[5] >> 3;
386     if (bsid > 8)
387       break;
388
389     frmsizecod = p[4] & 0x3f;
390     fscod = p[4] >> 6;
391
392     GST_DEBUG_OBJECT (rtpac3pay, "fscod %u, %u", fscod, frmsizecod);
393
394     if (fscod >= 3 || frmsizecod >= 38)
395       break;
396
397     frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] * 2;
398     if (frame_size > left)
399       break;
400
401     NF++;
402     GST_DEBUG_OBJECT (rtpac3pay, "found frame %" G_GSIZE_FORMAT " of size %u",
403         NF, frame_size);
404
405     p += frame_size;
406     left -= frame_size;
407   }
408   gst_buffer_unmap (buffer, &map);
409   if (NF == 0)
410     goto no_frames;
411
412   avail = gst_adapter_available (rtpac3pay->adapter);
413
414   /* get packet length of previous data and this new data,
415    * payload length includes a 4 byte header */
416   packet_len = gst_rtp_buffer_calc_packet_len (2 + avail + map.size, 0, 0);
417
418   /* if this buffer is going to overflow the packet, flush what we
419    * have. */
420   if (gst_rtp_base_payload_is_filled (basepayload,
421           packet_len, rtpac3pay->duration + duration)) {
422     ret = gst_rtp_ac3_pay_flush (rtpac3pay);
423     avail = 0;
424   } else {
425     ret = GST_FLOW_OK;
426   }
427
428   if (avail == 0) {
429     GST_DEBUG_OBJECT (rtpac3pay,
430         "first packet, save timestamp %" GST_TIME_FORMAT,
431         GST_TIME_ARGS (timestamp));
432     rtpac3pay->first_ts = timestamp;
433     rtpac3pay->duration = 0;
434     rtpac3pay->NF = 0;
435   }
436
437   gst_adapter_push (rtpac3pay->adapter, buffer);
438   rtpac3pay->duration += duration;
439   rtpac3pay->NF += NF;
440
441   return ret;
442
443   /* ERRORS */
444 no_frames:
445   {
446     GST_WARNING_OBJECT (rtpac3pay, "no valid AC3 frames found");
447     return GST_FLOW_OK;
448   }
449 }
450
451 static GstStateChangeReturn
452 gst_rtp_ac3_pay_change_state (GstElement * element, GstStateChange transition)
453 {
454   GstRtpAC3Pay *rtpac3pay;
455   GstStateChangeReturn ret;
456
457   rtpac3pay = GST_RTP_AC3_PAY (element);
458
459   switch (transition) {
460     case GST_STATE_CHANGE_READY_TO_PAUSED:
461       gst_rtp_ac3_pay_reset (rtpac3pay);
462       break;
463     default:
464       break;
465   }
466
467   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
468
469   switch (transition) {
470     case GST_STATE_CHANGE_PAUSED_TO_READY:
471       gst_rtp_ac3_pay_reset (rtpac3pay);
472       break;
473     default:
474       break;
475   }
476   return ret;
477 }