gst/rtp/gstrtpamrdepay.c: Fix depayloader clock_rate and some cleanups.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 10 Apr 2007 17:06:05 +0000 (17:06 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Tue, 10 Apr 2007 17:06:05 +0000 (17:06 +0000)
Original commit message from CVS:
* gst/rtp/gstrtpamrdepay.c: (gst_rtp_amr_depay_setcaps),
(gst_rtp_amr_depay_process):
Fix depayloader clock_rate and some cleanups.
* gst/rtp/gstrtph264depay.c: (gst_rtp_h264_depay_finalize),
(gst_rtp_h264_depay_setcaps), (gst_rtp_h264_depay_process):
* gst/rtp/gstrtph264depay.h:
Don't push codec_data in the adapter because it might get flushed when
we get a discont.
* gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_process):
Handle multiple AU per packet.
* gst/rtp/gstrtpsv3vdepay.c: (gst_rtp_sv3v_depay_process),
(gst_rtp_sv3v_depay_plugin_init):
Disable rank, this one does not work.
Remove timestamping, base class does that.

ChangeLog
gst/rtp/gstrtpamrdepay.c
gst/rtp/gstrtph264depay.c
gst/rtp/gstrtph264depay.h
gst/rtp/gstrtpmp4gdepay.c
gst/rtp/gstrtpsv3vdepay.c

index 31471a5..ae08c21 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-04-10  Wim Taymans  <wim@fluendo.com>
+
+       * gst/rtp/gstrtpamrdepay.c: (gst_rtp_amr_depay_setcaps),
+       (gst_rtp_amr_depay_process):
+       Fix depayloader clock_rate and some cleanups.
+
+       * gst/rtp/gstrtph264depay.c: (gst_rtp_h264_depay_finalize),
+       (gst_rtp_h264_depay_setcaps), (gst_rtp_h264_depay_process):
+       * gst/rtp/gstrtph264depay.h:
+       Don't push codec_data in the adapter because it might get flushed when
+       we get a discont.
+
+       * gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_process):
+       Handle multiple AU per packet.
+
+       * gst/rtp/gstrtpsv3vdepay.c: (gst_rtp_sv3v_depay_process),
+       (gst_rtp_sv3v_depay_plugin_init):
+       Disable rank, this one does not work.
+       Remove timestamping, base class does that.
+
 2007-04-10  Stefan Kost  <ensonic@users.sf.net>
 
        * gst/auparse/gstauparse.c: (gst_au_parse_parse_header):
index 06ea6cd..f587158 100644 (file)
@@ -197,6 +197,7 @@ gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
 
   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
     clock_rate = 8000;
+  depayload->clock_rate = clock_rate;
 
   /* we require 1 channel, 8000 Hz, octet aligned, no CRC,
    * no robust sorting, no interleaving for now */
@@ -233,24 +234,20 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 {
   GstRtpAMRDepay *rtpamrdepay;
   GstBuffer *outbuf = NULL;
+  gint payload_len;
 
   rtpamrdepay = GST_RTP_AMR_DEPAY (depayload);
 
   if (!rtpamrdepay->negotiated)
     goto not_negotiated;
 
-  if (!gst_rtp_buffer_validate (buf)) {
-    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
-        (NULL), ("AMR RTP packet did not validate"));
-    goto bad_packet;
-  }
+  if (!gst_rtp_buffer_validate (buf))
+    goto invalid_packet;
 
   /* when we get here, 1 channel, 8000 Hz, octet aligned, no CRC, 
    * no robust sorting, no interleaving data is to be depayloaded */
   {
-    gint payload_len;
     guint8 *payload, *p, *dp;
-    guint32 timestamp;
     guint8 CMR;
     gint i, num_packets, num_nonempty_packets;
     gint amr_len;
@@ -259,11 +256,8 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     payload_len = gst_rtp_buffer_get_payload_len (buf);
 
     /* need at least 2 bytes for the header */
-    if (payload_len < 2) {
-      GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
-          (NULL), ("AMR RTP payload too small (%d)", payload_len));
-      goto bad_packet;
-    }
+    if (payload_len < 2)
+      goto too_small;
 
     payload = gst_rtp_buffer_get_payload (buf);
 
@@ -290,11 +284,8 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
       payload_len -= 1;
       payload += 1;
 
-      if (ILP > ILL) {
-        GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
-            (NULL), ("AMR RTP wrong interleaving"));
-        goto bad_packet;
-      }
+      if (ILP > ILL)
+        goto wrong_interleaving;
     }
 
     /* 
@@ -317,11 +308,8 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
       fr_size = frame_size[FT];
       GST_DEBUG_OBJECT (rtpamrdepay, "frame size %d", fr_size);
-      if (fr_size == -1) {
-        GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
-            (NULL), ("AMR RTP frame size == -1"));
-        goto bad_packet;
-      }
+      if (fr_size == -1)
+        goto wrong_framesize;
 
       if (fr_size > 0) {
         amr_len += fr_size;
@@ -335,26 +323,15 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
     if (rtpamrdepay->crc) {
       /* data len + CRC len + header bytes should be smaller than payload_len */
-      if (num_packets + num_nonempty_packets + amr_len > payload_len) {
-        GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
-            (NULL), ("AMR RTP wrong length 1"));
-        goto bad_packet;
-      }
+      if (num_packets + num_nonempty_packets + amr_len > payload_len)
+        goto wrong_length_1;
     } else {
       /* data len + header bytes should be smaller than payload_len */
-      if (num_packets + amr_len > payload_len) {
-        GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
-            (NULL), ("AMR RTP wrong length 2"));
-        goto bad_packet;
-      }
+      if (num_packets + amr_len > payload_len)
+        goto wrong_length_2;
     }
 
-    timestamp = gst_rtp_buffer_get_timestamp (buf);
-
     outbuf = gst_buffer_new_and_alloc (payload_len);
-    GST_BUFFER_TIMESTAMP (outbuf) =
-        gst_util_uint64_scale_int (timestamp, GST_SECOND,
-        depayload->clock_rate);
 
     /* point to destination */
     p = GST_BUFFER_DATA (outbuf);
@@ -386,16 +363,51 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     GST_DEBUG ("gst_rtp_amr_depay_chain: pushing buffer of size %d",
         GST_BUFFER_SIZE (outbuf));
   }
-
   return outbuf;
 
   /* ERRORS */
+invalid_packet:
+  {
+    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
+        (NULL), ("AMR RTP packet did not validate"));
+    goto bad_packet;
+  }
 not_negotiated:
   {
     GST_ELEMENT_ERROR (rtpamrdepay, STREAM, NOT_IMPLEMENTED,
         (NULL), ("not negotiated"));
     return NULL;
   }
+too_small:
+  {
+    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
+        (NULL), ("AMR RTP payload too small (%d)", payload_len));
+    goto bad_packet;
+  }
+wrong_interleaving:
+  {
+    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
+        (NULL), ("AMR RTP wrong interleaving"));
+    goto bad_packet;
+  }
+wrong_framesize:
+  {
+    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
+        (NULL), ("AMR RTP frame size == -1"));
+    goto bad_packet;
+  }
+wrong_length_1:
+  {
+    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
+        (NULL), ("AMR RTP wrong length 1"));
+    goto bad_packet;
+  }
+wrong_length_2:
+  {
+    GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
+        (NULL), ("AMR RTP wrong length 2"));
+    goto bad_packet;
+  }
 bad_packet:
   {
     /* no fatal error */
index 1137679..be27910 100644 (file)
@@ -154,8 +154,10 @@ gst_rtp_h264_depay_finalize (GObject * object)
 
   rtph264depay = GST_RTP_H264_DEPAY (object);
 
+  if (rtph264depay->codec_data)
+    gst_buffer_unref (rtph264depay->codec_data);
+
   g_object_unref (rtph264depay->adapter);
-  rtph264depay->adapter = NULL;
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -255,9 +257,12 @@ gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
     }
     GST_BUFFER_SIZE (codec_data) = total;
 
-    /* don't set codec_data, we send unpacketized data so let the decoder
-     * packetize for us */
-    gst_adapter_push (rtph264depay->adapter, codec_data);
+    /* keep the codec_data, we need to send it as the first buffer. We cannot
+     * push it in the adapter because the adapter might be flushed on discont.
+     */
+    if (rtph264depay->codec_data)
+      gst_buffer_unref (rtph264depay->codec_data);
+    rtph264depay->codec_data = codec_data;
   }
 
   gst_pad_set_caps (depayload->srcpad, srccaps);
@@ -333,6 +338,12 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
         rtph264depay->wait_start = FALSE;
 
+        /* prepend codec_data */
+        if (rtph264depay->codec_data) {
+          gst_adapter_push (rtph264depay->adapter, rtph264depay->codec_data);
+          rtph264depay->codec_data = NULL;
+        }
+
         /* STAP-A    Single-time aggregation packet     5.7.1 */
         while (payload_len > 2) {
           /*                      1          
@@ -446,13 +457,20 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
         /* if NAL unit ends, flush the adapter */
         if (E) {
+          GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);
+
           outsize = gst_adapter_available (rtph264depay->adapter);
           outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
 
           gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
 
-          GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);
-
+          /* push codec_data first */
+          if (rtph264depay->codec_data) {
+            gst_buffer_set_caps (rtph264depay->codec_data,
+                GST_PAD_CAPS (depayload->srcpad));
+            gst_base_rtp_depayload_push (depayload, rtph264depay->codec_data);
+            rtph264depay->codec_data = NULL;
+          }
           return outbuf;
         }
         break;
@@ -473,6 +491,13 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
         gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
 
+        /* push codec_data first */
+        if (rtph264depay->codec_data) {
+          gst_buffer_set_caps (rtph264depay->codec_data,
+              GST_PAD_CAPS (depayload->srcpad));
+          gst_base_rtp_depayload_push (depayload, rtph264depay->codec_data);
+          rtph264depay->codec_data = NULL;
+        }
         return outbuf;
       }
     }
index ede2b84..41c4fc0 100644 (file)
@@ -44,6 +44,7 @@ struct _GstRtpH264Depay
 {
   GstBaseRTPDepayload depayload;
 
+  GstBuffer  *codec_data;
   GstAdapter *adapter;
   gboolean    wait_start;
 };
index c9e2d45..f1d68a2 100644 (file)
@@ -287,64 +287,92 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     guint32 timestamp;
     guint AU_headers_len;
     guint AU_size, AU_index;
+    gboolean M;
 
     payload_len = gst_rtp_buffer_get_payload_len (buf);
     payload = gst_rtp_buffer_get_payload (buf);
     payload_header = 0;
 
+    timestamp = gst_rtp_buffer_get_timestamp (buf);
+    M = gst_rtp_buffer_get_marker (buf);
+
     if (rtpmp4gdepay->sizelength > 0) {
+      gint num_AU_headers, AU_headers_bytes, i;
+
       /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
        * |AU-headers-length|AU-header|AU-header|      |AU-header|padding|
        * |                 |   (1)   |   (2)   |      |   (n) * | bits  |
        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
        *
-       * The lenght is 2 bytes and contains the length of the following
+       * The length is 2 bytes and contains the length of the following
        * AU-headers in bits.
        */
       AU_headers_len = (payload[0] << 8) | payload[1];
+      AU_headers_bytes = (AU_headers_len + 7) / 8;
+      num_AU_headers = AU_headers_len / 16;
+
+      GST_DEBUG_OBJECT (rtpmp4gdepay, "AU headers len %d, bytes %d, num %d",
+          AU_headers_len, AU_headers_bytes, num_AU_headers);
 
       /* skip header */
       payload += 2;
-      payload_header += 2;
-      payload_len -= 2;
-
-      /* FIXME, use bits */
-      AU_size = ((payload[0] << 8) | payload[1]) >> 3;
-      AU_index = payload[1] & 0x7;
-
-      GST_DEBUG_OBJECT (rtpmp4gdepay, "len, %d, size %d, index %d",
-          AU_headers_len, AU_size, AU_index);
-
       /* skip special headers */
-      payload += (AU_headers_len + 7) / 8;
-      payload_header += (AU_headers_len + 7) / 8;
-      payload_len = AU_size;
-    }
-
-    timestamp = gst_rtp_buffer_get_timestamp (buf);
-
-    /* strip header from payload and push in the adapter */
-    outbuf =
-        gst_rtp_buffer_get_payload_subbuffer (buf, payload_header, payload_len);
-    gst_adapter_push (rtpmp4gdepay->adapter, outbuf);
+      payload_header = 2 + AU_headers_bytes;
+
+      for (i = 0; i < num_AU_headers; i++) {
+        /* FIXME, use bits */
+        AU_size = ((payload[0] << 8) | payload[1]) >> 3;
+        AU_index = payload[1] & 0x7;
+        payload += 2;
+
+        GST_DEBUG_OBJECT (rtpmp4gdepay, "len, %d, size %d, index %d",
+            AU_headers_len, AU_size, AU_index);
+
+        /* collect stuff in the adapter, strip header from payload and push in
+         * the adapter */
+        outbuf =
+            gst_rtp_buffer_get_payload_subbuffer (buf, payload_header, AU_size);
+        gst_adapter_push (rtpmp4gdepay->adapter, outbuf);
+
+        if (M) {
+          guint avail;
+
+          /* packet is complete, flush */
+          avail = gst_adapter_available (rtpmp4gdepay->adapter);
+
+          outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail);
+          gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
+
+          GST_DEBUG ("gst_rtp_mp4g_depay_chain: pushing buffer of size %d",
+              GST_BUFFER_SIZE (outbuf));
+
+          /* only apply the timestamp for the first buffer */
+          if (i == 0)
+            gst_base_rtp_depayload_push_ts (depayload, timestamp, outbuf);
+          else
+            gst_base_rtp_depayload_push (depayload, outbuf);
+        }
+        payload_header += AU_size;
+      }
+    } else {
+      /* push complete buffer in adapter */
+      outbuf = gst_rtp_buffer_get_payload_subbuffer (buf, 0, payload_len);
+      gst_adapter_push (rtpmp4gdepay->adapter, outbuf);
 
-    /* if this was the last packet of the VOP, create and push a buffer */
-    if (gst_rtp_buffer_get_marker (buf)) {
-      guint avail;
+      /* if this was the last packet of the VOP, create and push a buffer */
+      if (M) {
+        guint avail;
 
-      avail = gst_adapter_available (rtpmp4gdepay->adapter);
+        avail = gst_adapter_available (rtpmp4gdepay->adapter);
 
-      outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail);
-      gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
-      GST_BUFFER_TIMESTAMP (outbuf) = gst_util_uint64_scale_int
-          (timestamp, GST_SECOND, depayload->clock_rate);
+        outbuf = gst_adapter_take_buffer (rtpmp4gdepay->adapter, avail);
+        gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
 
-      GST_DEBUG ("gst_rtp_mp4g_depay_chain: pushing buffer of size %d",
-          GST_BUFFER_SIZE (outbuf));
+        GST_DEBUG ("gst_rtp_mp4g_depay_chain: pushing buffer of size %d",
+            GST_BUFFER_SIZE (outbuf));
 
-      return outbuf;
-    } else {
-      return NULL;
+        return outbuf;
+      }
     }
   }
   return NULL;
index f2df179..bc2647b 100644 (file)
@@ -252,16 +252,11 @@ gst_rtp_sv3v_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     if (M) {
       /* frame is completed: push contents of adapter */
       guint avail;
-      guint32 timestamp;
 
       avail = gst_adapter_available (rtpsv3vdepay->adapter);
       outbuf = gst_adapter_take_buffer (rtpsv3vdepay->adapter, avail);
 
       /* timestamp for complete buffer is that of last buffer as well */
-      timestamp = gst_rtp_buffer_get_timestamp (buf);
-      GST_BUFFER_TIMESTAMP (outbuf) =
-          gst_util_uint64_scale_int (timestamp, GST_SECOND,
-          depayload->clock_rate);
       gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
 
       return outbuf;
@@ -342,5 +337,5 @@ gboolean
 gst_rtp_sv3v_depay_plugin_init (GstPlugin * plugin)
 {
   return gst_element_register (plugin, "rtpsv3vdepay",
-      GST_RANK_MARGINAL, GST_TYPE_RTP_SV3V_DEPAY);
+      GST_RANK_NONE, GST_TYPE_RTP_SV3V_DEPAY);
 }