webrtc/nice: support consent-freshness RFC7675
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / gst / rtp / gstrtpmp4gpay.c
1 /* GStreamer
2  * Copyright (C) <2006> 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 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <string.h>
25
26 #include <gst/base/gstbitreader.h>
27 #include <gst/rtp/gstrtpbuffer.h>
28
29 #include "gstrtpelements.h"
30 #include "gstrtpmp4gpay.h"
31 #include "gstrtputils.h"
32
33 GST_DEBUG_CATEGORY_STATIC (rtpmp4gpay_debug);
34 #define GST_CAT_DEFAULT (rtpmp4gpay_debug)
35
36 static GstStaticPadTemplate gst_rtp_mp4g_pay_sink_template =
37     GST_STATIC_PAD_TEMPLATE ("sink",
38     GST_PAD_SINK,
39     GST_PAD_ALWAYS,
40     GST_STATIC_CAPS ("video/mpeg,"
41         "mpegversion=(int) 4,"
42         "systemstream=(boolean)false;"
43         "audio/mpeg," "mpegversion=(int) 4, " "stream-format=(string) raw")
44     );
45
46 static GstStaticPadTemplate gst_rtp_mp4g_pay_src_template =
47 GST_STATIC_PAD_TEMPLATE ("src",
48     GST_PAD_SRC,
49     GST_PAD_ALWAYS,
50     GST_STATIC_CAPS ("application/x-rtp, "
51         "media = (string) { \"video\", \"audio\", \"application\" }, "
52         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
53         "clock-rate = (int) [1, MAX ], "
54         "encoding-name = (string) \"MPEG4-GENERIC\", "
55         /* required string params */
56         "streamtype = (string) { \"4\", \"5\" }, "      /* 4 = video, 5 = audio */
57         /* "profile-level-id = (string) [1,MAX], " */
58         /* "config = (string) [1,MAX]" */
59         "mode = (string) { \"generic\", \"CELP-cbr\", \"CELP-vbr\", \"AAC-lbr\", \"AAC-hbr\" } "
60         /* Optional general parameters */
61         /* "objecttype = (string) [1,MAX], " */
62         /* "constantsize = (string) [1,MAX], " *//* constant size of each AU */
63         /* "constantduration = (string) [1,MAX], " *//* constant duration of each AU */
64         /* "maxdisplacement = (string) [1,MAX], " */
65         /* "de-interleavebuffersize = (string) [1,MAX], " */
66         /* Optional configuration parameters */
67         /* "sizelength = (string) [1, 16], " *//* max 16 bits, should be enough... */
68         /* "indexlength = (string) [1, 8], " */
69         /* "indexdeltalength = (string) [1, 8], " */
70         /* "ctsdeltalength = (string) [1, 64], " */
71         /* "dtsdeltalength = (string) [1, 64], " */
72         /* "randomaccessindication = (string) {0, 1}, " */
73         /* "streamstateindication = (string) [0, 64], " */
74         /* "auxiliarydatasizelength = (string) [0, 64]" */ )
75     );
76
77
78 static void gst_rtp_mp4g_pay_finalize (GObject * object);
79
80 static GstStateChangeReturn gst_rtp_mp4g_pay_change_state (GstElement * element,
81     GstStateChange transition);
82
83 static gboolean gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload,
84     GstCaps * caps);
85 static GstFlowReturn gst_rtp_mp4g_pay_handle_buffer (GstRTPBasePayload *
86     payload, GstBuffer * buffer);
87 static gboolean gst_rtp_mp4g_pay_sink_event (GstRTPBasePayload * payload,
88     GstEvent * event);
89
90 #define gst_rtp_mp4g_pay_parent_class parent_class
91 G_DEFINE_TYPE (GstRtpMP4GPay, gst_rtp_mp4g_pay, GST_TYPE_RTP_BASE_PAYLOAD);
92 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (rtpmp4gpay, "rtpmp4gpay",
93     GST_RANK_SECONDARY, GST_TYPE_RTP_MP4G_PAY, rtp_element_init (plugin));
94
95 static void
96 gst_rtp_mp4g_pay_class_init (GstRtpMP4GPayClass * klass)
97 {
98   GObjectClass *gobject_class;
99   GstElementClass *gstelement_class;
100   GstRTPBasePayloadClass *gstrtpbasepayload_class;
101
102   gobject_class = (GObjectClass *) klass;
103   gstelement_class = (GstElementClass *) klass;
104   gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;
105
106   gobject_class->finalize = gst_rtp_mp4g_pay_finalize;
107
108   gstelement_class->change_state = gst_rtp_mp4g_pay_change_state;
109
110   gstrtpbasepayload_class->set_caps = gst_rtp_mp4g_pay_setcaps;
111   gstrtpbasepayload_class->handle_buffer = gst_rtp_mp4g_pay_handle_buffer;
112   gstrtpbasepayload_class->sink_event = gst_rtp_mp4g_pay_sink_event;
113
114   gst_element_class_add_static_pad_template (gstelement_class,
115       &gst_rtp_mp4g_pay_src_template);
116   gst_element_class_add_static_pad_template (gstelement_class,
117       &gst_rtp_mp4g_pay_sink_template);
118
119   gst_element_class_set_static_metadata (gstelement_class,
120       "RTP MPEG4 ES payloader",
121       "Codec/Payloader/Network/RTP",
122       "Payload MPEG4 elementary streams as RTP packets (RFC 3640)",
123       "Wim Taymans <wim.taymans@gmail.com>");
124
125   GST_DEBUG_CATEGORY_INIT (rtpmp4gpay_debug, "rtpmp4gpay", 0,
126       "MP4-generic RTP Payloader");
127 }
128
129 static void
130 gst_rtp_mp4g_pay_init (GstRtpMP4GPay * rtpmp4gpay)
131 {
132   rtpmp4gpay->adapter = gst_adapter_new ();
133 }
134
135 static void
136 gst_rtp_mp4g_pay_reset (GstRtpMP4GPay * rtpmp4gpay)
137 {
138   GST_DEBUG_OBJECT (rtpmp4gpay, "reset");
139
140   gst_adapter_clear (rtpmp4gpay->adapter);
141 }
142
143 static void
144 gst_rtp_mp4g_pay_cleanup (GstRtpMP4GPay * rtpmp4gpay)
145 {
146   gst_rtp_mp4g_pay_reset (rtpmp4gpay);
147
148   g_free (rtpmp4gpay->params);
149   rtpmp4gpay->params = NULL;
150
151   if (rtpmp4gpay->config)
152     gst_buffer_unref (rtpmp4gpay->config);
153   rtpmp4gpay->config = NULL;
154
155   g_free (rtpmp4gpay->profile);
156   rtpmp4gpay->profile = NULL;
157
158   rtpmp4gpay->streamtype = NULL;
159   rtpmp4gpay->mode = NULL;
160
161   rtpmp4gpay->frame_len = 0;
162 }
163
164 static void
165 gst_rtp_mp4g_pay_finalize (GObject * object)
166 {
167   GstRtpMP4GPay *rtpmp4gpay;
168
169   rtpmp4gpay = GST_RTP_MP4G_PAY (object);
170
171   gst_rtp_mp4g_pay_cleanup (rtpmp4gpay);
172
173   g_object_unref (rtpmp4gpay->adapter);
174   rtpmp4gpay->adapter = NULL;
175
176   G_OBJECT_CLASS (parent_class)->finalize (object);
177 }
178
179 static const unsigned int sampling_table[16] = {
180   96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
181   16000, 12000, 11025, 8000, 7350, 0, 0, 0
182 };
183
184 static gboolean
185 gst_rtp_mp4g_pay_parse_audio_config (GstRtpMP4GPay * rtpmp4gpay,
186     GstBuffer * buffer)
187 {
188   GstMapInfo map;
189   guint8 objectType = 0;
190   guint8 samplingIdx = 0;
191   guint8 channelCfg = 0;
192   GstBitReader br;
193
194   gst_buffer_map (buffer, &map, GST_MAP_READ);
195
196   gst_bit_reader_init (&br, map.data, map.size);
197
198   /* any object type is fine, we need to copy it to the profile-level-id field. */
199   if (!gst_bit_reader_get_bits_uint8 (&br, &objectType, 5))
200     goto too_short;
201   if (objectType == 0)
202     goto invalid_object;
203
204   if (!gst_bit_reader_get_bits_uint8 (&br, &samplingIdx, 4))
205     goto too_short;
206   /* only fixed values for now */
207   if (samplingIdx > 12 && samplingIdx != 15)
208     goto wrong_freq;
209
210   if (!gst_bit_reader_get_bits_uint8 (&br, &channelCfg, 4))
211     goto too_short;
212   if (channelCfg > 7)
213     goto wrong_channels;
214
215   /* rtp rate depends on sampling rate of the audio */
216   if (samplingIdx == 15) {
217     guint32 rate = 0;
218
219     /* index of 15 means we get the rate in the next 24 bits */
220     if (!gst_bit_reader_get_bits_uint32 (&br, &rate, 24))
221       goto too_short;
222
223     rtpmp4gpay->rate = rate;
224   } else {
225     /* else use the rate from the table */
226     rtpmp4gpay->rate = sampling_table[samplingIdx];
227   }
228
229   rtpmp4gpay->frame_len = 1024;
230
231   switch (objectType) {
232     case 1:
233     case 2:
234     case 3:
235     case 4:
236     case 6:
237     case 7:
238     {
239       guint8 frameLenFlag = 0;
240
241       if (gst_bit_reader_get_bits_uint8 (&br, &frameLenFlag, 1))
242         if (frameLenFlag)
243           rtpmp4gpay->frame_len = 960;
244
245       break;
246     }
247     default:
248       break;
249   }
250
251   /* extra rtp params contain the number of channels */
252   g_free (rtpmp4gpay->params);
253   rtpmp4gpay->params = g_strdup_printf ("%d", channelCfg);
254   /* audio stream type */
255   rtpmp4gpay->streamtype = "5";
256   /* mode only high bitrate for now */
257   rtpmp4gpay->mode = "AAC-hbr";
258   /* profile */
259   g_free (rtpmp4gpay->profile);
260   rtpmp4gpay->profile = g_strdup_printf ("%d", objectType);
261
262   GST_DEBUG_OBJECT (rtpmp4gpay,
263       "objectType: %d, samplingIdx: %d (%d), channelCfg: %d, frame_len %d",
264       objectType, samplingIdx, rtpmp4gpay->rate, channelCfg,
265       rtpmp4gpay->frame_len);
266
267   gst_buffer_unmap (buffer, &map);
268   return TRUE;
269
270   /* ERROR */
271 too_short:
272   {
273     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, FORMAT,
274         (NULL), ("config string too short"));
275     gst_buffer_unmap (buffer, &map);
276     return FALSE;
277   }
278 invalid_object:
279   {
280     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, FORMAT,
281         (NULL), ("invalid object type"));
282     gst_buffer_unmap (buffer, &map);
283     return FALSE;
284   }
285 wrong_freq:
286   {
287     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, NOT_IMPLEMENTED,
288         (NULL), ("unsupported frequency index %d", samplingIdx));
289     gst_buffer_unmap (buffer, &map);
290     return FALSE;
291   }
292 wrong_channels:
293   {
294     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, NOT_IMPLEMENTED,
295         (NULL), ("unsupported number of channels %d, must < 8", channelCfg));
296     gst_buffer_unmap (buffer, &map);
297     return FALSE;
298   }
299 }
300
301 #define VOS_STARTCODE                   0x000001B0
302
303 static gboolean
304 gst_rtp_mp4g_pay_parse_video_config (GstRtpMP4GPay * rtpmp4gpay,
305     GstBuffer * buffer)
306 {
307   GstMapInfo map;
308   guint32 code;
309
310   gst_buffer_map (buffer, &map, GST_MAP_READ);
311
312   if (map.size < 5)
313     goto too_short;
314
315   code = GST_READ_UINT32_BE (map.data);
316
317   g_free (rtpmp4gpay->profile);
318   if (code == VOS_STARTCODE) {
319     /* get profile */
320     rtpmp4gpay->profile = g_strdup_printf ("%d", (gint) map.data[4]);
321   } else {
322     GST_ELEMENT_WARNING (rtpmp4gpay, STREAM, FORMAT,
323         (NULL), ("profile not found in config string, assuming \'1\'"));
324     rtpmp4gpay->profile = g_strdup ("1");
325   }
326
327   /* fixed rate */
328   rtpmp4gpay->rate = 90000;
329   /* video stream type */
330   rtpmp4gpay->streamtype = "4";
331   /* no params for video */
332   rtpmp4gpay->params = NULL;
333   /* mode */
334   rtpmp4gpay->mode = "generic";
335
336   GST_LOG_OBJECT (rtpmp4gpay, "profile %s", rtpmp4gpay->profile);
337
338   gst_buffer_unmap (buffer, &map);
339
340   return TRUE;
341
342   /* ERROR */
343 too_short:
344   {
345     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, FORMAT,
346         (NULL), ("config string too short"));
347     gst_buffer_unmap (buffer, &map);
348     return FALSE;
349   }
350 }
351
352 static gboolean
353 gst_rtp_mp4g_pay_new_caps (GstRtpMP4GPay * rtpmp4gpay)
354 {
355   gchar *config;
356   GValue v = { 0 };
357   gboolean res;
358
359 #define MP4GCAPS                                                \
360   "streamtype", G_TYPE_STRING, rtpmp4gpay->streamtype,          \
361   "profile-level-id", G_TYPE_STRING, rtpmp4gpay->profile,       \
362   "mode", G_TYPE_STRING, rtpmp4gpay->mode,                      \
363   "config", G_TYPE_STRING, config,                              \
364   "sizelength", G_TYPE_STRING, "13",                            \
365   "indexlength", G_TYPE_STRING, "3",                            \
366   "indexdeltalength", G_TYPE_STRING, "3",                       \
367   NULL
368
369   g_value_init (&v, GST_TYPE_BUFFER);
370   gst_value_set_buffer (&v, rtpmp4gpay->config);
371   config = gst_value_serialize (&v);
372
373   /* hmm, silly */
374   if (rtpmp4gpay->params) {
375     res = gst_rtp_base_payload_set_outcaps (GST_RTP_BASE_PAYLOAD (rtpmp4gpay),
376         "encoding-params", G_TYPE_STRING, rtpmp4gpay->params, MP4GCAPS);
377   } else {
378     res = gst_rtp_base_payload_set_outcaps (GST_RTP_BASE_PAYLOAD (rtpmp4gpay),
379         MP4GCAPS);
380   }
381
382   g_value_unset (&v);
383   g_free (config);
384
385 #undef MP4GCAPS
386   return res;
387 }
388
389 static gboolean
390 gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
391 {
392   GstRtpMP4GPay *rtpmp4gpay;
393   GstStructure *structure;
394   const GValue *codec_data;
395   const gchar *media_type = NULL;
396   gboolean res;
397
398   rtpmp4gpay = GST_RTP_MP4G_PAY (payload);
399
400   structure = gst_caps_get_structure (caps, 0);
401
402   codec_data = gst_structure_get_value (structure, "codec_data");
403   if (codec_data) {
404     GST_LOG_OBJECT (rtpmp4gpay, "got codec_data");
405     if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) {
406       GstBuffer *buffer;
407       const gchar *name;
408
409       buffer = gst_value_get_buffer (codec_data);
410       GST_LOG_OBJECT (rtpmp4gpay, "configuring codec_data");
411
412       name = gst_structure_get_name (structure);
413
414       /* parse buffer */
415       if (!strcmp (name, "audio/mpeg")) {
416         res = gst_rtp_mp4g_pay_parse_audio_config (rtpmp4gpay, buffer);
417         media_type = "audio";
418       } else if (!strcmp (name, "video/mpeg")) {
419         res = gst_rtp_mp4g_pay_parse_video_config (rtpmp4gpay, buffer);
420         media_type = "video";
421       } else {
422         res = FALSE;
423       }
424       if (!res)
425         goto config_failed;
426
427       /* now we can configure the buffer */
428       if (rtpmp4gpay->config)
429         gst_buffer_unref (rtpmp4gpay->config);
430
431       rtpmp4gpay->config = gst_buffer_copy (buffer);
432     }
433   }
434   if (media_type == NULL)
435     goto config_failed;
436
437   gst_rtp_base_payload_set_options (payload, media_type, TRUE, "MPEG4-GENERIC",
438       rtpmp4gpay->rate);
439
440   res = gst_rtp_mp4g_pay_new_caps (rtpmp4gpay);
441
442   return res;
443
444   /* ERRORS */
445 config_failed:
446   {
447     GST_DEBUG_OBJECT (rtpmp4gpay, "failed to parse config");
448     return FALSE;
449   }
450 }
451
452 static GstFlowReturn
453 gst_rtp_mp4g_pay_flush (GstRtpMP4GPay * rtpmp4gpay)
454 {
455   guint avail, total;
456   GstBuffer *outbuf;
457   GstFlowReturn ret;
458   guint mtu;
459
460   /* the data available in the adapter is either smaller
461    * than the MTU or bigger. In the case it is smaller, the complete
462    * adapter contents can be put in one packet. In the case the
463    * adapter has more than one MTU, we need to fragment the MPEG data
464    * over multiple packets. */
465   total = avail = gst_adapter_available (rtpmp4gpay->adapter);
466
467   ret = GST_FLOW_OK;
468   mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpmp4gpay);
469
470   while (avail > 0) {
471     guint towrite;
472     guint8 *payload;
473     guint payload_len;
474     guint packet_len;
475     GstRTPBuffer rtp = { NULL };
476     GstBuffer *paybuf;
477
478     /* this will be the total length of the packet */
479     packet_len = gst_rtp_buffer_calc_packet_len (avail, 0, 0);
480
481     /* fill one MTU or all available bytes, we need 4 spare bytes for
482      * the AU header. */
483     towrite = MIN (packet_len, mtu - 4);
484
485     /* this is the payload length */
486     payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
487
488     GST_DEBUG_OBJECT (rtpmp4gpay,
489         "avail %d, towrite %d, packet_len %d, payload_len %d", avail, towrite,
490         packet_len, payload_len);
491
492     /* create buffer to hold the payload, also make room for the 4 header bytes. */
493     outbuf =
494         gst_rtp_base_payload_allocate_output_buffer (GST_RTP_BASE_PAYLOAD
495         (rtpmp4gpay), 4, 0, 0);
496     gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
497
498     /* copy payload */
499     payload = gst_rtp_buffer_get_payload (&rtp);
500
501     /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
502      * |AU-headers-length|AU-header|AU-header|      |AU-header|padding|
503      * |                 |   (1)   |   (2)   |      |   (n)   | bits  |
504      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
505      */
506     /* AU-headers-length, we only have 1 AU-header */
507     payload[0] = 0x00;
508     payload[1] = 0x10;          /* we use 16 bits for the header */
509
510     /* +---------------------------------------+
511      * |     AU-size                           |
512      * +---------------------------------------+
513      * |     AU-Index / AU-Index-delta         |
514      * +---------------------------------------+
515      * |     CTS-flag                          |
516      * +---------------------------------------+
517      * |     CTS-delta                         |
518      * +---------------------------------------+
519      * |     DTS-flag                          |
520      * +---------------------------------------+
521      * |     DTS-delta                         |
522      * +---------------------------------------+
523      * |     RAP-flag                          |
524      * +---------------------------------------+
525      * |     Stream-state                      |
526      * +---------------------------------------+
527      */
528     /* The AU-header, no CTS, DTS, RAP, Stream-state 
529      *
530      * AU-size is always the total size of the AU, not the fragmented size 
531      */
532     payload[2] = (total & 0x1fe0) >> 5;
533     payload[3] = (total & 0x1f) << 3;   /* we use 13 bits for the size, 3 bits index */
534
535     /* marker only if the packet is complete */
536     gst_rtp_buffer_set_marker (&rtp, avail <= payload_len);
537     if (avail <= payload_len)
538       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_MARKER);
539
540     gst_rtp_buffer_unmap (&rtp);
541
542     paybuf = gst_adapter_take_buffer_fast (rtpmp4gpay->adapter, payload_len);
543     gst_rtp_copy_meta (GST_ELEMENT_CAST (rtpmp4gpay), outbuf, paybuf, 0);
544     outbuf = gst_buffer_append (outbuf, paybuf);
545
546     GST_BUFFER_PTS (outbuf) = rtpmp4gpay->first_timestamp;
547     GST_BUFFER_DURATION (outbuf) = rtpmp4gpay->first_duration;
548
549     GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
550
551     if (rtpmp4gpay->discont) {
552       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
553       /* Only the first outputted buffer has the DISCONT flag */
554       rtpmp4gpay->discont = FALSE;
555     }
556
557     ret = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtpmp4gpay), outbuf);
558
559     avail -= payload_len;
560   }
561
562   return ret;
563 }
564
565 /* we expect buffers as exactly one complete AU
566  */
567 static GstFlowReturn
568 gst_rtp_mp4g_pay_handle_buffer (GstRTPBasePayload * basepayload,
569     GstBuffer * buffer)
570 {
571   GstRtpMP4GPay *rtpmp4gpay;
572
573   rtpmp4gpay = GST_RTP_MP4G_PAY (basepayload);
574
575   rtpmp4gpay->first_timestamp = GST_BUFFER_PTS (buffer);
576   rtpmp4gpay->first_duration = GST_BUFFER_DURATION (buffer);
577   rtpmp4gpay->discont = GST_BUFFER_IS_DISCONT (buffer);
578
579   /* we always encode and flush a full AU */
580   gst_adapter_push (rtpmp4gpay->adapter, buffer);
581
582   return gst_rtp_mp4g_pay_flush (rtpmp4gpay);
583 }
584
585 static gboolean
586 gst_rtp_mp4g_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
587 {
588   GstRtpMP4GPay *rtpmp4gpay;
589
590   rtpmp4gpay = GST_RTP_MP4G_PAY (payload);
591
592   GST_DEBUG ("Got event: %s", GST_EVENT_TYPE_NAME (event));
593
594   switch (GST_EVENT_TYPE (event)) {
595     case GST_EVENT_SEGMENT:
596     case GST_EVENT_EOS:
597       /* This flush call makes sure that the last buffer is always pushed
598        * to the base payloader */
599       gst_rtp_mp4g_pay_flush (rtpmp4gpay);
600       break;
601     case GST_EVENT_FLUSH_STOP:
602       gst_rtp_mp4g_pay_reset (rtpmp4gpay);
603       break;
604     default:
605       break;
606   }
607
608   /* let parent handle event too */
609   return GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);
610 }
611
612 static GstStateChangeReturn
613 gst_rtp_mp4g_pay_change_state (GstElement * element, GstStateChange transition)
614 {
615   GstStateChangeReturn ret;
616   GstRtpMP4GPay *rtpmp4gpay;
617
618   rtpmp4gpay = GST_RTP_MP4G_PAY (element);
619
620   switch (transition) {
621     case GST_STATE_CHANGE_READY_TO_PAUSED:
622       gst_rtp_mp4g_pay_cleanup (rtpmp4gpay);
623       break;
624     default:
625       break;
626   }
627
628   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
629
630   switch (transition) {
631     case GST_STATE_CHANGE_PAUSED_TO_READY:
632       gst_rtp_mp4g_pay_cleanup (rtpmp4gpay);
633       break;
634     default:
635       break;
636   }
637
638   return ret;
639 }