diff options
author | Abylay Ospan <aospan@netup.ru> | 2009-06-06 08:31:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 18:07:23 -0400 |
commit | 0d834635a35a98d0dced54da7695ccab4464854d (patch) | |
tree | 35f9e0e40491abd348d99fc471aa4164bb6b7ff4 /drivers | |
parent | d6a9a430a63adac71f2d23d4eb8f4eb467fc82c2 (diff) |
V4L/DVB (11930): TS continuity check: show error message when discontinuity detected or TEI flag detected in header
Signed-off-by: Abylay Ospan <aospan@netup.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.c | 42 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.h | 4 |
2 files changed, 46 insertions, 0 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index e2eca0b1fe7c..cfe2768d24af 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -38,6 +38,16 @@ | |||
38 | */ | 38 | */ |
39 | // #define DVB_DEMUX_SECTION_LOSS_LOG | 39 | // #define DVB_DEMUX_SECTION_LOSS_LOG |
40 | 40 | ||
41 | static int dvb_demux_tscheck; | ||
42 | module_param(dvb_demux_tscheck, int, 0644); | ||
43 | MODULE_PARM_DESC(dvb_demux_tscheck, | ||
44 | "enable transport stream continuity and TEI check"); | ||
45 | |||
46 | #define dprintk_tscheck(x...) do { \ | ||
47 | if (dvb_demux_tscheck && printk_ratelimit()) \ | ||
48 | printk(x); \ | ||
49 | } while (0) | ||
50 | |||
41 | /****************************************************************************** | 51 | /****************************************************************************** |
42 | * static inlined helper functions | 52 | * static inlined helper functions |
43 | ******************************************************************************/ | 53 | ******************************************************************************/ |
@@ -376,6 +386,36 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
376 | u16 pid = ts_pid(buf); | 386 | u16 pid = ts_pid(buf); |
377 | int dvr_done = 0; | 387 | int dvr_done = 0; |
378 | 388 | ||
389 | if (dvb_demux_tscheck) { | ||
390 | if (!demux->cnt_storage) | ||
391 | demux->cnt_storage = vmalloc(MAX_PID + 1); | ||
392 | |||
393 | if (!demux->cnt_storage) { | ||
394 | printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n"); | ||
395 | dvb_demux_tscheck = 0; | ||
396 | goto no_dvb_demux_tscheck; | ||
397 | } | ||
398 | |||
399 | /* check pkt counter */ | ||
400 | if (pid < MAX_PID) { | ||
401 | if (buf[1] & 0x80) | ||
402 | dprintk_tscheck("TEI detected. " | ||
403 | "PID=0x%x data1=0x%x\n", | ||
404 | pid, buf[1]); | ||
405 | |||
406 | if ((buf[3] & 0xf) != demux->cnt_storage[pid]) | ||
407 | dprintk_tscheck("TS packet counter mismatch. " | ||
408 | "PID=0x%x expected 0x%x " | ||
409 | "got 0x%x\n", | ||
410 | pid, demux->cnt_storage[pid], | ||
411 | buf[3] & 0xf); | ||
412 | |||
413 | demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf; | ||
414 | }; | ||
415 | /* end check */ | ||
416 | }; | ||
417 | no_dvb_demux_tscheck: | ||
418 | |||
379 | list_for_each_entry(feed, &demux->feed_list, list_head) { | 419 | list_for_each_entry(feed, &demux->feed_list, list_head) { |
380 | if ((feed->pid != pid) && (feed->pid != 0x2000)) | 420 | if ((feed->pid != pid) && (feed->pid != 0x2000)) |
381 | continue; | 421 | continue; |
@@ -1160,6 +1200,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) | |||
1160 | int i; | 1200 | int i; |
1161 | struct dmx_demux *dmx = &dvbdemux->dmx; | 1201 | struct dmx_demux *dmx = &dvbdemux->dmx; |
1162 | 1202 | ||
1203 | dvbdemux->cnt_storage = NULL; | ||
1163 | dvbdemux->users = 0; | 1204 | dvbdemux->users = 0; |
1164 | dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); | 1205 | dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); |
1165 | 1206 | ||
@@ -1226,6 +1267,7 @@ EXPORT_SYMBOL(dvb_dmx_init); | |||
1226 | 1267 | ||
1227 | void dvb_dmx_release(struct dvb_demux *dvbdemux) | 1268 | void dvb_dmx_release(struct dvb_demux *dvbdemux) |
1228 | { | 1269 | { |
1270 | vfree(dvbdemux->cnt_storage); | ||
1229 | vfree(dvbdemux->filter); | 1271 | vfree(dvbdemux->filter); |
1230 | vfree(dvbdemux->feed); | 1272 | vfree(dvbdemux->feed); |
1231 | } | 1273 | } |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h index 2c5f915329ca..2fe05d03240d 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/drivers/media/dvb/dvb-core/dvb_demux.h | |||
@@ -42,6 +42,8 @@ | |||
42 | 42 | ||
43 | #define DVB_DEMUX_MASK_MAX 18 | 43 | #define DVB_DEMUX_MASK_MAX 18 |
44 | 44 | ||
45 | #define MAX_PID 0x1fff | ||
46 | |||
45 | struct dvb_demux_filter { | 47 | struct dvb_demux_filter { |
46 | struct dmx_section_filter filter; | 48 | struct dmx_section_filter filter; |
47 | u8 maskandmode[DMX_MAX_FILTER_SIZE]; | 49 | u8 maskandmode[DMX_MAX_FILTER_SIZE]; |
@@ -127,6 +129,8 @@ struct dvb_demux { | |||
127 | 129 | ||
128 | struct mutex mutex; | 130 | struct mutex mutex; |
129 | spinlock_t lock; | 131 | spinlock_t lock; |
132 | |||
133 | uint8_t *cnt_storage; /* for TS continuity check */ | ||
130 | }; | 134 | }; |
131 | 135 | ||
132 | int dvb_dmx_init(struct dvb_demux *dvbdemux); | 136 | int dvb_dmx_init(struct dvb_demux *dvbdemux); |