--- margi2/dvb_demux.c 2001/03/06 23:44:34 1.1 +++ margi2/dvb_demux.c 2001/03/08 01:41:26 1.2 @@ -75,43 +75,30 @@ struct list_head *dmx_get_demuxes(void) return &dmx_muxs; } -static int dmx_section_feed_stop_filtering(struct dmx_section_feed_s* feed); - /****************************************************************************** * static inlined helper functions ******************************************************************************/ -/* NOTE: these might not work on some arhictectures due to missing alignment */ - - static inline u16 section_length(const u8 *buf) { - return 3+(0xfff&ntohs(*(u16 *)(buf+1))); + return 3+((buf[1]&0x0f)<<8)+buf[2]; } static inline u16 ts_pid(const u8 *buf) { - return (0x1fff&ntohs(*(u16 *)(buf+1))); + return ((buf[1]&0x1f)<<8)+buf[2]; } static inline int -payload(const u8 *tsp, const u8 **data) +payload(const u8 *tsp) { - int len=184; - *data=tsp; - if (!(tsp[3]&0x10)) // no payload? return 0; - - if (tsp[3]&0x20) { // adaptation field? - int aflen=tsp[4]+1; - - len-=aflen; - *data+=aflen; - } - return len; + if (tsp[3]&0x20) // adaptation field? + return 184-1-tsp[4]; + return 184; } /****************************************************************************** @@ -121,26 +108,19 @@ payload(const u8 *tsp, const u8 **data) static inline int DvbDmxSWFilterPayload(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) { - int p=4, count=184, ccok; + int p, count, ccok; - if (!(buf[3]&0x10)) // no payload? + if (!(count=payload(buf))) return -1; - - if (buf[3]&0x20) { // adaptation field? - count-=buf[4]+1; - p+=buf[4]+1; - } - + p=188-count; ccok=((dvbdmxfeed->cc+1)&0x0f)==(buf[3]&0x0f) ? 1 : 0; dvbdmxfeed->cc=buf[3]&0x0f; - - /* + /* if (!ccok) printk("missed packet!\n"); */ - if (buf[1]&0x40) { // PUSI ? + if (buf[1]&0x40) // PUSI ? dvbdmxfeed->peslen=0xfffa; - } dvbdmxfeed->peslen+=count; return dvbdmxfeed->cb.ts((u8 *)&buf[p], count, 0, 0, @@ -211,24 +191,28 @@ DvbDmxSWFilterSectionFeed(dvb_demux_feed static inline int DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) { - int p=4, count=184, ccok=0, rest=0; + int p, count; + int ccok, rest; - if (!(buf[3]&0x10)) // no payload? + if (!(count=payload(buf))) return -1; - - if (buf[3]&0x20) { // adaptation field? - count-=buf[4]+1; - p+=buf[4]+1; - } - + p=188-count; ccok=((dvbdmxfeed->cc+1)&0x0f)==(buf[3]&0x0f) ? 1 : 0; dvbdmxfeed->cc=buf[3]&0x0f; - //printk ("function : %s payload=%d ccok=%d\n", __FUNCTION__, count, ccok); - - if (buf[1]&0x40) { // PUSI set - if (buf[p] && ccok) { + if (buf[1]&0x40) { // PUSI set -- a section begins in this packet + // offset to start of first section is in buf[p] + + if (buf[p] && ccok) { // rest of previous section? + + // did we have enough data in last packet to calc length? + if (dvbdmxfeed->secbufp && dvbdmxfeed->secbufp<3) { + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, + buf+p+1, + 3-dvbdmxfeed->secbufp); + dvbdmxfeed->seclen=section_length(dvbdmxfeed->secbuf); + } rest=dvbdmxfeed->seclen-dvbdmxfeed->secbufp; if (rest==buf[p] && dvbdmxfeed->seclen) { memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, @@ -237,39 +221,50 @@ DvbDmxSWFilterSectionPacket(dvb_demux_fe DvbDmxSWFilterSectionFeed(dvbdmxfeed); } } - p+=buf[p]+1; - count-=buf[p]+1; + p+=buf[p]+1; // skip rest of last section + count=188-p; while (count>0) { - if ((count>2) && + if ((count>2) && // enough data to determine sec length? ((dvbdmxfeed->seclen=section_length(buf+p))<=count)) { memcpy(dvbdmxfeed->secbuf, buf+p, dvbdmxfeed->seclen); dvbdmxfeed->secbufp=dvbdmxfeed->seclen; - count-=dvbdmxfeed->seclen; p+=dvbdmxfeed->seclen; + count=188-p; DvbDmxSWFilterSectionFeed(dvbdmxfeed); - } else { + + // filling bytes until packet end? + if (buf[p]==0xff) + count=0; + } else { // section continues to following ts block memcpy(dvbdmxfeed->secbuf, buf+p, count); + dvbdmxfeed->secbufp+=count; count=0; } - if (buf[p]==0xff) - count=0; } - } else { + } else { // section continued below if (!ccok) return -1; + if (!dvbdmxfeed->secbufp) // any data in last ts packet? + return -1; + // did we have enough data in last packet to calc section length? if (dvbdmxfeed->secbufp<3) { - memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, count); + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, + 3-dvbdmxfeed->secbufp); dvbdmxfeed->seclen=section_length(dvbdmxfeed->secbuf); - dvbdmxfeed->secbufp+=count; - return DvbDmxSWFilterSectionFeed(dvbdmxfeed); } rest=dvbdmxfeed->seclen-dvbdmxfeed->secbufp; - if (!dvbdmxfeed->seclen || rest<0 || restsecbuf+dvbdmxfeed->secbufp, buf+p, count); - dvbdmxfeed->secbufp+=count; - return DvbDmxSWFilterSectionFeed(dvbdmxfeed); + if (rest<=count) { // section completed in this ts block + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, rest); + dvbdmxfeed->secbufp+=rest; + DvbDmxSWFilterSectionFeed(dvbdmxfeed); + } else { // section continues in following ts block + memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, count); + dvbdmxfeed->secbufp+=count; + } + } return 0; } @@ -545,7 +540,7 @@ static int dvbdmx_release_ts_feed(dmx_de if (dvbdmxfeed->state==DMX_STATE_FREE) return -EINVAL; - if (dvbdmxfeed->buffer) + if (dvbdmxfeed->buffer) vfree(dvbdmxfeed->buffer); dvbdmxfeed->buffer=0; dvbdmxfeed->state=DMX_STATE_FREE; @@ -708,7 +703,8 @@ dmx_section_feed_release_filter(dmx_sect if (dvbdmxfilter->feed!=dvbdmxfeed) return -EINVAL; if (feed->is_filtering) - return -EBUSY; + feed->stop_filtering(feed); + //return -EBUSY; f=dvbdmxfeed->filter; if (f==dvbdmxfeed->filter)