]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
iptv: fix stupid error causing IPTV systems to fail (fixes #2067)
authorAdam Sutton <dev@adamsutton.me.uk>
Tue, 22 Apr 2014 21:24:26 +0000 (22:24 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Tue, 22 Apr 2014 21:24:26 +0000 (22:24 +0100)
This occured where the IPTV system was using small packets (7 pkts
is pretty normal since it always fits in most IP datagrams)
unfortunately all my testing had been with custom generator script
that used much larger packets.

src/input/mpegts/iptv/iptv_udp.c
src/input/mpegts/mpegts_input.c

index 7df3745eb4c6d50f4437992a1d93794c80bc089c..ea8cac0b9c1ace8355920d8379586c1d454b3f2b 100644 (file)
@@ -181,10 +181,6 @@ error:
 static ssize_t
 iptv_udp_read ( iptv_mux_t *im, size_t *off )
 {
-  /* UDP/RTP should not have TS packets straddling datagrams, I think! */
-  im->mm_iptv_buffer.sb_ptr = 0;
-
-  /* Read */
   return sbuf_read(&im->mm_iptv_buffer, im->mm_iptv_fd);
 }
 
@@ -192,6 +188,8 @@ static ssize_t
 iptv_rtp_read ( iptv_mux_t *im, size_t *off )
 {
   ssize_t len, hlen;
+  int      ptr = im->mm_iptv_buffer.sb_ptr;
+  uint8_t *rtp = im->mm_iptv_buffer.sb_data + ptr;
 
   /* Raw packet */
   len = iptv_udp_read(im, NULL);
@@ -200,27 +198,36 @@ iptv_rtp_read ( iptv_mux_t *im, size_t *off )
 
   /* Strip RTP header */
   if (len < 12)
-    return 0; // ignore
-  if ((im->mm_iptv_buffer.sb_data[0] & 0xC0) != 0x80)
-    return 0;
-  if ((im->mm_iptv_buffer.sb_data[1] & 0x7F) != 33)
-    return 0;
-  hlen = ((im->mm_iptv_buffer.sb_data[0] & 0xf) * 4) + 12;
-  if (im->mm_iptv_buffer.sb_data[0] & 0x10) {
+    goto ignore;
+
+  /* Version 2 */
+  if ((rtp[0] & 0xC0) != 0x80)
+    goto ignore;
+
+  /* MPEG-TS */
+  if ((rtp[1] & 0x7F) != 33)
+    goto ignore;
+
+  /* Header length (4bytes per CSRC) */
+  hlen = ((rtp[0] & 0xf) * 4) + 12;
+  if (rtp[0] & 0x10) {
     if (len < hlen+4)
-      return 0;
-    hlen += (im->mm_iptv_buffer.sb_data[hlen+2] << 8) 
-          | (im->mm_iptv_buffer.sb_data[hlen+3] * 4);
+      goto ignore;
+    hlen += ((rtp[hlen+2] << 8) | rtp[hlen+3]) * 4;
     hlen += 4;
   }
   if (len < hlen || ((len - hlen) % 188) != 0)
-    return 0;
+    goto ignore;
+
+  /* Cut header */
+  memmove(rtp, rtp+hlen, len-hlen);
+  im->mm_iptv_buffer.sb_ptr -= hlen;
 
-  /* Cut */
-  sbuf_cut(&im->mm_iptv_buffer, hlen);
-  // TODO: would be nice to avoid this extra copy, it was possible until I
-  //       changed the API!
+  return len;
 
+ignore:
+  printf("ignore\n");
+  im->mm_iptv_buffer.sb_ptr = ptr; // reset
   return len;
 }
 
index 11936371b7658ed19ba4d1d42c6d50515c97d615..3e0b33472cc6f2c61a46f21b961b8dc9fad606fc 100644 (file)
@@ -458,7 +458,7 @@ mpegts_input_recv_packets
   mpegts_packet_t *mp;
   uint8_t *tsb = sb->sb_data + off;
   int     len  = sb->sb_ptr  - off;
-#define MIN_TS_PKT 100
+#define MIN_TS_PKT 10
 #define MIN_TS_SYN 5
 
   if (len < (MIN_TS_PKT * 188))