theorapay: handle 0 sized packets
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 14 Feb 2011 15:46:46 +0000 (16:46 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 14 Feb 2011 15:48:06 +0000 (16:48 +0100)
Handle 0 sized packets (repeat frame) in the payloader and depayloader.

Fixes #641827

gst/rtp/gstrtptheoradepay.c
gst/rtp/gstrtptheorapay.c

index a21cc6c..c1a576b 100644 (file)
@@ -501,7 +501,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     to_free = payload;
   }
 
-  GST_DEBUG_OBJECT (depayload, "assemble done");
+  GST_DEBUG_OBJECT (depayload, "assemble done, payload_len %d", payload_len);
 
   /* we not assembling anymore now */
   rtptheoradepay->assembling = FALSE;
@@ -524,7 +524,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
    */
   timestamp = gst_rtp_buffer_get_timestamp (buf);
 
-  while (payload_len > 2) {
+  while (payload_len >= 2) {
     guint16 length;
 
     length = GST_READ_UINT16_BE (payload);
@@ -559,7 +559,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
       memcpy (GST_BUFFER_DATA (outbuf), payload, length);
     }
 
-    if ((payload[0] & 0xC0) == 0x0)
+    if (payload_len > 0 && (payload[0] & 0xC0) == 0x0)
       rtptheoradepay->needs_keyframe = FALSE;
 
     payload += length;
index 7782853..0092fbc 100644 (file)
@@ -563,7 +563,7 @@ gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
 
   /* put buffer in packet, it either fits completely or needs to be fragmented
    * over multiple RTP packets. */
-  while (size) {
+  do {
     plen = MIN (rtptheorapay->payload_left - 2, size);
 
     GST_DEBUG_OBJECT (rtptheorapay, "append %u bytes", plen);
@@ -571,7 +571,8 @@ gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
     /* data is copied in the payload with a 2 byte length header */
     ppos[0] = ((plen - not_in_length) >> 8) & 0xff;
     ppos[1] = ((plen - not_in_length) & 0xff);
-    memcpy (&ppos[2], data, plen);
+    if (plen)
+      memcpy (&ppos[2], data, plen);
 
     /* only first (only) configuration cuts length field */
     /* NOTE: spec (if any) is not clear on this ... */
@@ -617,7 +618,7 @@ gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
       if (duration != GST_CLOCK_TIME_NONE)
         rtptheorapay->payload_duration += duration;
     }
-  }
+  } while (size);
 
   return ret;
 }
@@ -644,11 +645,14 @@ gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * basepayload,
   GST_DEBUG_OBJECT (rtptheorapay, "size %u, duration %" GST_TIME_FORMAT,
       size, GST_TIME_ARGS (duration));
 
-  if (G_UNLIKELY (size < 1 || size > 0xffff))
+  if (G_UNLIKELY (size > 0xffff))
     goto wrong_size;
 
   /* find packet type */
-  if (data[0] & 0x80) {
+  if (size == 0) {
+    TDT = 0;
+    keyframe = FALSE;
+  } else if (data[0] & 0x80) {
     /* header */
     if (data[0] == 0x80) {
       /* identification, we need to parse this in order to get the clock rate.
@@ -743,7 +747,7 @@ done:
 wrong_size:
   {
     GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
-        ("Invalid packet size (1 < %d <= 0xffff)", size), (NULL));
+        ("Invalid packet size (%d <= 0xffff)", size), (NULL));
     gst_buffer_unref (buffer);
     return GST_FLOW_OK;
   }