rtpjpegdepay: Don't send invalid frames downstream after packet loss or a DISCONT
authorNirbheek Chauhan <nirbheek@centricular.com>
Mon, 14 Mar 2016 21:55:26 +0000 (03:25 +0530)
committerTim-Philipp Müller <tim@centricular.com>
Mon, 4 Apr 2016 16:40:11 +0000 (17:40 +0100)
After clearing the adapter due to a DISCONT, as might happen when some packet(s)
have been lost, the depayloader was pushing data into the adapter (which had no
header due to the clear), creating a headerless frame out of it, and sending it
downstream. The downstream decoder would then usually ignore it; unless there
were lots of DISCONTs from the jitterbuffer in which case the decoder would reach
its max_errors limit and throw an element error. Now we just discard that data.

It is probaby not worth trying to salvage this data because non-progressive
jpeg does not degrade gracefully and makes the video unwatchable even with
low packet loss such as 3-5%.

gst/rtp/gstrtpjpegdepay.c

index a0c7fd4..c4e2e8e 100644 (file)
@@ -531,6 +531,13 @@ gst_rtp_jpeg_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
   width = payload[6] * 8;
   height = payload[7] * 8;
 
+  /* saw a packet with fragment offset > 0 and we don't already have data queued
+   * up (most importantly, we don't have a header for this data) -- drop it
+   * XXX: maybe we can check if the jpeg is progressive and salvage the data?
+   * XXX: not implemented yet because jpegenc can't create progressive jpegs */
+  if (frag_offset > 0 && gst_adapter_available (rtpjpegdepay->adapter) == 0)
+    goto no_header_packet;
+
   /* allow frame dimensions > 2040, passed in SDP session or media attributes
    * from gstrtspsrc.c (gst_rtspsrc_sdp_attributes_to_caps), or in caps */
   if (!width)
@@ -747,6 +754,12 @@ invalid_packet:
         gst_adapter_available (rtpjpegdepay->adapter));
     return NULL;
   }
+no_header_packet:
+  {
+    GST_WARNING_OBJECT (rtpjpegdepay,
+        "discarding data packets received when we have no header");
+    return NULL;
+  }
 }