Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] [PATCH] support for multiple feeds per pid
hi,
the attached patch gets rid of the pid2feed array in struct dvb_demux by
using the doubly linked list implementation from linux/list.h.
this should allow multiple clients to get data from the same pid, e.g.
getting a pid from the dvr device while having the same pid sent to the
mpeg decoder.
i am quite sure that this patch has bugs, because due to not having a
satellite dish at the moment, i am not able to test it. so it would be
nice if you could have a look at it and test it, before it is applied to
cvs. however, it is possible to compile it. :-)
the patch is against dvb-kernel and does not apply to DVB.
i do not know, whether multiple section feeds from one pid were possible
before. at least i thought so, but i do not really remember exactly.
please test if they still work, too, besides testing ts feeds. :-)
best regards,
andreas
Index: dvb_demux.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c,v
retrieving revision 1.13
diff -p -u -r1.13 dvb_demux.c
--- dvb_demux.c 22 Jan 2003 11:10:33 -0000 1.13
+++ dvb_demux.c 16 Feb 2003 03:21:42 -0000
@@ -451,23 +451,30 @@ void dvb_dmx_swfilter_packet_type(struct
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;
+ struct dvb_demux_feed *feed;
+ struct list_head *pos, *head=&demux->feed_list;
+ u16 pid = ts_pid(buf);
- dvb_dmx_swfilter_packet_type (feed, 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);
+ }
}
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, int count)
{
struct dvb_demux_feed *feed;
+ struct list_head *pos, *head=&demux->feed_list;
spin_lock(&demux->lock);
- if ((feed = demux->pid2feed[0x2000]))
- feed->cb.ts(buf, count*188, 0, 0, &feed->feed.ts, DMX_OK);
+ list_for_each(pos, head) {
+ feed = list_entry(pos, struct dvb_demux_feed, list_head);
+ if (feed->pid == 0x2000)
+ feed->cb.ts(buf, count*188, 0, 0, &feed->feed.ts, DMX_OK);
+ }
while (count) {
dvb_dmx_swfilter_packet(demux, buf);
@@ -551,21 +558,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 +772,7 @@ int dvbdmx_release_ts_feed(dmx_demux_t *
{
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 +793,12 @@ int dvbdmx_release_ts_feed(dmx_demux_t *
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 +851,7 @@ dmx_section_feed_set(struct dmx_section_
{
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 +859,14 @@ dmx_section_feed_set(struct dmx_section_
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 +1052,7 @@ static int dvbdmx_release_section_feed(d
{
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 +1068,16 @@ static int dvbdmx_release_section_feed(d
}
#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 +1237,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)
Index: dvb_demux.h
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.h,v
retrieving revision 1.10
diff -p -u -r1.10 dvb_demux.h
--- dvb_demux.h 22 Jan 2003 11:10:33 -0000 1.10
+++ dvb_demux.h 16 Feb 2003 03:21:42 -0000
@@ -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;
Home |
Main Index |
Thread Index