+ int ret=30000;
+ if (m_cached_channel)
+ {
+ eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
+ if(channelid==cache_chan->getChannelID())
+ return ret;
+ }
+
+ /* first, check if a channel is already existing. */
+// eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
+ for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
+ {
+// eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
+ if (i->m_channel_id == channelid)
+ {
+// eDebug("found shared channel..");
+ return ret;
+ }
+ }
+
+ int *decremented_cached_channel_fe_usecount=NULL,
+ *decremented_fe_usecount=NULL;
+
+ for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
+ {
+// eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
+ if (i->m_channel_id == ignore)
+ {
+ eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
+ // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
+ // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
+ // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
+ // or 2 when the cached channel is not equal to the compared channel
+ if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
+ {
+ ePtr<iDVBFrontend> fe;
+ if (!i->m_channel->getFrontend(fe))
+ {
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
+ {
+ if ( &(*fe) == &(*ii->m_frontend) )
+ {
+ --ii->m_inuse;
+ decremented_fe_usecount = &ii->m_inuse;
+ if (channel == &(*m_cached_channel))
+ decremented_cached_channel_fe_usecount = decremented_fe_usecount;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if (!decremented_cached_channel_fe_usecount)
+ {
+ if (m_cached_channel)
+ {
+ eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
+ if (channel->getUseCount() == 1)
+ {
+ ePtr<iDVBFrontend> fe;
+ if (!channel->getFrontend(fe))
+ {
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
+ {
+ if ( &(*fe) == &(*ii->m_frontend) )
+ {
+ --ii->m_inuse;
+ decremented_cached_channel_fe_usecount = &ii->m_inuse;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ decremented_cached_channel_fe_usecount=NULL;
+
+ ePtr<iDVBFrontendParameters> feparm;
+
+ if (!m_list)
+ {
+ eDebug("no channel list set!");
+ ret = 0;
+ goto error;
+ }
+
+ if (m_list->getChannelFrontendData(channelid, feparm))
+ {
+ eDebug("channel not found!");
+ ret = 0;
+ goto error;
+ }
+
+ ret = canAllocateFrontend(feparm);
+
+error:
+ if (decremented_fe_usecount)
+ ++(*decremented_fe_usecount);
+ if (decremented_cached_channel_fe_usecount)
+ ++(*decremented_cached_channel_fe_usecount);
+
+ return ret;
+}
+
+class eDVBChannelFilePush: public eFilePushThread
+{
+public:
+ void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
+protected:
+ int m_iframe_search, m_iframe_state, m_pid;
+ int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
+};
+
+int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
+{
+#if 0 /* not yet */
+ if (!m_iframe_search)
+ return len;
+
+ unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
+
+ eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
+
+ unsigned char *d = data;
+ while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
+ {
+ int offset = d - data;
+ int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
+ unsigned char *ts = data + ts_offset;
+ int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
+
+ if ((d[3] == 0) && (m_pid == pid)) /* picture start */
+ {
+ int picture_type = (d[5] >> 3) & 7;
+ d += 4;
+
+ eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
+
+ if (m_iframe_state == 1)
+ {
+ /* we are allowing data, and stop allowing data on the next frame.
+ we now found a frame. so stop here. */
+ memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
+ current_span_remaining = 0;
+ m_iframe_state = 0;
+ unsigned char *fts = ts + 188;
+ while (fts < (data + len))
+ {
+ fts[1] |= 0x1f;
+ fts[2] |= 0xff; /* drop packet */
+ fts += 188;
+ }
+
+ return len; // ts_offset + 188; /* deliver this packet, but not more. */
+ } else
+ {
+ if (picture_type != 1) /* we are only interested in I frames */
+ continue;
+
+ unsigned char *fts = data;
+ while (fts < ts)
+ {
+ fts[1] |= 0x1f;
+ fts[2] |= 0xff; /* drop packet */
+
+ fts += 188;
+ }
+ /* force payload only */
+ ts[3] &= ~0x30;
+ ts[3] |= 0x10;
+
+// memset(ts + 4, 0xFF, (offset % 188) - 4);
+
+ m_iframe_state = 1;
+ }
+ } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
+ {
+ if (m_pid != pid)
+ {
+ eDebug("now locked to pid %04x", pid);
+ m_pid = pid;
+ }
+// m_pid = 0x6e;
+ d += 4;
+ } else
+ d += 4; /* ignore */
+
+ }
+
+ if (m_iframe_state == 1)
+ return len;
+ else
+ return 0; /* we need find an iframe first */
+#else
+ return len;
+#endif