diff options
| author | Andreas Monzner <andreas.monzner@multimedia-labs.de> | 2006-05-20 00:21:50 +0000 |
|---|---|---|
| committer | Andreas Monzner <andreas.monzner@multimedia-labs.de> | 2006-05-20 00:21:50 +0000 |
| commit | 75db34c299094d2ae87941ed464e8efa79848e16 (patch) | |
| tree | 4d63a8aa488112c6d58d05440ae488f7c86a911e /lib/dvb | |
| parent | d0812009f069ba9aee256ba1fb8c54f2ffba671d (diff) | |
| download | enigma2-75db34c299094d2ae87941ed464e8efa79848e16.tar.gz enigma2-75db34c299094d2ae87941ed464e8efa79848e16.zip | |
many changes for better CI handling
- the CI is now working on both tuners
- the CI is no more blocked by freetv services
- add multi services support (on same transponder) (yet hardcoded for Alphacrypt only)
- fix bluescreen in CI MMI dialog when pressin ok/left/right
Diffstat (limited to 'lib/dvb')
| -rw-r--r-- | lib/dvb/db.cpp | 69 | ||||
| -rw-r--r-- | lib/dvb/epgcache.cpp | 2 | ||||
| -rw-r--r-- | lib/dvb/idvb.h | 14 | ||||
| -rw-r--r-- | lib/dvb/pmt.cpp | 101 | ||||
| -rw-r--r-- | lib/dvb/pmt.h | 7 | ||||
| -rw-r--r-- | lib/dvb/scan.cpp | 28 | ||||
| -rw-r--r-- | lib/dvb/scan.h | 2 |
7 files changed, 105 insertions, 118 deletions
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 9b2324a6..a9f58c0f 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -114,21 +114,13 @@ RESULT eBouquet::setListName(const std::string &name) } eDVBService::eDVBService() - :m_flags(0) + :m_cache(0), m_flags(0) { - memset(m_cache, -1, sizeof(m_cache)); } eDVBService::~eDVBService() { -} - -bool eDVBService::cacheEmpty() -{ - for (int i=0; i < cacheMax; ++i) - if (m_cache[i] != -1) - return false; - return true; + delete [] m_cache; } eDVBService &eDVBService::operator=(const eDVBService &s) @@ -137,8 +129,8 @@ eDVBService &eDVBService::operator=(const eDVBService &s) m_service_name_sort = s.m_service_name_sort; m_provider_name = s.m_provider_name; m_flags = s.m_flags; -// m_ca = s.m_ca; - memcpy(m_cache, s.m_cache, sizeof(m_cache)); + m_ca = s.m_ca; + copyCache(s.m_cache); return *this; } @@ -232,15 +224,47 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ return res; } +bool eDVBService::cacheEmpty() +{ + if (m_cache) + for (int i=0; i < cacheMax; ++i) + if (m_cache[i] != -1) + return false; + return true; +} + +void eDVBService::initCache() +{ + m_cache = new int[cacheMax]; + memset(m_cache, -1, sizeof(int) * cacheMax); +} + +void eDVBService::copyCache(int *source) +{ + if (source) + { + if (!m_cache) + m_cache = new int[cacheMax]; + memcpy(m_cache, source, cacheMax * sizeof(int)); + } + else + { + delete [] m_cache; + m_cache = 0; + } +} + int eDVBService::getCacheEntry(cacheID id) { - if (id >= cacheMax) + if (id >= cacheMax || !m_cache) return -1; return m_cache[id]; } void eDVBService::setCacheEntry(cacheID id, int pid) { + if (!m_cache) + initCache(); if (id < cacheMax) m_cache[id] = pid; } @@ -426,13 +450,13 @@ void eDVBDB::reloadServicelist() { int cid, val; sscanf(v.c_str(), "%02d%04x", &cid, &val); - s->m_cache[cid]=val; - }/* else if (p == 'C') + s->setCacheEntry(cid,val); + } else if (p == 'C') { int val; sscanf(v.c_str(), "%04x", &val); - s->m_ca.insert(val); - }*/ + s->m_ca.push_front((uint16_t)val); + } } addService(ref, s); } @@ -517,15 +541,16 @@ void eDVBDB::saveServicelist() // write cached pids for (int x=0; x < eDVBService::cacheMax; ++x) - if (i->second->m_cache[x] != -1) - fprintf(f, ",c:%02d%04x", x, i->second->m_cache[x]); + { + int entry = i->second->getCacheEntry(x); + if (entry != -1) + fprintf(f, ",c:%02d%04x", x, entry); + } -/* // write cached ca pids - for (std::set<int>::const_iterator ca(i->second->m_ca.begin()); + for (CAID_LIST::const_iterator ca(i->second->m_ca.begin()); ca != i->second->m_ca.end(); ++ca) fprintf(f, ",C:%04x", *ca); -*/ if (i->second->m_flags) fprintf(f, ",f:%x", i->second->m_flags); diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index ee61268c..b04bdd89 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -2118,7 +2118,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler) if (tmp==3) { eServiceReferenceDVB ref; - if (!pmthandler->getService(ref)) + if (!pmthandler->getServiceReference(ref)) { int pid = (*es)->getPid(); messages.send(Message(Message::got_private_pid, ref, pid)); diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 8b86866e..8bbbaafa 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -18,6 +18,14 @@ #include <libsig_comp.h> #include <connection.h> +#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || __GNUC__ == 4 ) // check if gcc version >= 3.1 +#include <ext/slist> +#define CAID_LIST __gnu_cxx::slist<uint16_t> +#else +#include <slist> +#define CAID_LIST std::slist<uint16_t> +#endif + struct eBouquet { std::string m_bouquet_name; @@ -220,6 +228,9 @@ class eDVBChannelQuery; class eDVBService: public iStaticServiceInformation { DECLARE_REF(eDVBService); + int *m_cache; + void initCache(); + void copyCache(int *source); public: enum cacheID { @@ -250,9 +261,8 @@ public: bool usePMT() const { return !(m_flags & dxNoDVB); } -// std::set<int> m_ca; + CAID_LIST m_ca; - int m_cache[cacheMax]; virtual ~eDVBService(); eDVBService &operator=(const eDVBService &); diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 0cdebebf..4d48f86e 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -85,9 +85,9 @@ void eDVBServicePMTHandler::PMTready(int error) { serviceEvent(eventNewProgramInfo); eEPGCache::getInstance()->PMTready(this); - if (!m_pvr_channel) + if (!m_pvr_channel) // don't send campmt to camd.socket for playbacked services { - if(!m_ca_servicePtr) // don't send campmt to camd.socket for playbacked services + if(!m_ca_servicePtr) { int demuxes[2] = {0,0}; uint8_t tmp; @@ -98,9 +98,10 @@ void eDVBServicePMTHandler::PMTready(int error) else demuxes[1]=demuxes[0]; eDVBCAService::register_service(m_reference, demuxes, m_ca_servicePtr); - eDVBCIInterfaces::getInstance()->addPMTHandler(this); + eDVBCIInterfaces::getInstance()->recheckPMTHandlers(); } - eDVBCIInterfaces::getInstance()->gotPMT(this); + else + eDVBCIInterfaces::getInstance()->gotPMT(this); } if (m_ca_servicePtr) { @@ -140,70 +141,21 @@ PyObject *eDVBServicePMTHandler::getCaIds() { PyObject *ret=0; - ePtr<eTable<ProgramMapSection> > ptr; + program prog; - if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr)) + if ( !getProgramInfo(prog) ) { - uint16_t caids[255]; - memset(caids, 0, sizeof(caids)); - std::vector<ProgramMapSection*>::const_iterator i = ptr->getSections().begin(); - for (; i != ptr->getSections().end(); ++i) - { - const ProgramMapSection &pmt = **i; - ElementaryStreamInfoConstIterator es = pmt.getEsInfo()->begin(); - for (; es != pmt.getEsInfo()->end(); ++es) - { - for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); - desc != (*es)->getDescriptors()->end(); ++desc) - { - switch ((*desc)->getTag()) - { - case CA_DESCRIPTOR: - { - const CaDescriptor *cadescr = (const CaDescriptor*)*desc; - uint16_t caid = cadescr->getCaSystemId(); - int idx=0; - while (caids[idx] && caids[idx] != caid) - ++idx; - caids[idx]=caid; - break; - } - } - } - } - for (DescriptorConstIterator desc = pmt.getDescriptors()->begin(); - desc != pmt.getDescriptors()->end(); ++desc) - { - switch ((*desc)->getTag()) - { - case CA_DESCRIPTOR: - { - const CaDescriptor *cadescr = (const CaDescriptor*)*desc; - uint16_t caid = cadescr->getCaSystemId(); - int idx=0; - while (caids[idx] && caids[idx] != caid) - ++idx; - caids[idx]=caid; - break; - } - } - } - } - int cnt=0; - while (caids[cnt]) - ++cnt; + int cnt=prog.caids.size(); if (cnt) { ret=PyList_New(cnt); + std::set<uint16_t>::iterator it(prog.caids.begin()); while(cnt--) - PyList_SET_ITEM(ret, cnt, PyInt_FromLong(caids[cnt])); + PyList_SET_ITEM(ret, cnt, PyInt_FromLong(*it++)); } } - if (!ret) - ret=PyList_New(0); - - return ret; + return ret ? ret : PyList_New(0); } int eDVBServicePMTHandler::getProgramInfo(struct program &program) @@ -213,7 +165,6 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) program.videoStreams.clear(); program.audioStreams.clear(); program.pcrPid = -1; - program.isCrypted = false; program.pmtPid = -1; program.textPid = -1; program.audioChannel = m_service ? m_service->getCacheEntry(eDVBService::cACHANNEL) : -1; @@ -243,7 +194,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) ElementaryStreamInfoConstIterator es; for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es) { - int isaudio = 0, isvideo = 0, cadescriptors = 0; + int isaudio = 0, isvideo = 0; videoStream video; audioStream audio; audio.component_tag=-1; @@ -317,9 +268,12 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) ((StreamIdentifierDescriptor*)*desc)->getComponentTag(); break; case CA_DESCRIPTOR: - ++cadescriptors; + { + CaDescriptor *descr = (CaDescriptor*)(*desc); + program.caids.insert(descr->getCaSystemId()); break; } + } } break; } @@ -346,22 +300,15 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) } else continue; - if ( cadescriptors > 0 ) - program.isCrypted=true; } - if ( !program.isCrypted ) + for (DescriptorConstIterator desc = pmt.getDescriptors()->begin(); + desc != pmt.getDescriptors()->end(); ++desc) { - for (DescriptorConstIterator desc = pmt.getDescriptors()->begin(); - desc != pmt.getDescriptors()->end(); ++desc) + if ((*desc)->getTag() == CA_DESCRIPTOR) { - switch ((*desc)->getTag()) - { - case CA_DESCRIPTOR: - program.isCrypted=true; - break; - } + CaDescriptor *descr = (CaDescriptor*)(*desc); + program.caids.insert(descr->getCaSystemId()); } - break; } } return 0; @@ -410,6 +357,9 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) ++cnt; program.textPid = tpid; } + CAID_LIST &caids = m_service->m_ca; + for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it) + program.caids.insert(*it); if ( cnt ) return 0; } @@ -499,6 +449,7 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, ref.getChannelID(chid); res = m_resourceManager->allocateChannel(chid, m_channel); eDebug("allocate Channel: res %d", res); + eDVBCIInterfaces::getInstance()->addPMTHandler(this); } else { eDVBMetaParser parser; @@ -549,7 +500,7 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, if (ref.path.empty()) { delete m_dvb_scan; - m_dvb_scan = new eDVBScan(m_channel); + m_dvb_scan = new eDVBScan(m_channel, false); m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); } } else diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index f4e99a57..57176d1f 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -117,11 +117,11 @@ public: { std::vector<videoStream> videoStreams; std::vector<audioStream> audioStreams; - // ca info + std::set<uint16_t> caids; int pcrPid; int pmtPid; int textPid; - bool isCrypted; + bool isCrypted() { return !caids.empty(); } int audioChannel; }; @@ -131,7 +131,8 @@ public: PyObject *getCaIds(); int getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel); - int getService(eServiceReferenceDVB &service) { service = m_reference; return 0; } + int getServiceReference(eServiceReferenceDVB &service) { service = m_reference; return 0; } + int getService(ePtr<eDVBService> &service) { service = m_service; return 0; } int getPMT(ePtr<eTable<ProgramMapSection> > &ptr) { return m_PMT.getCurrent(ptr); } int getChannel(eUsePtr<iDVBChannel> &channel); diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp index 3bfbe571..6549e32c 100644 --- a/lib/dvb/scan.cpp +++ b/lib/dvb/scan.cpp @@ -15,17 +15,18 @@ #include <lib/base/eerror.h> #include <lib/base/estring.h> #include <errno.h> -#include <set> -#define SCAN_eDebug(x...) eDebug(x) -#define SCAN_eDebugNoNewLine(x...) eDebugNoNewLine(x) +static bool scan_debug; +#define SCAN_eDebug(x...) if (scan_debug) eDebug(x) +#define SCAN_eDebugNoNewLine(x...) if (scan_debug) eDebugNoNewLine(x) DEFINE_REF(eDVBScan); -eDVBScan::eDVBScan(iDVBChannel *channel) - :m_channel(channel), m_ready(0), m_flags(0), m_ready_all(readySDT) - ,m_channel_state(iDVBChannel::state_idle) +eDVBScan::eDVBScan(iDVBChannel *channel, bool debug) + :m_channel(channel), m_channel_state(iDVBChannel::state_idle) + ,m_ready(0), m_ready_all(readySDT), m_flags(0) { + scan_debug=debug; if (m_channel->getDemux(m_demux)) SCAN_eDebug("scan: failed to allocate demux!"); m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection); @@ -100,10 +101,10 @@ RESULT eDVBScan::nextChannel() if (m_ch_toScan.empty()) { -// SCAN_eDebug("no channels left to scan."); -// SCAN_eDebug("%d channels scanned, %d were unavailable.", -// m_ch_scanned.size(), m_ch_unavailable.size()); -// SCAN_eDebug("%d channels in database.", m_new_channels.size()); + SCAN_eDebug("no channels left to scan."); + SCAN_eDebug("%d channels scanned, %d were unavailable.", + m_ch_scanned.size(), m_ch_unavailable.size()); + SCAN_eDebug("%d channels in database.", m_new_channels.size()); m_event(evtFinish); return -ENOENT; } @@ -528,7 +529,8 @@ void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags) dvb_service->m_service_name_sort = service->second->m_service_name_sort; } dvb_service->m_provider_name = service->second->m_provider_name; - + if (service->second->m_ca.size()) + dvb_service->m_ca = service->second->m_ca; if (!dontRemoveOldFlags) // do not remove new found flags when not wished dvb_service->m_flags &= ~eDVBService::dxNewFound; } @@ -580,7 +582,6 @@ RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescription SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str()); break; } -/* case CA_IDENTIFIER_DESCRIPTOR: { CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc; @@ -589,12 +590,11 @@ RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescription for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i) { SCAN_eDebugNoNewLine("%04x ", *i); - service->m_ca.insert(*i); + service->m_ca.push_front(*i); } SCAN_eDebug(""); break; } -*/ default: SCAN_eDebug("descr<%x>", (*desc)->getTag()); break; diff --git a/lib/dvb/scan.h b/lib/dvb/scan.h index 1fc55e0f..fe5e0686 100644 --- a/lib/dvb/scan.h +++ b/lib/dvb/scan.h @@ -65,7 +65,7 @@ private: int m_flags; public: - eDVBScan(iDVBChannel *channel); + eDVBScan(iDVBChannel *channel, bool debug=false); ~eDVBScan(); enum { scanNetworkSearch = 1, scanSearchBAT = 2, scanRemoveServices = 4, scanDontRemoveFeeds=8 }; |
