Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: Losless Section Demux version 1.4



> definitely valid - otherwise you could not use them for robust firmware 
> updates, DSMCC and MHP downloads etc.

Here's my try to chop off the individual memcopy's but althought
the code looks great and it's even not so cumbersome as I first
thouhgt, it doesn't work. :(. Let it lurk anyway, here maybe more
eyes can see more

Emard
--- /usr/local/src/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c	2003-12-30 13:58:16.000000000 +0100
+++ dvb_demux.c	2003-12-30 19:21:45.000000000 +0100
@@ -259,7 +259,7 @@ static int dvb_dmx_swfilter_section_copy
 {
 	struct dvb_demux *demux = feed->demux;
 	struct dmx_section_feed *sec = &feed->feed.sec;
-	u16 limit, seclen, n;
+	u16 limit, seclen, n, rest, offset;
 
 	if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
 		return 0;
@@ -276,7 +276,106 @@ static int dvb_dmx_swfilter_section_copy
 	if(len <= 0)
 		return 0;
 
-	demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
+	/* use cumbersome code for slow CPU that must 
+	** calculate crc on-the-fly during demux->memcopy()
+	** fast CPU better not execute cumbersome code
+	*/
+	if(1 == 1)
+	{
+		/* cumbersome code starts here */
+		if(len < 2)
+		{
+			/* boundary condition - here's the best we can do */
+			demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
+			goto proceed_dump;
+		}
+		/* enough bytes to patch the boundary condition, 
+		** caution, this memcpy must be normal (no crc yet) 
+		*/
+		memcpy(sec->secbuf_base + sec->tsfeedp, buf, 2);
+
+		limit = sec->tsfeedp;
+		/* to be sure always set secbuf */
+		sec->secbuf = sec->secbuf_base + sec->secbufp;
+
+		/* processing stale data in buffer...
+		** who knows in which state we are left so better
+		** flush remnants if any. This for() loop should
+		** in most cases be run only just to calculate 'rest'
+		** and goto copy_limited;
+		** for() it's is here also to gracefully clean up after
+		** internal errors if they should ever happen
+		*/
+		for(rest = 0; sec->secbufp < limit; )
+		{
+			seclen = section_length(sec->secbuf);
+			if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE)
+				return 0;
+			if(seclen + sec->secbufp > limit)
+			{
+				/* (rest = how many bytes from new buffer should be
+				** appended to the secbuf to get one complete section)
+				*/
+				rest = seclen + sec->secbufp - limit;
+				goto copy_limited;
+			}
+			/* internal error probably occured, try to
+			** gracefully fix the situation. We must reset
+			** crc though, in the given circumstances we
+			** can only dump correct data but without having
+			** correct crc from memcopy()
+			*/
+			sec->seclen = seclen;
+			sec->crc_val = ~0;
+			/* dump [secbuf .. secbuf+seclen) */
+			dvb_dmx_swfilter_section_feed(feed);
+			sec->secbufp += seclen; /* secbufp and secbuf moving together is */
+			sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
+		}
+	copy_limited:;
+		/* at this point, we enter the for()
+		** loop with correct number of 'rest' bytes that
+		** should be copied from the new buffer to the
+		** secbufp to complete the section at the boundary
+		** condition between data in secbufp and secbuf
+		** offset is offset to tne new buffer that is
+		** memcopyed each section separately with crc 
+		** reset inbetween them
+		*/
+		for(offset = 0; offset + rest <= len &&
+			        sec->secbufp + rest <= DMX_MAX_SECFEED_SIZE; )
+		{		
+			if(rest > 0)
+			{
+				demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf + offset, rest);
+				offset += rest;
+				sec->tsfeedp += rest;
+
+				limit = sec->tsfeedp;
+				if(limit > DMX_MAX_SECFEED_SIZE)
+					return -1;
+
+				seclen = section_length(sec->secbuf);
+				if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 
+				   || seclen + sec->secbufp > limit)
+					return 0;
+		       
+				/* dump [secbuf .. secbuf+seclen) */
+				dvb_dmx_swfilter_section_feed(feed);
+				sec->secbufp += seclen; /* secbufp and secbuf moving together is */
+				sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
+				sec->crc_val = ~0; /* after feed, reset crc for the next section */
+			}
+			rest = section_length(buf + offset);
+			if(rest <= 0)
+				return 0;
+		}
+		return 0;
+	}
+
+	// demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
+	memcpy(sec->secbuf_base + sec->tsfeedp, buf, len);
+ proceed_dump:;
 	sec->tsfeedp += len;
 
 	/* -----------------------------------------------------
@@ -287,6 +386,7 @@ static int dvb_dmx_swfilter_section_copy
 	if(limit > DMX_MAX_SECFEED_SIZE)
 		return -1; /* internal error should never happen */
 
+
 	/* to be sure always set secbuf */
 	sec->secbuf = sec->secbuf_base + sec->secbufp;
 

Home | Main Index | Thread Index