summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
authorAndreas Oberritter <devnull@localhost>2003-02-17 11:41:47 +0000
committerAndreas Oberritter <devnull@localhost>2003-02-17 11:41:47 +0000
commit218b5ed2dd2770dff18c55b0c813ade613293a1d (patch)
tree2c1056896773451e677866f85c5084bd5095b92d /linux/drivers
parent270f03e0f9d6fa16328d02469cf272bf90912ad3 (diff)
downloadmediapointer-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.c5
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_demux.c89
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_demux.h8
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_ */