24 #include <linux/sched.h>
26 #include <linux/slab.h>
28 #include <linux/module.h>
29 #include <linux/poll.h>
30 #include <linux/string.h>
32 #include <asm/uaccess.h>
33 #include <asm/div64.h>
43 static int dvb_demux_tscheck;
46 "enable transport stream continuity and TEI check");
48 static int dvb_demux_speedcheck;
51 "enable transport stream speed check");
53 static int dvb_demux_feed_err_pkts = 1;
56 "when set to 0, drop packets with the TEI bit set (1 by default)");
58 #define dprintk_tscheck(x...) do { \
59 if (dvb_demux_tscheck && printk_ratelimit()) \
69 return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
72 static inline u16 ts_pid(
const u8 *
buf)
74 return ((buf[1] & 0x1f) << 8) + buf[2];
86 return 184 - 1 - tsp[4];
107 static inline int dvb_dmx_swfilter_payload(
struct dvb_demux_feed *feed,
136 static int dvb_dmx_swfilter_sectionfilter(
struct dvb_demux_feed *feed,
151 if (f->
doneq && !neq)
158 static inline int dvb_dmx_swfilter_section_feed(
struct dvb_demux_feed *feed)
163 int section_syntax_indicator;
172 section_syntax_indicator = ((sec->
secbuf[1] & 0x80) != 0);
173 if (section_syntax_indicator &&
179 if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
188 static void dvb_dmx_swfilter_section_new(
struct dvb_demux_feed *feed)
192 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
201 if (sec->
secbuf[0] != 0xff || sec->
secbuf[n - 1] != 0xff) {
202 printk(
"dvb_demux.c section ts padding loss: %d/%d\n",
204 printk(
"dvb_demux.c pad data:");
205 for (i = 0; i <
n; i++)
234 static int dvb_dmx_swfilter_section_copy_dump(
struct dvb_demux_feed *feed,
235 const u8 *buf,
u8 len)
245 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
246 printk(
"dvb_demux.c section buffer full loss: %d/%d\n",
272 || seclen + sec->
secbufp > limit)
278 dvb_dmx_swfilter_section_feed(feed);
279 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
281 printk(
"dvb_demux.c pusi not seen, discarding section data\n");
290 static int dvb_dmx_swfilter_section_packet(
struct dvb_demux_feed *feed,
305 ccok = ((feed->
cc + 1) & 0x0f) ==
cc;
310 if ((buf[4] > 0) && (buf[5] & 0x80))
315 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
316 printk(
"dvb_demux.c discontinuity detected %d bytes lost\n",
328 dvb_dmx_swfilter_section_new(feed);
333 if (count > 1 && buf[p] < count) {
334 const u8 *before = &buf[p + 1];
335 u8 before_len = buf[
p];
336 const u8 *
after = &before[before_len];
337 u8 after_len = count - 1 - before_len;
339 dvb_dmx_swfilter_section_copy_dump(feed, before,
343 dvb_dmx_swfilter_section_new(feed);
344 dvb_dmx_swfilter_section_copy_dump(feed, after,
347 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
349 printk(
"dvb_demux.c PUSI=1 but %d bytes lost\n", count);
353 dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
359 static inline void dvb_dmx_swfilter_packet_type(
struct dvb_demux_feed *feed,
362 switch (feed->
type) {
364 if (!feed->
feed.
ts.is_filtering)
368 dvb_dmx_swfilter_payload(feed, buf);
374 if (feed->
demux->write_to_decoder)
375 feed->
demux->write_to_decoder(feed, buf, 188);
379 if (!feed->
feed.
sec.is_filtering)
381 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
390 #define DVR_FEED(f) \
391 (((f)->type == DMX_TYPE_TS) && \
392 ((f)->feed.ts.is_filtering) && \
393 (((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET))
395 static void dvb_dmx_swfilter_packet(
struct dvb_demux *demux,
const u8 *buf)
401 if (dvb_demux_speedcheck) {
402 struct timespec cur_time, delta_time;
403 u64 speed_bytes, speed_timedelta;
413 delta_time = timespec_sub(cur_time,
418 speed_bytes = 1000 * div64_u64(speed_bytes,
421 (
u64)timespec_to_ns(&delta_time);
422 speed_timedelta = div64_u64(speed_timedelta,
425 div64_u64(speed_bytes,
436 "PID=0x%x data1=0x%x\n",
440 if (!dvb_demux_feed_err_pkts)
448 "PID=0x%x expected 0x%x "
459 if ((feed->
pid != pid) && (feed->
pid != 0x2000))
464 if ((
DVR_FEED(feed)) && (dvr_done++))
467 if (feed->
pid == pid)
468 dvb_dmx_swfilter_packet_type(feed, buf);
469 else if (feed->
pid == 0x2000)
477 spin_lock(&demux->
lock);
481 dvb_dmx_swfilter_packet(demux, buf);
485 spin_unlock(&demux->
lock);
490 static inline int find_next_packet(
const u8 *buf,
int pos,
size_t count,
495 while (pos < count) {
496 if (buf[pos] == 0x47 ||
497 (pktsize == 204 && buf[pos] == 0xB8))
505 int backtrack = pos - pktsize;
506 if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
507 (pktsize == 204 && buf[backtrack] == 0xB8)))
515 static inline void _dvb_dmx_swfilter(
struct dvb_demux *demux,
const u8 *buf,
516 size_t count,
const int pktsize)
521 spin_lock(&demux->
lock);
532 if (demux->
tsbuf[0] == 0x47)
533 dvb_dmx_swfilter_packet(demux, demux->
tsbuf);
539 p = find_next_packet(buf, p, count, pktsize);
542 if (count - p < pktsize)
547 if (pktsize == 204 && (*q == 0xB8)) {
549 demux->
tsbuf[0] = 0x47;
552 dvb_dmx_swfilter_packet(demux, q);
560 if (pktsize == 204 && demux->
tsbuf[0] == 0xB8)
561 demux->
tsbuf[0] = 0x47;
565 spin_unlock(&demux->
lock);
570 _dvb_dmx_swfilter(demux, buf, count, 188);
576 _dvb_dmx_swfilter(demux, buf, count, 204);
582 spin_lock(&demux->
lock);
586 spin_unlock(&demux->
lock);
610 for (i = 0; i < demux->
feednum; i++)
619 return &demux->
feed[
i];
635 spin_lock_irq(&feed->demux->lock);
636 if (dvb_demux_feed_find(feed)) {
637 printk(
KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
638 __func__, feed->type, feed->state, feed->pid);
642 list_add(&feed->list_head, &feed->demux->feed_list);
644 spin_unlock_irq(&feed->demux->lock);
649 spin_lock_irq(&feed->
demux->lock);
650 if (!(dvb_demux_feed_find(feed))) {
651 printk(
KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
658 spin_unlock_irq(&feed->
demux->lock);
690 dvb_demux_feed_add(feed);
716 static int dmx_ts_feed_start_filtering(
struct dmx_ts_feed *ts_feed)
740 spin_lock_irq(&demux->
lock);
743 spin_unlock_irq(&demux->
lock);
749 static int dmx_ts_feed_stop_filtering(
struct dmx_ts_feed *ts_feed)
769 spin_lock_irq(&demux->
lock);
772 spin_unlock_irq(&demux->
lock);
778 static int dvbdmx_allocate_ts_feed(
struct dmx_demux *
dmx,
788 if (!(feed = dvb_dmx_feed_alloc(demux))) {
800 (*ts_feed) = &feed->
feed.
ts;
801 (*ts_feed)->parent = dmx;
803 (*ts_feed)->is_filtering = 0;
804 (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;
805 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
806 (*ts_feed)->set = dmx_ts_feed_set;
808 if (!(feed->
filter = dvb_dmx_filter_alloc(demux))) {
823 static int dvbdmx_release_ts_feed(
struct dmx_demux *dmx,
843 dvb_demux_feed_del(feed);
868 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
874 spin_lock_irq(&dvbdemux->
lock);
875 *filter = &dvbdmxfilter->
filter;
876 (*filter)->parent =
feed;
877 (*filter)->priv =
NULL;
878 dvbdmxfilter->
feed = dvbdmxfeed;
882 dvbdmxfeed->
filter = dvbdmxfilter;
883 spin_unlock_irq(&dvbdemux->
lock);
890 u16 pid,
size_t circular_buffer_size,
902 dvb_demux_feed_add(dvbdmxfeed);
906 dvbdmxfeed->
feed.
sec.check_crc = check_crc;
912 if (!dvbdmxfeed->
buffer) {
930 if (!(f = dvbdmxfeed->
filter))
941 f->
doneq = doneq ? 1 : 0;
942 }
while ((f = f->
next));
959 if (!dvbdmxfeed->
filter) {
964 dvbdmxfeed->
feed.
sec.tsfeedp = 0;
966 dvbdmxfeed->
feed.
sec.secbufp = 0;
967 dvbdmxfeed->
feed.
sec.seclen = 0;
974 prepare_secfilters(dvbdmxfeed);
976 if ((ret = dvbdmx->
start_feed(dvbdmxfeed)) < 0) {
981 spin_lock_irq(&dvbdmx->
lock);
984 spin_unlock_irq(&dvbdmx->
lock);
1005 spin_lock_irq(&dvbdmx->
lock);
1008 spin_unlock_irq(&dvbdmx->
lock);
1023 if (dvbdmxfilter->
feed != dvbdmxfeed) {
1031 spin_lock_irq(&dvbdmx->
lock);
1034 if (f == dvbdmxfilter) {
1037 while (f->
next != dvbdmxfilter)
1043 spin_unlock_irq(&dvbdmx->
lock);
1048 static int dvbdmx_allocate_section_feed(
struct dmx_demux *demux,
1058 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
1065 dvbdmxfeed->
demux = dvbdmx;
1066 dvbdmxfeed->
pid = 0xffff;
1069 dvbdmxfeed->
feed.
sec.tsfeedp = 0;
1073 (*feed) = &dvbdmxfeed->
feed.
sec;
1074 (*feed)->is_filtering = 0;
1075 (*feed)->parent =
demux;
1076 (*feed)->priv =
NULL;
1078 (*feed)->set = dmx_section_feed_set;
1079 (*feed)->allocate_filter = dmx_section_feed_allocate_filter;
1080 (*feed)->start_filtering = dmx_section_feed_start_filtering;
1081 (*feed)->stop_filtering = dmx_section_feed_stop_filtering;
1082 (*feed)->release_filter = dmx_section_feed_release_filter;
1088 static int dvbdmx_release_section_feed(
struct dmx_demux *demux,
1106 dvb_demux_feed_del(dvbdmxfeed);
1108 dvbdmxfeed->
pid = 0xffff;
1118 static int dvbdmx_open(
struct dmx_demux *demux)
1129 static int dvbdmx_close(
struct dmx_demux *demux)
1133 if (dvbdemux->
users == 0)
1141 static int dvbdmx_write(
struct dmx_demux *demux,
const char __user *buf,
size_t count)
1165 static int dvbdmx_add_frontend(
struct dmx_demux *demux,
1176 static int dvbdmx_remove_frontend(
struct dmx_demux *demux,
1202 static int dvbdmx_connect_frontend(
struct dmx_demux *demux,
1217 static int dvbdmx_disconnect_frontend(
struct dmx_demux *demux)
1242 dvbdemux->
users = 0;
1249 if (!dvbdemux->
feed) {
1254 for (i = 0; i < dvbdemux->
filternum; i++) {
1258 for (i = 0; i < dvbdemux->
feednum; i++) {
1260 dvbdemux->
feed[
i].index =
i;
1271 dvbdemux->
pids[
i] = 0xffff;
1284 dvbdemux->
memcopy = dvb_dmx_memcopy;
1287 dmx->
priv = dvbdemux;
1288 dmx->
open = dvbdmx_open;
1289 dmx->
close = dvbdmx_close;
1290 dmx->
write = dvbdmx_write;