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