rtp: Update codes based on 1.18.4
[platform/upstream/gst-plugins-good.git] / gst / rtp / gstrtpmp4gpay.c
index 1514911..532e2de 100644 (file)
@@ -13,8 +13,8 @@
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -27,6 +27,7 @@
 #include <gst/rtp/gstrtpbuffer.h>
 
 #include "gstrtpmp4gpay.h"
+#include "gstrtputils.h"
 
 GST_DEBUG_CATEGORY_STATIC (rtpmp4gpay_debug);
 #define GST_CAT_DEFAULT (rtpmp4gpay_debug)
@@ -78,40 +79,41 @@ static void gst_rtp_mp4g_pay_finalize (GObject * object);
 static GstStateChangeReturn gst_rtp_mp4g_pay_change_state (GstElement * element,
     GstStateChange transition);
 
-static gboolean gst_rtp_mp4g_pay_setcaps (GstBaseRTPPayload * payload,
+static gboolean gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload,
     GstCaps * caps);
-static GstFlowReturn gst_rtp_mp4g_pay_handle_buffer (GstBaseRTPPayload *
+static GstFlowReturn gst_rtp_mp4g_pay_handle_buffer (GstRTPBasePayload *
     payload, GstBuffer * buffer);
-static gboolean gst_rtp_mp4g_pay_handle_event (GstBaseRTPPayload * payload,
+static gboolean gst_rtp_mp4g_pay_sink_event (GstRTPBasePayload * payload,
     GstEvent * event);
 
 #define gst_rtp_mp4g_pay_parent_class parent_class
-G_DEFINE_TYPE (GstRtpMP4GPay, gst_rtp_mp4g_pay, GST_TYPE_BASE_RTP_PAYLOAD)
+G_DEFINE_TYPE (GstRtpMP4GPay, gst_rtp_mp4g_pay, GST_TYPE_RTP_BASE_PAYLOAD);
 
-     static void gst_rtp_mp4g_pay_class_init (GstRtpMP4GPayClass * klass)
+static void
+gst_rtp_mp4g_pay_class_init (GstRtpMP4GPayClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
-  GstBaseRTPPayloadClass *gstbasertppayload_class;
+  GstRTPBasePayloadClass *gstrtpbasepayload_class;
 
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
-  gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+  gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;
 
   gobject_class->finalize = gst_rtp_mp4g_pay_finalize;
 
   gstelement_class->change_state = gst_rtp_mp4g_pay_change_state;
 
-  gstbasertppayload_class->set_caps = gst_rtp_mp4g_pay_setcaps;
-  gstbasertppayload_class->handle_buffer = gst_rtp_mp4g_pay_handle_buffer;
-  gstbasertppayload_class->handle_event = gst_rtp_mp4g_pay_handle_event;
+  gstrtpbasepayload_class->set_caps = gst_rtp_mp4g_pay_setcaps;
+  gstrtpbasepayload_class->handle_buffer = gst_rtp_mp4g_pay_handle_buffer;
+  gstrtpbasepayload_class->sink_event = gst_rtp_mp4g_pay_sink_event;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_mp4g_pay_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_mp4g_pay_sink_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_mp4g_pay_src_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_mp4g_pay_sink_template);
 
-  gst_element_class_set_details_simple (gstelement_class,
+  gst_element_class_set_static_metadata (gstelement_class,
       "RTP MPEG4 ES payloader",
       "Codec/Payloader/Network/RTP",
       "Payload MPEG4 elementary streams as RTP packets (RFC 3640)",
@@ -133,7 +135,6 @@ gst_rtp_mp4g_pay_reset (GstRtpMP4GPay * rtpmp4gpay)
   GST_DEBUG_OBJECT (rtpmp4gpay, "reset");
 
   gst_adapter_clear (rtpmp4gpay->adapter);
-  rtpmp4gpay->offset = 0;
 }
 
 static void
@@ -181,16 +182,15 @@ static gboolean
 gst_rtp_mp4g_pay_parse_audio_config (GstRtpMP4GPay * rtpmp4gpay,
     GstBuffer * buffer)
 {
-  guint8 *data;
-  gsize size;
+  GstMapInfo map;
   guint8 objectType = 0;
   guint8 samplingIdx = 0;
   guint8 channelCfg = 0;
   GstBitReader br;
 
-  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
 
-  gst_bit_reader_init (&br, data, size);
+  gst_bit_reader_init (&br, map.data, map.size);
 
   /* any object type is fine, we need to copy it to the profile-level-id field. */
   if (!gst_bit_reader_get_bits_uint8 (&br, &objectType, 5))
@@ -261,7 +261,7 @@ gst_rtp_mp4g_pay_parse_audio_config (GstRtpMP4GPay * rtpmp4gpay,
       objectType, samplingIdx, rtpmp4gpay->rate, channelCfg,
       rtpmp4gpay->frame_len);
 
-  gst_buffer_unmap (buffer, data, -1);
+  gst_buffer_unmap (buffer, &map);
   return TRUE;
 
   /* ERROR */
@@ -269,28 +269,28 @@ too_short:
   {
     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, FORMAT,
         (NULL), ("config string too short"));
-    gst_buffer_unmap (buffer, data, -1);
+    gst_buffer_unmap (buffer, &map);
     return FALSE;
   }
 invalid_object:
   {
     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, FORMAT,
         (NULL), ("invalid object type"));
-    gst_buffer_unmap (buffer, data, -1);
+    gst_buffer_unmap (buffer, &map);
     return FALSE;
   }
 wrong_freq:
   {
     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, NOT_IMPLEMENTED,
         (NULL), ("unsupported frequency index %d", samplingIdx));
-    gst_buffer_unmap (buffer, data, -1);
+    gst_buffer_unmap (buffer, &map);
     return FALSE;
   }
 wrong_channels:
   {
     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, NOT_IMPLEMENTED,
         (NULL), ("unsupported number of channels %d, must < 8", channelCfg));
-    gst_buffer_unmap (buffer, data, -1);
+    gst_buffer_unmap (buffer, &map);
     return FALSE;
   }
 }
@@ -301,21 +301,20 @@ static gboolean
 gst_rtp_mp4g_pay_parse_video_config (GstRtpMP4GPay * rtpmp4gpay,
     GstBuffer * buffer)
 {
-  guint8 *data;
-  gsize size;
+  GstMapInfo map;
   guint32 code;
 
-  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
 
-  if (size < 5)
+  if (map.size < 5)
     goto too_short;
 
-  code = GST_READ_UINT32_BE (data);
+  code = GST_READ_UINT32_BE (map.data);
 
   g_free (rtpmp4gpay->profile);
   if (code == VOS_STARTCODE) {
     /* get profile */
-    rtpmp4gpay->profile = g_strdup_printf ("%d", (gint) data[4]);
+    rtpmp4gpay->profile = g_strdup_printf ("%d", (gint) map.data[4]);
   } else {
     GST_ELEMENT_WARNING (rtpmp4gpay, STREAM, FORMAT,
         (NULL), ("profile not found in config string, assuming \'1\'"));
@@ -333,7 +332,7 @@ gst_rtp_mp4g_pay_parse_video_config (GstRtpMP4GPay * rtpmp4gpay,
 
   GST_LOG_OBJECT (rtpmp4gpay, "profile %s", rtpmp4gpay->profile);
 
-  gst_buffer_unmap (buffer, data, -1);
+  gst_buffer_unmap (buffer, &map);
 
   return TRUE;
 
@@ -342,7 +341,7 @@ too_short:
   {
     GST_ELEMENT_ERROR (rtpmp4gpay, STREAM, FORMAT,
         (NULL), ("config string too short"));
-    gst_buffer_unmap (buffer, data, -1);
+    gst_buffer_unmap (buffer, &map);
     return FALSE;
   }
 }
@@ -370,10 +369,10 @@ gst_rtp_mp4g_pay_new_caps (GstRtpMP4GPay * rtpmp4gpay)
 
   /* hmm, silly */
   if (rtpmp4gpay->params) {
-    res = gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4gpay),
+    res = gst_rtp_base_payload_set_outcaps (GST_RTP_BASE_PAYLOAD (rtpmp4gpay),
         "encoding-params", G_TYPE_STRING, rtpmp4gpay->params, MP4GCAPS);
   } else {
-    res = gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4gpay),
+    res = gst_rtp_base_payload_set_outcaps (GST_RTP_BASE_PAYLOAD (rtpmp4gpay),
         MP4GCAPS);
   }
 
@@ -385,7 +384,7 @@ gst_rtp_mp4g_pay_new_caps (GstRtpMP4GPay * rtpmp4gpay)
 }
 
 static gboolean
-gst_rtp_mp4g_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+gst_rtp_mp4g_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
 {
   GstRtpMP4GPay *rtpmp4gpay;
   GstStructure *structure;
@@ -432,7 +431,7 @@ gst_rtp_mp4g_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
   if (media_type == NULL)
     goto config_failed;
 
-  gst_basertppayload_set_options (payload, media_type, TRUE, "MPEG4-GENERIC",
+  gst_rtp_base_payload_set_options (payload, media_type, TRUE, "MPEG4-GENERIC",
       rtpmp4gpay->rate);
 
   res = gst_rtp_mp4g_pay_new_caps (rtpmp4gpay);
@@ -463,16 +462,17 @@ gst_rtp_mp4g_pay_flush (GstRtpMP4GPay * rtpmp4gpay)
   total = avail = gst_adapter_available (rtpmp4gpay->adapter);
 
   ret = GST_FLOW_OK;
-  mtu = GST_BASE_RTP_PAYLOAD_MTU (rtpmp4gpay);
+  mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpmp4gpay);
 
   while (avail > 0) {
     guint towrite;
     guint8 *payload;
     guint payload_len;
     guint packet_len;
-    GstRTPBuffer rtp;
+    GstRTPBuffer rtp = { NULL };
+    GstBuffer *paybuf;
 
-    /* this will be the total lenght of the packet */
+    /* this will be the total length of the packet */
     packet_len = gst_rtp_buffer_calc_packet_len (avail, 0, 0);
 
     /* fill one MTU or all available bytes, we need 4 spare bytes for
@@ -487,8 +487,9 @@ gst_rtp_mp4g_pay_flush (GstRtpMP4GPay * rtpmp4gpay)
         packet_len, payload_len);
 
     /* create buffer to hold the payload, also make room for the 4 header bytes. */
-    outbuf = gst_rtp_buffer_new_allocate (payload_len + 4, 0, 0);
-
+    outbuf =
+        gst_rtp_base_payload_allocate_output_buffer (GST_RTP_BASE_PAYLOAD
+        (rtpmp4gpay), 4, 0, 0);
     gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
 
     /* copy payload */
@@ -528,24 +529,27 @@ gst_rtp_mp4g_pay_flush (GstRtpMP4GPay * rtpmp4gpay)
     payload[2] = (total & 0x1fe0) >> 5;
     payload[3] = (total & 0x1f) << 3;   /* we use 13 bits for the size, 3 bits index */
 
-    /* copy stuff from adapter to payload */
-    gst_adapter_copy (rtpmp4gpay->adapter, &payload[4], 0, payload_len);
-    gst_adapter_flush (rtpmp4gpay->adapter, payload_len);
-
     /* marker only if the packet is complete */
     gst_rtp_buffer_set_marker (&rtp, avail <= payload_len);
 
     gst_rtp_buffer_unmap (&rtp);
 
-    GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4gpay->first_timestamp;
+    paybuf = gst_adapter_take_buffer_fast (rtpmp4gpay->adapter, payload_len);
+    gst_rtp_copy_meta (GST_ELEMENT_CAST (rtpmp4gpay), outbuf, paybuf, 0);
+    outbuf = gst_buffer_append (outbuf, paybuf);
+
+    GST_BUFFER_PTS (outbuf) = rtpmp4gpay->first_timestamp;
     GST_BUFFER_DURATION (outbuf) = rtpmp4gpay->first_duration;
 
-    if (rtpmp4gpay->frame_len) {
-      GST_BUFFER_OFFSET (outbuf) = rtpmp4gpay->offset;
-      rtpmp4gpay->offset += rtpmp4gpay->frame_len;
+    GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
+
+    if (rtpmp4gpay->discont) {
+      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
+      /* Only the first outputted buffer has the DISCONT flag */
+      rtpmp4gpay->discont = FALSE;
     }
 
-    ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmp4gpay), outbuf);
+    ret = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtpmp4gpay), outbuf);
 
     avail -= payload_len;
   }
@@ -556,15 +560,16 @@ gst_rtp_mp4g_pay_flush (GstRtpMP4GPay * rtpmp4gpay)
 /* we expect buffers as exactly one complete AU
  */
 static GstFlowReturn
-gst_rtp_mp4g_pay_handle_buffer (GstBaseRTPPayload * basepayload,
+gst_rtp_mp4g_pay_handle_buffer (GstRTPBasePayload * basepayload,
     GstBuffer * buffer)
 {
   GstRtpMP4GPay *rtpmp4gpay;
 
   rtpmp4gpay = GST_RTP_MP4G_PAY (basepayload);
 
-  rtpmp4gpay->first_timestamp = GST_BUFFER_TIMESTAMP (buffer);
+  rtpmp4gpay->first_timestamp = GST_BUFFER_PTS (buffer);
   rtpmp4gpay->first_duration = GST_BUFFER_DURATION (buffer);
+  rtpmp4gpay->discont = GST_BUFFER_IS_DISCONT (buffer);
 
   /* we always encode and flush a full AU */
   gst_adapter_push (rtpmp4gpay->adapter, buffer);
@@ -573,7 +578,7 @@ gst_rtp_mp4g_pay_handle_buffer (GstBaseRTPPayload * basepayload,
 }
 
 static gboolean
-gst_rtp_mp4g_pay_handle_event (GstBaseRTPPayload * payload, GstEvent * event)
+gst_rtp_mp4g_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
 {
   GstRtpMP4GPay *rtpmp4gpay;
 
@@ -596,7 +601,7 @@ gst_rtp_mp4g_pay_handle_event (GstBaseRTPPayload * payload, GstEvent * event)
   }
 
   /* let parent handle event too */
-  return FALSE;
+  return GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);
 }
 
 static GstStateChangeReturn