diff options
author | Andreas Oberritter <devnull@localhost> | 2003-02-17 11:41:47 +0000 |
---|---|---|
committer | Andreas Oberritter <devnull@localhost> | 2003-02-17 11:41:47 +0000 |
commit | 218b5ed2dd2770dff18c55b0c813ade613293a1d (patch) | |
tree | 2c1056896773451e677866f85c5084bd5095b92d /linux/drivers | |
parent | 270f03e0f9d6fa16328d02469cf272bf90912ad3 (diff) | |
download | mediapointer-dvb-s2-218b5ed2dd2770dff18c55b0c813ade613293a1d.tar.gz mediapointer-dvb-s2-218b5ed2dd2770dff18c55b0c813ade613293a1d.tar.bz2 |
replaced pid2feed array by linked list, allow multiple
clients to use the same pid
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dmxdev.c | 5 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_demux.c | 89 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_demux.h | 8 |
3 files changed, 59 insertions, 43 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index a097a0858..af4d267d8 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -581,9 +581,8 @@ dvb_dmxdev_filter_start(dmxdev_filter_t *filter) /* find active filter/feed with same PID */ for (i=0; i<dmxdev->filternum; i++) { if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && - dmxdev->filter[i].pid == para->pid) { - if (dmxdev->filter[i].type != DMXDEV_TYPE_SEC) - return -EBUSY; + dmxdev->filter[i].pid == para->pid && + dmxdev->filter[i].type == DMXDEV_TYPE_SEC) { *secfeed = dmxdev->filter[i].feed.sec; break; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index d2147ed9f..6eb5cf663 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -451,27 +451,26 @@ void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf) void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) { - struct dvb_demux_feed *feed = demux->pid2feed[ts_pid(buf)]; - - if (!feed) - return; - - dvb_dmx_swfilter_packet_type (feed, buf); + struct dvb_demux_feed *feed; + struct list_head *pos, *head=&demux->feed_list; + u16 pid = ts_pid(buf); + + list_for_each(pos, head) { + feed = list_entry(pos, struct dvb_demux_feed, list_head); + if (feed->pid == pid) + dvb_dmx_swfilter_packet_type (feed, buf); + if (feed->pid == 0x2000) + feed->cb.ts(buf, 188, 0, 0, &feed->feed.ts, DMX_OK); + } } -void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, int count) +void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - struct dvb_demux_feed *feed; - spin_lock(&demux->lock); - if ((feed = demux->pid2feed[0x2000])) - feed->cb.ts(buf, count*188, 0, 0, &feed->feed.ts, DMX_OK); - - while (count) { + while (count--) { dvb_dmx_swfilter_packet(demux, buf); - count--; buf += 188; } @@ -551,21 +550,22 @@ static int dmx_pid_set (u16 pid, struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct dvb_demux_feed **pid2feed = demux->pid2feed; + struct list_head *pos, *n, *head=&demux->feed_list; if (pid > DMX_MAX_PID) return -EINVAL; - if (feed->pid != 0xffff) { - if (feed->pid <= DMX_MAX_PID) - pid2feed[feed->pid] = 0; - feed->pid = 0xffff; - } + if (pid == feed->pid) + return 0; - if (pid2feed[pid]) - return -EBUSY; + if (feed->pid <= DMX_MAX_PID) + list_for_each_safe(pos, n, head) + if (DMX_FEED_ENTRY(pos)->pid == feed->pid) { + list_del(pos); + break; + } - pid2feed[pid] = feed; + list_add(&feed->list_head, head); feed->pid = pid; return 0; @@ -764,6 +764,7 @@ int dvbdmx_release_ts_feed(dmx_demux_t *dmx, dmx_ts_feed_t *ts_feed) { struct dvb_demux *demux = (struct dvb_demux *) dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; + struct list_head *pos, *n, *head=&demux->feed_list; if (down_interruptible (&demux->mutex)) return -ERESTARTSYS; @@ -784,8 +785,12 @@ int dvbdmx_release_ts_feed(dmx_demux_t *dmx, dmx_ts_feed_t *ts_feed) feed->filter->state = DMX_STATE_FREE; if (feed->pid <= DMX_MAX_PID) { - feed->demux->pid2feed[feed->pid]=0; - feed->pid=0xffff; + list_for_each_safe(pos, n, head) + if (DMX_FEED_ENTRY(pos)->pid == feed->pid) { + list_del(pos); + break; + } + feed->pid = 0xffff; } if (feed->ts_type & TS_DECODER) @@ -838,6 +843,7 @@ dmx_section_feed_set(struct dmx_section_feed_s* feed, { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=dvbdmxfeed->demux; + struct list_head *pos, *n, *head=&dvbdmx->feed_list; if (pid>0x1fff) return -EINVAL; @@ -845,15 +851,14 @@ dmx_section_feed_set(struct dmx_section_feed_s* feed, if (down_interruptible (&dvbdmx->mutex)) return -ERESTARTSYS; - if (dvbdmxfeed->pid!=0xffff) { - dvbdmx->pid2feed[dvbdmxfeed->pid]=0; - dvbdmxfeed->pid=0xffff; - } - if (dvbdmx->pid2feed[pid]) { - up(&dvbdmx->mutex); - return -EBUSY; - } - dvbdmx->pid2feed[pid]=dvbdmxfeed; + if (dvbdmxfeed->pid <= DMX_MAX_PID) + list_for_each_safe(pos, n, head) + if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) { + list_del(pos); + break; + } + + list_add(&dvbdmxfeed->list_head, head); dvbdmxfeed->pid=pid; dvbdmxfeed->buffer_size=circular_buffer_size; @@ -1039,6 +1044,7 @@ static int dvbdmx_release_section_feed(dmx_demux_t *demux, { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=(struct dvb_demux *) demux; + struct list_head *pos, *n, *head=&dvbdmx->feed_list; if (down_interruptible (&dvbdmx->mutex)) return -ERESTARTSYS; @@ -1054,9 +1060,16 @@ static int dvbdmx_release_section_feed(dmx_demux_t *demux, } #endif dvbdmxfeed->state=DMX_STATE_FREE; - dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; - if (dvbdmxfeed->pid!=0xffff) - dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0; + + if (dvbdmxfeed->pid <= DMX_MAX_PID) { + list_for_each_safe(pos, n, head) + if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) { + list_del(pos); + break; + } + dvbdmxfeed->pid = 0xffff; + } + up(&dvbdmx->mutex); return 0; } @@ -1216,7 +1229,7 @@ dvb_dmx_init(struct dvb_demux *dvbdemux) dvbdemux->pids[i]=0xffff; } dvbdemux->playing=dvbdemux->recording=0; - memset(dvbdemux->pid2feed, 0, (DMX_MAX_PID+1)*sizeof(struct dvb_demux_feed *)); + INIT_LIST_HEAD(&dvbdemux->feed_list); dvbdemux->tsbufp=0; if (!dvbdemux->check_crc32) diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.h b/linux/drivers/media/dvb/dvb-core/dvb_demux.h index 1e4f877ab..344a126b9 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.h @@ -62,6 +62,8 @@ struct dvb_demux_filter { }; +#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head) + struct dvb_demux_feed { union { dmx_ts_feed_t ts; @@ -92,6 +94,8 @@ struct dvb_demux_feed { int cc; u16 peslen; + + struct list_head list_head; }; struct dvb_demux { @@ -121,7 +125,7 @@ struct dvb_demux { int recording; #define DMX_MAX_PID 0x2000 - struct dvb_demux_feed *pid2feed[DMX_MAX_PID+1]; + struct list_head feed_list; u8 tsbuf[188]; int tsbufp; @@ -133,7 +137,7 @@ struct dvb_demux { int dvb_dmx_init(struct dvb_demux *dvbdemux); int dvb_dmx_release(struct dvb_demux *dvbdemux); void dvb_dmx_swfilter_packet(struct dvb_demux *dvbdmx, const u8 *buf); -void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, int count); +void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count); #endif /* _DVB_DEMUX_H_ */ |