From 6b0aed0170609572ef832ec4a3cdb41ad601a8ce Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Tue, 22 Apr 2014 22:24:26 +0100 Subject: [PATCH] iptv: fix stupid error causing IPTV systems to fail (fixes #2067) 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 | 45 ++++++++++++++++++-------------- src/input/mpegts/mpegts_input.c | 2 +- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/input/mpegts/iptv/iptv_udp.c b/src/input/mpegts/iptv/iptv_udp.c index 7df3745e..ea8cac0b 100644 --- a/src/input/mpegts/iptv/iptv_udp.c +++ b/src/input/mpegts/iptv/iptv_udp.c @@ -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,28 +198,37 @@ 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 */ - sbuf_cut(&im->mm_iptv_buffer, hlen); - // TODO: would be nice to avoid this extra copy, it was possible until I - // changed the API! + /* Cut header */ + memmove(rtp, rtp+hlen, len-hlen); + im->mm_iptv_buffer.sb_ptr -= hlen; return len; + +ignore: + printf("ignore\n"); + im->mm_iptv_buffer.sb_ptr = ptr; // reset + return len; } /* diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 11936371..3e0b3347 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -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))