aboutsummaryrefslogtreecommitdiff
path: root/lib/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dvb')
-rw-r--r--lib/dvb/demux.cpp61
-rw-r--r--lib/dvb/demux.h4
-rw-r--r--lib/dvb/dvb.cpp51
-rw-r--r--lib/dvb/dvb.h3
-rw-r--r--lib/dvb/epgcache.cpp224
-rw-r--r--lib/dvb/epgcache.h8
-rw-r--r--lib/dvb/frontend.cpp40
-rw-r--r--lib/dvb/idemux.h3
-rw-r--r--lib/dvb/idvb.h1
-rw-r--r--lib/dvb/pmt.cpp4
-rw-r--r--lib/dvb/sec.cpp29
11 files changed, 259 insertions, 169 deletions
diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp
index 4fba8fa8..0c736c55 100644
--- a/lib/dvb/demux.cpp
+++ b/lib/dvb/demux.cpp
@@ -247,6 +247,14 @@ eDVBSectionReader::~eDVBSectionReader()
::close(fd);
}
+RESULT eDVBSectionReader::setBufferSize(int size)
+{
+ int res=::ioctl(fd, DMX_SET_BUFFER_SIZE, size);
+ if (res < 0)
+ eDebug("eDVBSectionReader DMX_SET_BUFFER_SIZE failed(%m)");
+ return res;
+}
+
RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask)
{
RESULT res;
@@ -279,8 +287,7 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask)
memcpy(sct.filter.mask, mask.mask, DMX_FILTER_SIZE);
#if HAVE_DVB_API_VERSION >= 3
memcpy(sct.filter.mode, mask.mode, DMX_FILTER_SIZE);
- if (::ioctl(fd, DMX_SET_BUFFER_SIZE, 8192*8) < 0)
- eDebug("DMX_SET_BUFFER_SIZE failed(%m)");
+ setBufferSize(8192*8);
#endif
res = ::ioctl(fd, DMX_SET_FILTER, &sct);
@@ -352,7 +359,7 @@ eDVBPESReader::eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res):
if (m_fd >= 0)
{
- ::ioctl(m_fd, DMX_SET_BUFFER_SIZE, 64*1024);
+ setBufferSize(64*1024);
::fcntl(m_fd, F_SETFL, O_NONBLOCK);
m_notifier = eSocketNotifier::create(context, m_fd, eSocketNotifier::Read, false);
CONNECT(m_notifier->activated, eDVBPESReader::data);
@@ -364,6 +371,14 @@ eDVBPESReader::eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res):
}
}
+RESULT eDVBPESReader::setBufferSize(int size)
+{
+ int res = ::ioctl(m_fd, DMX_SET_BUFFER_SIZE, size);
+ if (res < 0)
+ eDebug("eDVBPESReader DMX_SET_BUFFER_SIZE failed(%m)");
+ return res;
+}
+
DEFINE_REF(eDVBPESReader)
eDVBPESReader::~eDVBPESReader()
@@ -484,7 +499,7 @@ eDVBTSRecorder::eDVBTSRecorder(eDVBDemux *demux): m_demux(demux)
m_running = 0;
m_target_fd = -1;
m_thread = new eDVBRecordFileThread();
- CONNECT(m_thread->m_event, eDVBTSRecorder::filepushEvent);
+ CONNECT(m_thread->m_event, eDVBTSRecorder::filepushEvent);
#ifndef HAVE_ADD_PID
m_demux->m_dvr_busy = 1;
#endif
@@ -536,8 +551,8 @@ RESULT eDVBTSRecorder::start()
eDebug("FAILED to open demux (%s) in ts recoder (%m)", filename);
return -3;
}
-
- ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, 1024*1024);
+
+ setBufferSize(1024*1024);
dmx_pes_filter_params flt;
#if HAVE_DVB_API_VERSION > 3
@@ -577,6 +592,14 @@ RESULT eDVBTSRecorder::start()
return 0;
}
+RESULT eDVBTSRecorder::setBufferSize(int size)
+{
+ int res = ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, size);
+ if (res < 0)
+ eDebug("eDVBTSRecorder DMX_SET_BUFFER_SIZE failed(%m)");
+ return res;
+}
+
RESULT eDVBTSRecorder::addPID(int pid)
{
if (m_pids.find(pid) != m_pids.end())
@@ -625,18 +648,36 @@ RESULT eDVBTSRecorder::setBoundary(off_t max)
RESULT eDVBTSRecorder::stop()
{
+ int state=3;
+
for (std::map<int,int>::iterator i(m_pids.begin()); i != m_pids.end(); ++i)
stopPID(i->first);
if (!m_running)
return -1;
+
+#if HAVE_DVB_API_VERSION >= 5
+ /* workaround for record thread stop */
+ if (::ioctl(m_source_fd, DMX_STOP) < 0)
+ perror("DMX_STOP");
+ else
+ state &= ~1;
+
+ if (::close(m_source_fd) < 0)
+ perror("close");
+ else
+ state &= ~2;
+#endif
+
m_thread->stop();
-
- close(m_source_fd);
+
+ if (state & 3)
+ ::close(m_source_fd);
+
+ m_running = 0;
m_source_fd = -1;
-
+
m_thread->stopSaveMetaInformation();
-
return 0;
}
diff --git a/lib/dvb/demux.h b/lib/dvb/demux.h
index 7a697d49..d43c41bb 100644
--- a/lib/dvb/demux.h
+++ b/lib/dvb/demux.h
@@ -56,9 +56,9 @@ class eDVBSectionReader: public iDVBSectionReader, public Object
void data(int);
ePtr<eSocketNotifier> notifier;
public:
-
eDVBSectionReader(eDVBDemux *demux, eMainloop *context, RESULT &res);
virtual ~eDVBSectionReader();
+ RESULT setBufferSize(int size);
RESULT start(const eDVBSectionFilterMask &mask);
RESULT stop();
RESULT connectRead(const Slot1<void,const __u8*> &read, ePtr<eConnection> &conn);
@@ -76,6 +76,7 @@ class eDVBPESReader: public iDVBPESReader, public Object
public:
eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res);
virtual ~eDVBPESReader();
+ RESULT setBufferSize(int size);
RESULT start(int pid);
RESULT stop();
RESULT connectRead(const Slot2<void,const __u8*, int> &read, ePtr<eConnection> &conn);
@@ -90,6 +91,7 @@ public:
eDVBTSRecorder(eDVBDemux *demux);
~eDVBTSRecorder();
+ RESULT setBufferSize(int size);
RESULT start();
RESULT addPID(int pid);
RESULT removePID(int pid);
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index 17712dde..51629452 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -96,6 +96,8 @@ eDVBResourceManager::eDVBResourceManager()
m_boxtype = DM800;
else if (!strncmp(tmp, "dm500hd\n", rd))
m_boxtype = DM500HD;
+ else if (!strncmp(tmp, "dm800se\n", rd))
+ m_boxtype = DM800SE;
else {
eDebug("boxtype detection via /proc/stb/info not possible... use fallback via demux count!\n");
if (m_demux.size() == 3)
@@ -318,27 +320,34 @@ PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
return NULL;
}
- if ((unsigned int)PyList_Size(list) != m_frontend.size())
+ unsigned int assigned=0;
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
{
+ int pos=0;
+ while (pos < PyList_Size(list)) {
+ ePyObject obj = PyList_GET_ITEM(list, pos++);
+ if (!i->m_frontend->setSlotInfo(obj))
+ continue;
+ ++assigned;
+ break;
+ }
+ }
+ if (assigned != m_frontend.size()) {
char blasel[256];
- sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist",
- m_frontend.size(), PyList_Size(list));
+ sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations .. assigned %d socket informations, but %d registered frontends!",
+ m_frontend.size(), assigned);
PyErr_SetString(PyExc_StandardError, blasel);
return NULL;
}
- int pos=0;
- for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
- {
- ePyObject obj = PyList_GET_ITEM(list, pos++);
- if (!i->m_frontend->setSlotInfo(obj))
- return NULL;
- }
- pos=0;
for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_simulate_frontend.begin()); i != m_simulate_frontend.end(); ++i)
{
- ePyObject obj = PyList_GET_ITEM(list, pos++);
- if (!i->m_frontend->setSlotInfo(obj))
- return NULL;
+ int pos=0;
+ while (pos < PyList_Size(list)) {
+ ePyObject obj = PyList_GET_ITEM(list, pos++);
+ if (!i->m_frontend->setSlotInfo(obj))
+ continue;
+ break;
+ }
}
Py_RETURN_NONE;
}
@@ -455,7 +464,7 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBA
ePtr<eDVBRegisteredDemux> unused;
- if (m_boxtype == DM800 || m_boxtype == DM500HD) // dm800 / 500hd
+ if (m_boxtype == DM800 || m_boxtype == DM500HD || m_boxtype == DM800SE) // dm800 / 500hd
{
cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux
for (; i != m_demux.end(); ++i, ++n)
@@ -1657,6 +1666,18 @@ void eDVBChannel::SDTready(int result)
m_SDT = 0;
}
+int eDVBChannel::reserveDemux()
+{
+ ePtr<iDVBDemux> dmx;
+ if (!getDemux(dmx, 0))
+ {
+ uint8_t id;
+ if (!dmx->getCADemuxID(id))
+ return id;
+ }
+ return -1;
+}
+
RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
{
if (PyCallable_Check(callback))
diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h
index 7b320006..fb925807 100644
--- a/lib/dvb/dvb.h
+++ b/lib/dvb/dvb.h
@@ -135,7 +135,7 @@ class eDVBResourceManager: public iObject, public Object
DECLARE_REF(eDVBResourceManager);
int avail, busy;
- enum { DM7025, DM800, DM500HD, DM8000 };
+ enum { DM7025, DM800, DM500HD, DM800SE, DM8000 };
int m_boxtype;
@@ -268,6 +268,7 @@ public:
int getUseCount() { return m_use_count; }
RESULT requestTsidOnid(ePyObject callback);
+ int reserveDemux();
private:
ePtr<eDVBAllocatedFrontend> m_frontend;
ePtr<eDVBAllocatedDemux> m_demux, m_decoder_demux;
diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp
index 119223a3..8ac0c718 100644
--- a/lib/dvb/epgcache.cpp
+++ b/lib/dvb/epgcache.cpp
@@ -213,9 +213,9 @@ pthread_mutex_t eEPGCache::channel_map_lock=
DEFINE_REF(eEPGCache)
eEPGCache::eEPGCache()
- :messages(this,1), cleanTimer(eTimer::create(this))//, paused(0)
+ :messages(this,1), cleanTimer(eTimer::create(this)), m_running(0)//, paused(0)
{
- eDebug("[EPGC] Initialized EPGCache");
+ eDebug("[EPGC] Initialized EPGCache (wait for setCacheFile call now)");
CONNECT(messages.recv_msg, eEPGCache::gotMessage);
CONNECT(eDVBLocalTimeHandler::getInstance()->m_timeUpdated, eEPGCache::timeUpdated);
@@ -226,22 +226,46 @@ eEPGCache::eEPGCache()
if (!res_mgr)
eDebug("[eEPGCache] no resource manager !!!!!!!");
else
- {
res_mgr->connectChannelAdded(slot(*this,&eEPGCache::DVBChannelAdded), m_chanAddedConn);
+
+ instance=this;
+ memset(m_filename, 0, sizeof(m_filename));
+}
+
+void eEPGCache::setCacheFile(const char *path)
+{
+ bool inited = !!strlen(m_filename);
+ strncpy(m_filename, path, 1024);
+ if (!inited)
+ {
+ eDebug("[EPGC] setCacheFile read/write epg data from/to '%s'", m_filename);
if (eDVBLocalTimeHandler::getInstance()->ready())
timeUpdated();
}
- instance=this;
}
void eEPGCache::timeUpdated()
{
- if (!sync())
+ if (strlen(m_filename))
{
- eDebug("[EPGC] time updated.. start EPG Mainloop");
- run();
- } else
- messages.send(Message(Message::timeChanged));
+ if (!sync())
+ {
+ eDebug("[EPGC] time updated.. start EPG Mainloop");
+ run();
+ singleLock s(channel_map_lock);
+ channelMapIterator it = m_knownChannels.begin();
+ for (; it != m_knownChannels.end(); ++it)
+ {
+ if (it->second->state == -1) {
+ it->second->state=0;
+ messages.send(Message(Message::startChannel, it->second));
+ }
+ }
+ } else
+ messages.send(Message(Message::timeChanged));
+ }
+ else
+ eDebug("[EPGC] time updated.. but cache file not set yet.. dont start epg!!");
}
void eEPGCache::DVBChannelAdded(eDVBChannel *chan)
@@ -337,8 +361,11 @@ void eEPGCache::DVBChannelRunning(iDVBChannel *chan)
return;
}
#endif
- messages.send(Message(Message::startChannel, chan));
- // -> gotMessage -> changedService
+ if (m_running) {
+ data.state=0;
+ messages.send(Message(Message::startChannel, chan));
+ // -> gotMessage -> changedService
+ }
}
}
}
@@ -365,7 +392,8 @@ void eEPGCache::DVBChannelStateChanged(iDVBChannel *chan)
case iDVBChannel::state_release:
{
eDebug("[eEPGCache] remove channel %p", chan);
- messages.send(Message(Message::leaveChannel, chan));
+ if (it->second->state >= 0)
+ messages.send(Message(Message::leaveChannel, chan));
pthread_mutex_lock(&it->second->channel_active);
singleLock s(channel_map_lock);
m_knownChannels.erase(it);
@@ -953,39 +981,24 @@ void eEPGCache::gotMessage( const Message &msg )
void eEPGCache::thread()
{
hasStarted();
+ m_running=1;
nice(4);
load();
cleanLoop();
runLoop();
save();
+ m_running=0;
}
void eEPGCache::load()
{
- FILE *f = fopen("/hdd/epg.dat", "r");
+ FILE *f = fopen(m_filename, "r");
if (f)
{
- unlink("/hdd/epg.dat");
+ unlink(m_filename);
int size=0;
int cnt=0;
-#if 0
- unsigned char md5_saved[16];
- unsigned char md5[16];
- bool md5ok=false;
- if (!md5_file("/hdd/epg.dat", 1, md5))
- {
- FILE *f = fopen("/hdd/epg.dat.md5", "r");
- if (f)
- {
- fread( md5_saved, 16, 1, f);
- fclose(f);
- if ( !memcmp(md5_saved, md5, 16) )
- md5ok=true;
- }
- }
- if ( md5ok )
-#endif
{
unsigned int magic=0;
fread( &magic, sizeof(int), 1, f);
@@ -1027,7 +1040,7 @@ void eEPGCache::load()
eventDB[key]=std::pair<eventMap,timeMap>(evMap,tmMap);
}
eventData::load(f);
- eDebug("[EPGC] %d events read from /hdd/epg.dat", cnt);
+ eDebug("[EPGC] %d events read from %s", cnt, m_filename);
#ifdef ENABLE_PRIVATE_EPG
char text2[11];
fread( text2, 11, 1, f);
@@ -1075,103 +1088,106 @@ void eEPGCache::load()
void eEPGCache::save()
{
- struct statfs s;
- off64_t tmp;
- if (statfs("/hdd", &s)<0)
- tmp=0;
- else
+ /* create empty file */
+ FILE *f = fopen(m_filename, "w");
+
+ if (!f)
+ {
+ eDebug("[EPGC] couldn't save epg data to '%s'(%m)", m_filename);
+ return;
+ }
+
+ char *buf = realpath(m_filename, NULL);
+ if (!buf)
{
- tmp=s.f_blocks;
- tmp*=s.f_bsize;
+ eDebug("[EPGC] realpath to '%s' failed in save (%m)", m_filename);
+ fclose(f);
+ return;
}
- // prevent writes to builtin flash
- if ( tmp < 1024*1024*50 ) // storage size < 50MB
+ eDebug("[EPGC] store epg to realpath '%s'", buf);
+
+ struct statfs s;
+ off64_t tmp;
+ if (statfs(buf, &s) < 0) {
+ eDebug("[EPGC] statfs '%s' failed in save (%m)", buf);
+ fclose(f);
return;
+ }
+
+ free(buf);
// check for enough free space on storage
tmp=s.f_bfree;
tmp*=s.f_bsize;
if ( tmp < (eventData::CacheSize*12)/10 ) // 20% overhead
+ {
+ eDebug("[EPGC] not enough free space at path '%s' %lld bytes availd but %d needed", buf, tmp, (eventData::CacheSize*12)/10);
+ fclose(f);
return;
+ }
- FILE *f = fopen("/hdd/epg.dat", "w");
int cnt=0;
- if ( f )
- {
- unsigned int magic = 0x98765432;
- fwrite( &magic, sizeof(int), 1, f);
- const char *text = "UNFINISHED_V7";
- fwrite( text, 13, 1, f );
- int size = eventDB.size();
- fwrite( &size, sizeof(int), 1, f );
- for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it)
- {
- timeMap &timemap = service_it->second.second;
- fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f);
- size = timemap.size();
- fwrite( &size, sizeof(int), 1, f);
- for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it)
- {
- __u8 len = time_it->second->ByteSize;
- fwrite( &time_it->second->type, sizeof(__u8), 1, f );
- fwrite( &len, sizeof(__u8), 1, f);
- fwrite( time_it->second->EITdata, len, 1, f);
- ++cnt;
- }
+ unsigned int magic = 0x98765432;
+ fwrite( &magic, sizeof(int), 1, f);
+ const char *text = "UNFINISHED_V7";
+ fwrite( text, 13, 1, f );
+ int size = eventDB.size();
+ fwrite( &size, sizeof(int), 1, f );
+ for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it)
+ {
+ timeMap &timemap = service_it->second.second;
+ fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f);
+ size = timemap.size();
+ fwrite( &size, sizeof(int), 1, f);
+ for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it)
+ {
+ __u8 len = time_it->second->ByteSize;
+ fwrite( &time_it->second->type, sizeof(__u8), 1, f );
+ fwrite( &len, sizeof(__u8), 1, f);
+ fwrite( time_it->second->EITdata, len, 1, f);
+ ++cnt;
}
- eDebug("[EPGC] %d events written to /hdd/epg.dat", cnt);
- eventData::save(f);
+ }
+ eDebug("[EPGC] %d events written to %s", cnt, m_filename);
+ eventData::save(f);
#ifdef ENABLE_PRIVATE_EPG
- const char* text3 = "PRIVATE_EPG";
- fwrite( text3, 11, 1, f );
- size = content_time_tables.size();
+ const char* text3 = "PRIVATE_EPG";
+ fwrite( text3, 11, 1, f );
+ size = content_time_tables.size();
+ fwrite( &size, sizeof(int), 1, f);
+ for (contentMaps::iterator a = content_time_tables.begin(); a != content_time_tables.end(); ++a)
+ {
+ contentMap &content_time_table = a->second;
+ fwrite( &a->first, sizeof(uniqueEPGKey), 1, f);
+ int size = content_time_table.size();
fwrite( &size, sizeof(int), 1, f);
- for (contentMaps::iterator a = content_time_tables.begin(); a != content_time_tables.end(); ++a)
+ for (contentMap::iterator i = content_time_table.begin(); i != content_time_table.end(); ++i )
{
- contentMap &content_time_table = a->second;
- fwrite( &a->first, sizeof(uniqueEPGKey), 1, f);
- int size = content_time_table.size();
+ int size = i->second.size();
+ fwrite( &i->first, sizeof(int), 1, f);
fwrite( &size, sizeof(int), 1, f);
- for (contentMap::iterator i = content_time_table.begin(); i != content_time_table.end(); ++i )
- {
- int size = i->second.size();
- fwrite( &i->first, sizeof(int), 1, f);
- fwrite( &size, sizeof(int), 1, f);
- for ( contentTimeMap::iterator it(i->second.begin());
- it != i->second.end(); ++it )
- {
- fwrite( &it->first, sizeof(time_t), 1, f);
- fwrite( &it->second.first, sizeof(time_t), 1, f);
- fwrite( &it->second.second, sizeof(__u16), 1, f);
- }
- }
- }
-#endif
- // write version string after binary data
- // has been written to disk.
- fsync(fileno(f));
- fseek(f, sizeof(int), SEEK_SET);
- fwrite("ENIGMA_EPG_V7", 13, 1, f);
- fclose(f);
-#if 0
- unsigned char md5[16];
- if (!md5_file("/hdd/epg.dat", 1, md5))
- {
- FILE *f = fopen("/hdd/epg.dat.md5", "w");
- if (f)
+ for ( contentTimeMap::iterator it(i->second.begin());
+ it != i->second.end(); ++it )
{
- fwrite( md5, 16, 1, f);
- fclose(f);
+ fwrite( &it->first, sizeof(time_t), 1, f);
+ fwrite( &it->second.first, sizeof(time_t), 1, f);
+ fwrite( &it->second.second, sizeof(__u16), 1, f);
}
}
-#endif
}
+#endif
+ // write version string after binary data
+ // has been written to disk.
+ fsync(fileno(f));
+ fseek(f, sizeof(int), SEEK_SET);
+ fwrite("ENIGMA_EPG_V7", 13, 1, f);
+ fclose(f);
}
eEPGCache::channel_data::channel_data(eEPGCache *ml)
:cache(ml)
- ,abortTimer(eTimer::create(ml)), zapTimer(eTimer::create(ml)), state(0)
+ ,abortTimer(eTimer::create(ml)), zapTimer(eTimer::create(ml)), state(-1)
,isRunning(0), haveData(0)
#ifdef ENABLE_PRIVATE_EPG
,startPrivateTimer(eTimer::create(ml))
diff --git a/lib/dvb/epgcache.h b/lib/dvb/epgcache.h
index 4d45d87e..90aff6c6 100644
--- a/lib/dvb/epgcache.h
+++ b/lib/dvb/epgcache.h
@@ -177,7 +177,8 @@ class eEPGCache: public eMainloop, private eThread, public Object
eEPGCache *cache;
ePtr<eTimer> abortTimer, zapTimer;
int prevChannelState;
- __u8 state, isRunning, haveData;
+ int state;
+ __u8 isRunning, haveData;
ePtr<eDVBChannel> channel;
ePtr<eConnection> m_stateChangedConn, m_NowNextConn, m_ScheduleConn, m_ScheduleOtherConn, m_ViasatConn;
ePtr<iDVBSectionReader> m_NowNextReader, m_ScheduleReader, m_ScheduleOtherReader, m_ViasatReader;
@@ -290,6 +291,8 @@ private:
void thread(); // thread function
// called from epgcache thread
+ int m_running;
+ char m_filename[1024];
void save();
void load();
#ifdef ENABLE_PRIVATE_EPG
@@ -325,6 +328,9 @@ public:
#endif
#endif
+ // must be called once!
+ void setCacheFile(const char *filename);
+
// called from main thread
inline void Lock();
inline void Unlock();
diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp
index bd8f0028..ebdad8a7 100644
--- a/lib/dvb/frontend.cpp
+++ b/lib/dvb/frontend.cpp
@@ -813,7 +813,7 @@ int eDVBFrontend::readFrontendData(int type)
float fval1 = SDS_SNRE / 268435456.0,
fval2, fval3, fval4;
- if (parm_u_qpsk_fec_inner <= FEC_S2_QPSK_9_10) // DVB-S2 QPSK
+ if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
{
fval2 = 6.76;
fval3 = 4.35;
@@ -906,6 +906,19 @@ int eDVBFrontend::readFrontendData(int type)
}
else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
ret = (snr * 100) >> 8;
+ else if (!strcmp(m_description, "CXD1981"))
+ {
+ int mse = (~snr) & 0xFF;
+ switch (parm_u_qam_modulation) {
+ case QAM_16:
+ case QAM_64:
+ case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
+ case QAM_32:
+ case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
+
+ default: break;
+ }
+ }
if (type == signalQuality)
{
@@ -1076,6 +1089,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &
case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
}
+ PutToDict(dict, "fec_inner", tmp);
switch (p[0].u.data)
{
@@ -1124,7 +1138,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &
PutToDict(dict, "orbital_position", orb_pos);
PutToDict(dict, "polarization", polarization);
- switch(parm_u_qpsk_fec_inner)
+ switch((int)parm_u_qpsk_fec_inner)
{
case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
@@ -1458,9 +1472,11 @@ int eDVBFrontend::readInputpower()
return 0;
int power=m_slotid; // this is needed for read inputpower from the correct tuner !
char proc_name[64];
- sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid);
- FILE *f=fopen(proc_name, "r");
- if (f)
+ char proc_name2[64];
+ sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
+ sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
+ FILE *f;
+ if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
{
if (fscanf(f, "%d", &power) != 1)
eDebug("read %s failed!! (%m)", proc_name);
@@ -2684,17 +2700,23 @@ int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
bool eDVBFrontend::setSlotInfo(ePyObject obj)
{
- ePyObject Id, Descr, Enabled, IsDVBS2;
- if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 4)
+ ePyObject Id, Descr, Enabled, IsDVBS2, frontendId;
+ if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5)
goto arg_error;
Id = PyTuple_GET_ITEM(obj, 0);
Descr = PyTuple_GET_ITEM(obj, 1);
Enabled = PyTuple_GET_ITEM(obj, 2);
IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
- if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2))
+ frontendId = PyTuple_GET_ITEM(obj, 4);
+ m_slotid = PyInt_AsLong(Id);
+ if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId))
goto arg_error;
strcpy(m_description, PyString_AS_STRING(Descr));
- m_slotid = PyInt_AsLong(Id);
+ if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
+// eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
+// m_slotid, m_description);
+ return false;
+ }
m_enabled = Enabled == Py_True;
// HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
diff --git a/lib/dvb/idemux.h b/lib/dvb/idemux.h
index e92b1e75..86b35fdb 100644
--- a/lib/dvb/idemux.h
+++ b/lib/dvb/idemux.h
@@ -6,6 +6,7 @@
class iDVBSectionReader: public iObject
{
public:
+ virtual RESULT setBufferSize(int size)=0;
virtual RESULT start(const eDVBSectionFilterMask &mask)=0;
virtual RESULT stop()=0;
virtual RESULT connectRead(const Slot1<void,const __u8*> &read, ePtr<eConnection> &conn)=0;
@@ -15,6 +16,7 @@ public:
class iDVBPESReader: public iObject
{
public:
+ virtual RESULT setBufferSize(int size)=0;
virtual RESULT start(int pid)=0;
virtual RESULT stop()=0;
virtual RESULT connectRead(const Slot2<void,const __u8*, int> &read, ePtr<eConnection> &conn)=0;
@@ -26,6 +28,7 @@ public:
class iDVBTSRecorder: public iObject
{
public:
+ virtual RESULT setBufferSize(int size) = 0;
virtual RESULT start() = 0;
virtual RESULT addPID(int pid) = 0;
virtual RESULT removePID(int pid) = 0;
diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h
index d00d1fc8..f1217a6a 100644
--- a/lib/dvb/idvb.h
+++ b/lib/dvb/idvb.h
@@ -509,6 +509,7 @@ public:
/* direct frontend access for raw channels and/or status inquiries. */
virtual SWIG_VOID(RESULT) getFrontend(ePtr<iDVBFrontend> &SWIG_OUTPUT)=0;
virtual RESULT requestTsidOnid(SWIG_PYOBJECT(ePyObject) callback) { return -1; }
+ virtual int reserveDemux() { return -1; }
#ifndef SWIG
enum
{
diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp
index ee89a3a4..ea4b96c5 100644
--- a/lib/dvb/pmt.cpp
+++ b/lib/dvb/pmt.cpp
@@ -133,11 +133,11 @@ void eDVBServicePMTHandler::PATready(int)
{
int pmtpid = -1;
std::vector<ProgramAssociationSection*>::const_iterator i;
- for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
+ for (i = ptr->getSections().begin(); pmtpid == -1 && i != ptr->getSections().end(); ++i)
{
const ProgramAssociationSection &pat = **i;
ProgramAssociationConstIterator program;
- for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program)
+ for (program = pat.getPrograms()->begin(); pmtpid == -1 && program != pat.getPrograms()->end(); ++program)
if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
pmtpid = (*program)->getProgramMapPid();
}
diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp
index 9ca0f734..a2bc8869 100644
--- a/lib/dvb/sec.cpp
+++ b/lib/dvb/sec.cpp
@@ -548,6 +548,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
if ( send_mask )
{
+ int diseqc_repeats = diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0 ? di_param.m_repeats : 0;
int vlt = iDVBFrontend::voltageOff;
eSecCommand::pair compare;
compare.steps = +3;
@@ -620,7 +621,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
if ( send_mask & 2 )
++loops;
- loops <<= di_param.m_repeats;
+ loops <<= diseqc_repeats;
for ( int i = 0; i < loops;) // fill commands...
{
@@ -657,7 +658,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
int tmp = m_params[DELAY_BETWEEN_DISEQC_REPEATS];
if (cmd)
{
- int delay = di_param.m_repeats ? (tmp - 54) / 2 : tmp; // standard says 100msek between two repeated commands
+ int delay = diseqc_repeats ? (tmp - 54) / 2 : tmp; // standard says 100msek between two repeated commands
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay) );
diseqc.data[2]=cmd;
diseqc.data[3]=(cmd==0x38) ? csw : ucsw;
@@ -1001,19 +1002,6 @@ RESULT eDVBSatelliteEquipmentControl::clear()
//reset some tuner configuration
for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it)
{
- long tmp;
- char c;
- if (sscanf(it->m_frontend->getDescription(), "BCM450%c (internal)", &c) == 1 && !it->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp) && tmp != -1)
- {
- FILE *f=fopen("/proc/stb/tsmux/lnb_b_input", "w");
- if (!f || fwrite("B", 1, 1, f) != 1)
- eDebug("set /proc/stb/tsmux/lnb_b_input to B failed!! (%m)");
- else
- {
- eDebug("set /proc/stb/tsmux/lnb_b_input to B OK");
- fclose(f);
- }
- }
it->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, -1);
it->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, -1);
it->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, -1);
@@ -1445,17 +1433,6 @@ RESULT eDVBSatelliteEquipmentControl::setTunerLinked(int tu1, int tu2)
char c;
p1->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)p2);
p2->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)p1);
- if (!strcmp(p1->m_frontend->getDescription(), p2->m_frontend->getDescription()) && sscanf(p1->m_frontend->getDescription(), "BCM450%c (internal)", &c) == 1)
- {
- FILE *f=fopen("/proc/stb/tsmux/lnb_b_input", "w");
- if (!f || fwrite("A", 1, 1, f) != 1)
- eDebug("set /proc/stb/tsmux/lnb_b_input to A failed!! (%m)");
- else
- {
- eDebug("set /proc/stb/tsmux/lnb_b_input to A OK");
- fclose(f);
- }
- }
}
p1=p2=NULL;