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