rtp: Update codes based on 1.18.4
[platform/upstream/gst-plugins-good.git] / gst / rtp / gstrtpmp4adepay.c
index 24f8f59..9177d7c 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
 
 #include <gst/base/gstbitreader.h>
 #include <gst/rtp/gstrtpbuffer.h>
+#include <gst/audio/audio.h>
 
 #include <string.h>
 #include "gstrtpmp4adepay.h"
+#include "gstrtputils.h"
 
 GST_DEBUG_CATEGORY_STATIC (rtpmp4adepay_debug);
 #define GST_CAT_DEFAULT (rtpmp4adepay_debug)
@@ -35,7 +37,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/mpeg,"
-        "mpegversion = (int) 4," "framed = (boolean) true, "
+        "mpegversion = (int) 4," "framed = (boolean) { false, true }, "
         "stream-format = (string) raw")
     );
 
@@ -45,7 +47,6 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("application/x-rtp, "
         "media = (string) \"audio\", "
-        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
         "clock-rate = (int) [1, MAX ], "
         "encoding-name = (string) \"MP4A-LATM\""
         /* All optional parameters
@@ -58,14 +59,14 @@ GST_STATIC_PAD_TEMPLATE ("sink",
 
 #define gst_rtp_mp4a_depay_parent_class parent_class
 G_DEFINE_TYPE (GstRtpMP4ADepay, gst_rtp_mp4a_depay,
-    GST_TYPE_BASE_RTP_DEPAYLOAD);
+    GST_TYPE_RTP_BASE_DEPAYLOAD);
 
 static void gst_rtp_mp4a_depay_finalize (GObject * object);
 
-static gboolean gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload,
+static gboolean gst_rtp_mp4a_depay_setcaps (GstRTPBaseDepayload * depayload,
     GstCaps * caps);
-static GstBuffer *gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload,
-    GstBuffer * buf);
+static GstBuffer *gst_rtp_mp4a_depay_process (GstRTPBaseDepayload * depayload,
+    GstRTPBuffer * rtp);
 
 static GstStateChangeReturn gst_rtp_mp4a_depay_change_state (GstElement *
     element, GstStateChange transition);
@@ -76,25 +77,25 @@ gst_rtp_mp4a_depay_class_init (GstRtpMP4ADepayClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
-  GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
+  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
 
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
-  gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
+  gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
 
   gobject_class->finalize = gst_rtp_mp4a_depay_finalize;
 
   gstelement_class->change_state = gst_rtp_mp4a_depay_change_state;
 
-  gstbasertpdepayload_class->process = gst_rtp_mp4a_depay_process;
-  gstbasertpdepayload_class->set_caps = gst_rtp_mp4a_depay_setcaps;
+  gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_mp4a_depay_process;
+  gstrtpbasedepayload_class->set_caps = gst_rtp_mp4a_depay_setcaps;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_mp4a_depay_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_mp4a_depay_sink_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_mp4a_depay_src_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_mp4a_depay_sink_template);
 
-  gst_element_class_set_details_simple (gstelement_class,
+  gst_element_class_set_static_metadata (gstelement_class,
       "RTP MPEG4 audio depayloader", "Codec/Depayloader/Network/RTP",
       "Extracts MPEG4 audio from RTP packets (RFC 3016)",
       "Nokia Corporation (contact <stefan.kost@nokia.com>), "
@@ -108,6 +109,7 @@ static void
 gst_rtp_mp4a_depay_init (GstRtpMP4ADepay * rtpmp4adepay)
 {
   rtpmp4adepay->adapter = gst_adapter_new ();
+  rtpmp4adepay->framed = FALSE;
 }
 
 static void
@@ -124,11 +126,11 @@ gst_rtp_mp4a_depay_finalize (GObject * object)
 }
 
 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000,
-  44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000
+  44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
 };
 
 static gboolean
-gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
+gst_rtp_mp4a_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
 {
   GstStructure *structure;
   GstRtpMP4ADepay *rtpmp4adepay;
@@ -141,6 +143,8 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
 
   rtpmp4adepay = GST_RTP_MP4A_DEPAY (depayload);
 
+  rtpmp4adepay->framed = FALSE;
+
   structure = gst_caps_get_structure (caps, 0);
 
   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
@@ -152,7 +156,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
 
   srccaps = gst_caps_new_simple ("audio/mpeg",
       "mpegversion", G_TYPE_INT, 4,
-      "framed", G_TYPE_BOOLEAN, TRUE, "channels", G_TYPE_INT, channels,
+      "framed", G_TYPE_BOOLEAN, FALSE, "channels", G_TYPE_INT, channels,
       "stream-format", G_TYPE_STRING, "raw", NULL);
 
   if ((str = gst_structure_get_string (structure, "config"))) {
@@ -161,6 +165,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
     g_value_init (&v, GST_TYPE_BUFFER);
     if (gst_value_deserialize (&v, str)) {
       GstBuffer *buffer;
+      GstMapInfo map;
       guint8 *data;
       gsize size;
       gint i;
@@ -172,7 +177,9 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
       gst_buffer_ref (buffer);
       g_value_unset (&v);
 
-      data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+      gst_buffer_map (buffer, &map, GST_MAP_READ);
+      data = map.data;
+      size = map.size;
 
       if (size < 2) {
         GST_WARNING_OBJECT (depayload, "config too short (%d < 2)",
@@ -239,6 +246,8 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
         /* index of 15 means we get the rate in the next 24 bits */
         if (!gst_bit_reader_get_bits_uint32 (&br, &rate, 24))
           goto bad_config;
+      } else if (sr_idx >= G_N_ELEMENTS (aac_sample_rates)) {
+        goto bad_config;
       } else {
         /* else use the rate from the table */
         rate = aac_sample_rates[sr_idx];
@@ -266,7 +275,8 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
       }
 
       /* ignore remaining bit, we're only interested in full bytes */
-      gst_buffer_unmap (buffer, data, size);
+      gst_buffer_resize (buffer, 0, size);
+      gst_buffer_unmap (buffer, &map);
       data = NULL;
 
       gst_caps_set_simple (srccaps,
@@ -275,7 +285,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
           "codec_data", GST_TYPE_BUFFER, buffer, NULL);
     bad_config:
       if (data)
-        gst_buffer_unmap (buffer, data, -1);
+        gst_buffer_unmap (buffer, &map);
       gst_buffer_unref (buffer);
     } else {
       g_warning ("cannot convert config to buffer");
@@ -288,30 +298,47 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
 }
 
 static GstBuffer *
-gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
+gst_rtp_mp4a_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
 {
   GstRtpMP4ADepay *rtpmp4adepay;
   GstBuffer *outbuf;
-  GstRTPBuffer rtp;
-  guint8 *bdata;
+  GstMapInfo map;
 
   rtpmp4adepay = GST_RTP_MP4A_DEPAY (depayload);
 
   /* flush remaining data on discont */
-  if (GST_BUFFER_IS_DISCONT (buf)) {
+  if (GST_BUFFER_IS_DISCONT (rtp->buffer)) {
     gst_adapter_clear (rtpmp4adepay->adapter);
   }
 
-  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
-  outbuf = gst_rtp_buffer_get_payload_buffer (&rtp);
+  outbuf = gst_rtp_buffer_get_payload_buffer (rtp);
+
+  if (!rtpmp4adepay->framed) {
+    if (gst_rtp_buffer_get_marker (rtp)) {
+      GstCaps *caps;
+
+      rtpmp4adepay->framed = TRUE;
+
+      gst_rtp_base_depayload_push (depayload, outbuf);
+
+      caps = gst_pad_get_current_caps (depayload->srcpad);
+      caps = gst_caps_make_writable (caps);
+      gst_caps_set_simple (caps, "framed", G_TYPE_BOOLEAN, TRUE, NULL);
+      gst_pad_set_caps (depayload->srcpad, caps);
+      gst_caps_unref (caps);
+      return NULL;
+    } else {
+      return outbuf;
+    }
+  }
 
   outbuf = gst_buffer_make_writable (outbuf);
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+  GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (rtp->buffer);
   gst_adapter_push (rtpmp4adepay->adapter, outbuf);
 
   /* RTP marker bit indicates the last packet of the AudioMuxElement => create
    * and push a buffer */
-  if (gst_rtp_buffer_get_marker (&rtp)) {
+  if (gst_rtp_buffer_get_marker (rtp)) {
     guint avail;
     guint i;
     guint8 *data;
@@ -319,12 +346,13 @@ gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     GstClockTime timestamp;
 
     avail = gst_adapter_available (rtpmp4adepay->adapter);
-    timestamp = gst_adapter_prev_timestamp (rtpmp4adepay->adapter, NULL);
+    timestamp = gst_adapter_prev_pts (rtpmp4adepay->adapter, NULL);
 
     GST_LOG_OBJECT (rtpmp4adepay, "have marker and %u available", avail);
 
     outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
-    data = bdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_READ);
+    gst_buffer_map (outbuf, &map, GST_MAP_READ);
+    data = map.data;
     /* position in data we are at */
     pos = 0;
 
@@ -355,19 +383,19 @@ gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
       /* take data out, skip the header */
       pos += skip;
-      tmp = gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_MEMORY, pos,
-          data_len);
+      tmp = gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, pos, data_len);
 
       /* skip data too */
       skip += data_len;
       pos += data_len;
 
-      /* update our pointers whith what we consumed */
+      /* update our pointers with what we consumed */
       data += skip;
       avail -= skip;
 
-      GST_BUFFER_TIMESTAMP (tmp) = timestamp;
-      gst_base_rtp_depayload_push (depayload, tmp);
+      GST_BUFFER_PTS (tmp) = timestamp;
+      gst_rtp_drop_non_audio_meta (depayload, tmp);
+      gst_rtp_base_depayload_push (depayload, tmp);
 
       /* shift ts for next buffers */
       if (rtpmp4adepay->frame_len && timestamp != -1
@@ -385,10 +413,9 @@ gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
               "possible wrongly encoded packet."));
     }
 
-    gst_buffer_unmap (outbuf, bdata, -1);
+    gst_buffer_unmap (outbuf, &map);
     gst_buffer_unref (outbuf);
   }
-  gst_rtp_buffer_unmap (&rtp);
   return NULL;
 
   /* ERRORS */
@@ -396,9 +423,8 @@ wrong_size:
   {
     GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
         ("Packet did not validate"), ("wrong packet size"));
-    gst_buffer_unmap (outbuf, bdata, -1);
+    gst_buffer_unmap (outbuf, &map);
     gst_buffer_unref (outbuf);
-    gst_rtp_buffer_unmap (&rtp);
     return NULL;
   }
 }
@@ -417,6 +443,7 @@ gst_rtp_mp4a_depay_change_state (GstElement * element,
       gst_adapter_clear (rtpmp4adepay->adapter);
       rtpmp4adepay->frame_len = 0;
       rtpmp4adepay->numSubFrames = 0;
+      rtpmp4adepay->framed = FALSE;
       break;
     default:
       break;