Mailing List archive

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

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



Emard wrote:
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
isn't it possible to use the generic ringbuffer implementation for these purposes (maybe it has to change a little - but this should not be a real problem - )?

Holger



------------------------------------------------------------------------

--- /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;



--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index