summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_demux.c30
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_demux.h3
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-core.c1
3 files changed, 31 insertions, 3 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c
index c05e98e5c..26c793d13 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -249,7 +249,22 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
}
/*
-** Losless Section Demux 1.4 by Emard
+** Losless Section Demux 1.4.1 by Emard
+** Valsecchi Patrick:
+** - middle of section A (no PUSI)
+** - end of section A and start of section B
+** (with PUSI pointing to the start of the second section)
+**
+** In this case, without feed->pusi_seen you'll receive a garbage section
+** consisting of the end of section A. Basically because tsfeedp
+** is incemented and the use=0 condition is not raised
+** when the second packet arrives.
+**
+** Fix:
+** when demux is started, let feed->pusi_seen = 0 to
+** prevent initial feeding of garbage from the end of
+** previous section. When you for the first time see PUSI=1
+** then set feed->pusi_seen = 1
*/
static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
{
@@ -295,7 +310,12 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const
sec->seclen = seclen;
sec->crc_val = ~0;
/* dump [secbuf .. secbuf+seclen) */
- dvb_dmx_swfilter_section_feed(feed);
+ if(feed->pusi_seen)
+ dvb_dmx_swfilter_section_feed(feed);
+#ifdef DVB_DEMUX_SECTION_LOSS_LOG
+ else
+ printk("dvb_demux.c pusi not seen, discarding section data\n");
+#endif
sec->secbufp += seclen; /* secbufp and secbuf moving together is */
sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
}
@@ -328,6 +348,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
** in the following dvb_dmx_swfilter_section_new
*/
#endif
+ /* Discontinuity detected. Reset pusi_seen = 0 to
+ ** stop feeding of suspicious data until next PUSI=1 arrives
+ */
+ feed->pusi_seen = 0;
dvb_dmx_swfilter_section_new(feed);
return 0;
}
@@ -343,6 +367,8 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
u8 after_len = count-1-before_len;
dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
+ /* before start of new section, set pusi_seen = 1 */
+ feed->pusi_seen = 1;
dvb_dmx_swfilter_section_new(feed);
dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
}
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.h b/linux/drivers/media/dvb/dvb-core/dvb_demux.h
index 98acadbe1..3f40fe16d 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -93,7 +93,8 @@ struct dvb_demux_feed {
enum dmx_ts_pes pes_type;
int cc;
-
+ int pusi_seen; /* prevents feeding of garbage from previous section */
+
u16 peslen;
struct list_head list_head;
diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c
index 04d094316..b4cc259f1 100644
--- a/linux/drivers/media/dvb/ttpci/budget-core.c
+++ b/linux/drivers/media/dvb/ttpci/budget-core.c
@@ -253,6 +253,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
return -EINVAL;
spin_lock(&budget->feedlock);
+ feed->pusi_seen = 0; /* have a clean section start */
status = start_ts_capture(budget);
spin_unlock(&budget->feedlock);
return status;