diff --git a/device.c b/device.c index 4fa8c93..610348b 100644 --- a/device.c +++ b/device.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.c,v 1.38 2007/09/24 16:10:19 ajhseppa Exp $ + * $Id: device.c,v 1.39 2007/09/24 17:20:58 rahrenbe Exp $ */ #include "common.h" @@ -34,7 +34,6 @@ cIptvDevice::cIptvDevice(unsigned int Index) pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex); // Initialize filter pointers memset(&secfilters, '\0', sizeof(secfilters)); - StartSectionHandler(); } @@ -45,7 +44,7 @@ cIptvDevice::~cIptvDevice() delete pUdpProtocol; delete tsBuffer; // Destroy all filters - for (int i = 0; i < eMaxFilterCount; ++i) + for (int i = 0; i < eMaxSecFilterCount; ++i) DeleteFilter(i); } @@ -155,7 +154,7 @@ bool cIptvDevice::SetPid(cPidHandle *Handle, int Type, bool On) bool cIptvDevice::DeleteFilter(unsigned int Index) { - if ((Index < eMaxFilterCount) && secfilters[Index]) { + if ((Index < eMaxSecFilterCount) && secfilters[Index]) { debug("cIptvDevice::DeleteFilter(%d) Index=%d\n", deviceIndex, Index); delete secfilters[Index]; secfilters[Index] = NULL; @@ -167,12 +166,10 @@ bool cIptvDevice::DeleteFilter(unsigned int Index) int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) { // Search the next free filter slot - for (unsigned int i = 0; i < eMaxFilterCount; ++i) { + for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { if (!secfilters[i]) { debug("cIptvDevice::OpenFilter(%d): Pid=%d Tid=%02X Mask=%02X Index=%d\n", deviceIndex, Pid, Tid, Mask, i); - - secfilters[i] = new cIptvSectionFilter(i, deviceIndex, Pid, Tid, - Mask); + secfilters[i] = new cIptvSectionFilter(i, deviceIndex, Pid, Tid, Mask); return secfilters[i]->GetReadDesc(); } } @@ -183,7 +180,7 @@ int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) bool cIptvDevice::CloseFilter(int Handle) { debug("cIptvDevice::CloseFilter(%d): %d\n", deviceIndex, Handle); - for (unsigned int i = 0; i < eMaxFilterCount; ++i) { + for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { if (secfilters[i] && Handle == secfilters[i]->GetReadDesc()) return DeleteFilter(i); } @@ -260,10 +257,9 @@ bool cIptvDevice::GetTSPacket(uchar *&Data) isPacketDelivered = true; Data = p; // Run the data through all filters - for (unsigned int i = 0; i < eMaxFilterCount; ++i) { - if (secfilters[i]) { + for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { + if (secfilters[i]) secfilters[i]->ProcessData(p); - } } return true; } diff --git a/device.h b/device.h index d0e5a3e..87703b6 100644 --- a/device.h +++ b/device.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.h,v 1.16 2007/09/24 13:03:38 ajhseppa Exp $ + * $Id: device.h,v 1.17 2007/09/24 17:20:58 rahrenbe Exp $ */ #ifndef __IPTV_DEVICE_H @@ -11,14 +11,11 @@ #include #include "protocoludp.h" -//#include "protocolrtsp.h" #include "protocolhttp.h" #include "protocolfile.h" #include "streamer.h" - #include "sectionfilter.h" - class cIptvDevice : public cDevice { // static ones public: @@ -30,7 +27,7 @@ public: // private parts private: enum { - eMaxFilterCount = 32, + eMaxSecFilterCount = 32 }; unsigned int deviceIndex; bool isPacketDelivered; @@ -42,7 +39,7 @@ private: cIptvProtocolFile *pFileProtocol; cIptvStreamer *pIptvStreamer; cMutex mutex; - cIptvSectionFilter* secfilters[eMaxFilterCount]; + cIptvSectionFilter* secfilters[eMaxSecFilterCount]; // constructor & destructor public: @@ -83,4 +80,3 @@ public: }; #endif // __IPTV_DEVICE_H - diff --git a/sectionfilter.c b/sectionfilter.c index 7876c04..c29b1a6 100644 --- a/sectionfilter.c +++ b/sectionfilter.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: sectionfilter.c,v 1.2 2007/09/24 16:08:09 ajhseppa Exp $ + * $Id: sectionfilter.c,v 1.3 2007/09/24 17:20:58 rahrenbe Exp $ */ #include "sectionfilter.h" @@ -12,19 +12,18 @@ cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd, u_short Pid, u_char Tid, u_char Mask) - : pusi_seen(0), - feedcc(0), - doneq(0), - secbuf(NULL), - secbufp(0), - seclen(0), - tsfeedp(0), - crc_val(0), - pid(Pid), - id(Index) +: pusi_seen(0), + feedcc(0), + doneq(0), + secbuf(NULL), + secbufp(0), + seclen(0), + tsfeedp(0), + crc_val(0), + pid(Pid), + id(Index) { debug("cIptvSectionFilter::cIptvSectionFilter(%d)\n", Index); - memset(secbuf_base, '\0', sizeof(secbuf_base)); memset(filter_value, '\0', sizeof(filter_value)); memset(filter_mask, '\0', sizeof(filter_mask)); @@ -97,21 +96,21 @@ inline uint16_t cIptvSectionFilter::ts_pid(const uint8_t *buf) inline uint8_t cIptvSectionFilter::payload(const uint8_t *tsp) { if (!(tsp[3] & 0x10)) // no payload? - return 0; + return 0; if (tsp[3] & 0x20) { // adaptation field? - if (tsp[4] > 183) // corrupted data? - return 0; - else - return 184 - 1 - tsp[4]; - } + if (tsp[4] > 183) // corrupted data? + return 0; + else + return 184 - 1 - tsp[4]; + } return 184; } int cIptvSectionFilter::dvb_dmxdev_section_callback(const uint8_t *buffer1, size_t buffer1_len, - const uint8_t *buffer2, size_t buffer2_len, - enum dmx_success success) + const uint8_t *buffer2, size_t buffer2_len, + enum dmx_success success) { struct timeval tv; tv.tv_sec = 0; @@ -123,30 +122,26 @@ int cIptvSectionFilter::dvb_dmxdev_section_callback(const uint8_t *buffer1, size // Check if error if (retval < 0) { - char tmp[64]; - error("ERROR: select(): %s", strerror_r(errno, tmp, sizeof(tmp))); - } + char tmp[64]; + error("ERROR: select(): %s", strerror_r(errno, tmp, sizeof(tmp))); + } // There is no data in the fifo, more can be written else if (!retval) { #ifdef DEBUG_PRINTF - printf("id = %d, pid %d would now write %d data to buffer\n", id, pid, buffer1_len); - for (unsigned int i = 0; i < buffer1_len; ++i) { - printf("0x%X ", buffer1[i]); - } - printf("\n"); + printf("id = %d, pid %d would now write %d data to buffer\n", id, pid, buffer1_len); + for (unsigned int i = 0; i < buffer1_len; ++i) + printf("0x%X ", buffer1[i]); + printf("\n"); #endif - - retval = write(fifoDescriptor, buffer1, buffer1_len); - - if (retval < 0) { - char tmp[64]; - error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp))); - } - } + retval = write(fifoDescriptor, buffer1, buffer1_len); + if (retval < 0) { + char tmp[64]; + error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp))); + } + } #ifdef DEBUG_PRINTF - else if (retval) { - printf("id %d pid %d data is already present\n", id, pid); - } + else if (retval) + printf("id %d pid %d data is already present\n", id, pid); #endif return 0; } @@ -157,64 +152,56 @@ void cIptvSectionFilter::dvb_dmx_swfilter_section_new() { #ifdef DVB_DEMUX_SECTION_LOSS_LOG if (secbufp < tsfeedp) { - int i, n = tsfeedp - secbufp; - - /* - * Section padding is done with 0xff bytes entirely. - * Due to speed reasons, we won't check all of them - * but just first and last. - */ - if (secbuf[0] != 0xff || secbuf[n - 1] != 0xff) { - printf("dvb_demux.c section ts padding loss: %d/%d\n", - n, tsfeedp); - printf("dvb_demux.c pad data:"); - for (i = 0; i < n; i++) - printf(" %02x", secbuf[i]); - printf("\n"); - } - } + int i, n = tsfeedp - secbufp; + /* + * Section padding is done with 0xff bytes entirely. + * Due to speed reasons, we won't check all of them + * but just first and last. + */ + if (secbuf[0] != 0xff || secbuf[n - 1] != 0xff) { + printf("dvb_demux.c section ts padding loss: %d/%d\n", + n, tsfeedp); + printf("dvb_demux.c pad data:"); + for (i = 0; i < n; i++) + printf(" %02x", secbuf[i]); + printf("\n"); + } + } #endif - tsfeedp = secbufp = seclen = 0; secbuf = secbuf_base; } - int cIptvSectionFilter::dvb_dmx_swfilter_sectionfilter() { uint8_t neq = 0; int i; for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { - uint8_t local_xor = filter_value[i] ^ secbuf[i]; - - if (maskandmode[i] & local_xor) { + uint8_t local_xor = filter_value[i] ^ secbuf[i]; + if (maskandmode[i] & local_xor) { #ifdef DEBUG_PRINTF - printf("maskandmode discard\n"); + printf("maskandmode discard\n"); #endif - return 0; - } - - neq |= maskandnotmode[i] & local_xor; - } + return 0; + } + neq |= maskandnotmode[i] & local_xor; + } if (doneq && !neq) { #ifdef DEBUG_PRINTF - printf("doneq discard, doneq = 0x%X, neq = 0x%X\n", doneq, !neq); + printf("doneq discard, doneq = 0x%X, neq = 0x%X\n", doneq, !neq); #endif - return 0; - } - + return 0; + } return dvb_dmxdev_section_callback(secbuf, seclen, NULL, 0, DMX_OK); } inline int cIptvSectionFilter::dvb_dmx_swfilter_section_feed() { if (dvb_dmx_swfilter_sectionfilter() < 0) - return -1; - + return -1; seclen = 0; - return 0; } @@ -222,20 +209,20 @@ int cIptvSectionFilter::dvb_dmx_swfilter_section_copy_dump(const uint8_t *buf, u { uint16_t limit, seclen_local, n; - if (tsfeedp >= DMX_MAX_SECFEED_SIZE) { - return 0; - } + if (tsfeedp >= DMX_MAX_SECFEED_SIZE) + return 0; + if (tsfeedp + len > DMX_MAX_SECFEED_SIZE) { #ifdef DVB_DEMUX_SECTION_LOSS_LOG - printf("dvb_demux.c section buffer full loss: %d/%d\n", - tsfeedp + len - DMX_MAX_SECFEED_SIZE, - DMX_MAX_SECFEED_SIZE); + printf("dvb_demux.c section buffer full loss: %d/%d\n", + tsfeedp + len - DMX_MAX_SECFEED_SIZE, + DMX_MAX_SECFEED_SIZE); #endif - len = DMX_MAX_SECFEED_SIZE - tsfeedp; - } + len = DMX_MAX_SECFEED_SIZE - tsfeedp; + } if (len <= 0) - return 0; + return 0; memcpy(secbuf_base + tsfeedp, buf, len); tsfeedp += len; @@ -244,55 +231,50 @@ int cIptvSectionFilter::dvb_dmx_swfilter_section_copy_dump(const uint8_t *buf, u * Dump all the sections we can find in the data (Emard) */ limit = tsfeedp; - if (limit > DMX_MAX_SECFEED_SIZE) { - return -1; /* internal error should never happen */ - } + if (limit > DMX_MAX_SECFEED_SIZE) + return -1; /* internal error should never happen */ /* to be sure always set secbuf */ secbuf = secbuf_base + secbufp; for (n = 0; secbufp + 2 < limit; n++) { - seclen_local = section_length(secbuf); - if (seclen_local <= 0 || seclen_local > DMX_MAX_SECTION_SIZE - || seclen_local + secbufp > limit) { - return 0; - } + seclen_local = section_length(secbuf); + if (seclen_local <= 0 || seclen_local > DMX_MAX_SECTION_SIZE || + seclen_local + secbufp > limit) + return 0; #ifdef DEBUG_PRINTF - printf("Non-mismatching seclen! %d, limit = %d\n", seclen_local, limit); + printf("Non-mismatching seclen! %d, limit = %d\n", seclen_local, limit); #endif - seclen = seclen_local; - crc_val = ~0; - /* dump [secbuf .. secbuf+seclen) */ - if (pusi_seen) { - dvb_dmx_swfilter_section_feed(); - } + seclen = seclen_local; + crc_val = ~0; + /* dump [secbuf .. secbuf+seclen) */ + if (pusi_seen) + dvb_dmx_swfilter_section_feed(); #ifdef DVB_DEMUX_SECTION_LOSS_LOG - else - printf("dvb_demux.c pusi not seen, discarding section data\n"); + else + printf("dvb_demux.c pusi not seen, discarding section data\n"); #endif - secbufp += seclen_local; /* secbufp and secbuf moving together is */ - secbuf += seclen_local; /* redundant but saves pointer arithmetic */ - } - + secbufp += seclen_local; /* secbufp and secbuf moving together is */ + secbuf += seclen_local; /* redundant but saves pointer arithmetic */ + } return 0; } - void cIptvSectionFilter::ProcessData(const uint8_t* buf) { if (buf[0] != 0x47) { - error("Not TS packet: 0x%X\n", buf[0]); - return; - } + error("Not TS packet: 0x%X\n", buf[0]); + return; + } // Stop if not the PID this filter is looking for if (ts_pid(buf) != pid) - return; + return; uint8_t count = payload(buf); if (count == 0) /* count == 0 if no payload or out of range */ - return; + return; uint8_t p = 188 - count; /* payload start */ @@ -302,53 +284,52 @@ void cIptvSectionFilter::ProcessData(const uint8_t* buf) int dc_i = 0; if (buf[3] & 0x20) { - /* adaption field present, check for discontinuity_indicator */ - if ((buf[4] > 0) && (buf[5] & 0x80)) - dc_i = 1; - } - + /* adaption field present, check for discontinuity_indicator */ + if ((buf[4] > 0) && (buf[5] & 0x80)) + dc_i = 1; + } if (!ccok || dc_i) { #ifdef DVB_DEMUX_SECTION_LOSS_LOG - printf("dvb_demux.c discontinuity detected %d bytes lost\n", - count); - /* - * those bytes under sume circumstances will again be reported - * in the following dvb_dmx_swfilter_section_new - */ + printf("dvb_demux.c discontinuity detected %d bytes lost\n", + count); + /* + * those bytes under sume circumstances will again be reported + * in the following dvb_dmx_swfilter_section_new + */ #endif - /* - * Discontinuity detected. Reset pusi_seen = 0 to - * stop feeding of suspicious data until next PUSI=1 arrives - */ - pusi_seen = 0; - dvb_dmx_swfilter_section_new(); - } + /* + * Discontinuity detected. Reset pusi_seen = 0 to + * stop feeding of suspicious data until next PUSI=1 arrives + */ + pusi_seen = 0; + dvb_dmx_swfilter_section_new(); + } if (buf[1] & 0x40) { - /* PUSI=1 (is set), section boundary is here */ - if (count > 1 && buf[p] < count) { + /* PUSI=1 (is set), section boundary is here */ + if (count > 1 && buf[p] < count) { #ifdef DEBUG_PRINTF - printf("Valid section\n"); + printf("Valid section\n"); #endif - const uint8_t *before = &buf[p + 1]; - uint8_t before_len = buf[p]; - const uint8_t *after = &before[before_len]; - uint8_t after_len = count - 1 - before_len; + const uint8_t *before = &buf[p + 1]; + uint8_t before_len = buf[p]; + const uint8_t *after = &before[before_len]; + uint8_t after_len = count - 1 - before_len; - dvb_dmx_swfilter_section_copy_dump(before, before_len); - /* before start of new section, set pusi_seen = 1 */ - pusi_seen = 1; - dvb_dmx_swfilter_section_new(); - dvb_dmx_swfilter_section_copy_dump(after, after_len); - } + dvb_dmx_swfilter_section_copy_dump(before, before_len); + /* before start of new section, set pusi_seen = 1 */ + pusi_seen = 1; + dvb_dmx_swfilter_section_new(); + dvb_dmx_swfilter_section_copy_dump(after, after_len); + } #ifdef DVB_DEMUX_SECTION_LOSS_LOG - else if (count > 0) - printf("dvb_demux.c PUSI=1 but %d bytes lost\n", count); + else if (count > 0) + printf("dvb_demux.c PUSI=1 but %d bytes lost\n", count); #endif - } else { - /* PUSI=0 (is not set), no section boundary */ - dvb_dmx_swfilter_section_copy_dump(&buf[p], count); - } - + } + else { + /* PUSI=0 (is not set), no section boundary */ + dvb_dmx_swfilter_section_copy_dump(&buf[p], count); + } } diff --git a/sectionfilter.h b/sectionfilter.h index 62e4216..19a6b05 100644 --- a/sectionfilter.h +++ b/sectionfilter.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: sectionfilter.h,v 1.1 2007/09/24 13:03:39 ajhseppa Exp $ + * $Id: sectionfilter.h,v 1.2 2007/09/24 17:20:58 rahrenbe Exp $ */ #ifndef __IPTV_SECTIONFILTER_H @@ -20,7 +20,6 @@ #include #include #include - #include #include "common.h" @@ -39,79 +38,76 @@ #define DVB_DEMUX_MASK_MAX 18 class cIptvSectionFilter { - private: - enum dmx_success { - DMX_OK = 0, /* Received Ok */ - DMX_LENGTH_ERROR, /* Incorrect length */ - DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ - DMX_CRC_ERROR, /* Incorrect CRC */ - DMX_FRAME_ERROR, /* Frame alignment error */ - DMX_FIFO_ERROR, /* Receiver FIFO overrun */ - DMX_MISSED_ERROR /* Receiver missed packet */ - } ; + enum dmx_success { + DMX_OK = 0, /* Received Ok */ + DMX_LENGTH_ERROR, /* Incorrect length */ + DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ + DMX_CRC_ERROR, /* Incorrect CRC */ + DMX_FRAME_ERROR, /* Frame alignment error */ + DMX_FIFO_ERROR, /* Receiver FIFO overrun */ + DMX_MISSED_ERROR /* Receiver missed packet */ + }; - int fifoDescriptor; - int readDescriptor; + int fifoDescriptor; + int readDescriptor; - int pusi_seen; - int feedcc; - int doneq; + int pusi_seen; + int feedcc; + int doneq; - uint8_t *secbuf; - uint8_t secbuf_base[DMX_MAX_SECFEED_SIZE]; - uint16_t secbufp; - uint16_t seclen; - uint16_t tsfeedp; - uint32_t crc_val; + uint8_t *secbuf; + uint8_t secbuf_base[DMX_MAX_SECFEED_SIZE]; + uint16_t secbufp; + uint16_t seclen; + uint16_t tsfeedp; + uint32_t crc_val; - uint16_t pid; - int id; + uint16_t pid; + int id; - - uint8_t filter_value[DMX_MAX_FILTER_SIZE]; - uint8_t filter_mask[DMX_MAX_FILTER_SIZE]; - uint8_t filter_mode[DMX_MAX_FILTER_SIZE]; + uint8_t filter_value[DMX_MAX_FILTER_SIZE]; + uint8_t filter_mask[DMX_MAX_FILTER_SIZE]; + uint8_t filter_mode[DMX_MAX_FILTER_SIZE]; - uint8_t maskandmode[DMX_MAX_FILTER_SIZE]; - uint8_t maskandnotmode[DMX_MAX_FILTER_SIZE]; + uint8_t maskandmode[DMX_MAX_FILTER_SIZE]; + uint8_t maskandnotmode[DMX_MAX_FILTER_SIZE]; - char pipeName[128]; + char pipeName[128]; - inline uint16_t section_length(const uint8_t *buf); - inline uint16_t ts_pid(const uint8_t *buf); - inline uint8_t payload(const uint8_t *tsp); + inline uint16_t section_length(const uint8_t *buf); + inline uint16_t ts_pid(const uint8_t *buf); + inline uint8_t payload(const uint8_t *tsp); - int dvb_dmxdev_section_callback(const uint8_t *buffer1, - size_t buffer1_len, - const uint8_t *buffer2, - size_t buffer2_len, - enum dmx_success success); + int dvb_dmxdev_section_callback(const uint8_t *buffer1, + size_t buffer1_len, + const uint8_t *buffer2, + size_t buffer2_len, + enum dmx_success success); - void dvb_dmx_swfilter_section_new(); + void dvb_dmx_swfilter_section_new(); - int dvb_dmx_swfilter_sectionfilter(); + int dvb_dmx_swfilter_sectionfilter(); - inline int dvb_dmx_swfilter_section_feed(); + inline int dvb_dmx_swfilter_section_feed(); - int dvb_dmx_swfilter_section_copy_dump(const uint8_t *buf, - uint8_t len); + int dvb_dmx_swfilter_section_copy_dump(const uint8_t *buf, + uint8_t len); - int GetFifoDesc(); - void ClearPipeName(); - void SetPipeName(int deviceIndex); + int GetFifoDesc(); + void ClearPipeName(); + void SetPipeName(int deviceIndex); public: - // constructor & destructor - cIptvSectionFilter(int Index, int devInd, u_short Pid, u_char Tid, - u_char Mask); + // constructor & destructor + cIptvSectionFilter(int Index, int devInd, u_short Pid, u_char Tid, + u_char Mask); - virtual ~cIptvSectionFilter(); + virtual ~cIptvSectionFilter(); - void ProcessData(const uint8_t* buf); + void ProcessData(const uint8_t* buf); - int GetReadDesc(); + int GetReadDesc(); }; #endif // __IPTV_SECTIONFILTER_H -