1 #include <lib/dvb/fcc.h>
2 #include <lib/nav/core.h>
3 #include <lib/base/nconfig.h>
4 #include <lib/base/eerror.h>
5 #include <lib/python/python.h>
9 void FCCServiceChannels::addFCCService(const eServiceReference &service)
11 eDVBChannelID fcc_chid;
13 ((const eServiceReferenceDVB&)service).getChannelID(fcc_chid);
15 if (m_fcc_chids.find(fcc_chid) != m_fcc_chids.end())
16 m_fcc_chids[fcc_chid] += 1;
18 m_fcc_chids[fcc_chid] = 1;
21 void FCCServiceChannels::removeFCCService(const eServiceReference &service)
23 eDVBChannelID fcc_chid;
24 ((const eServiceReferenceDVB&)service).getChannelID(fcc_chid);
26 if (m_fcc_chids.find(fcc_chid) != m_fcc_chids.end())
28 m_fcc_chids[fcc_chid] -= 1;
30 if (m_fcc_chids[fcc_chid] == 0)
31 m_fcc_chids.erase(fcc_chid);
35 int FCCServiceChannels::getFCCChannelID(std::map<eDVBChannelID, int> &fcc_chids)
37 if (!m_fcc_chids.size()) return -1;
39 fcc_chids = m_fcc_chids;
43 eFCCServiceManager *eFCCServiceManager::m_instance = (eFCCServiceManager*)0;
45 eFCCServiceManager* eFCCServiceManager::getInstance()
50 eFCCServiceManager::eFCCServiceManager(eNavigation *navptr)
51 :m_core(navptr), m_fcc_enable(false)
59 eFCCServiceManager::~eFCCServiceManager()
61 if (m_instance == this)
67 RESULT eFCCServiceManager::playFCCService(const eServiceReference &ref, ePtr<iPlayableService> &service)
69 std::map< ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
70 for (;it != m_FCCServices.end();++it)
72 ASSERT (ref != it->second.m_service_reference);
75 ASSERT(m_core->m_servicehandler);
76 RESULT res = m_core->m_servicehandler->play(ref, service);
81 ePtr<eConnection> conn;
82 service->connectEvent(slot(*this, &eFCCServiceManager::FCCEvent), conn);
84 FCCServiceElem elem = {ref, conn, fcc_state_preparing, false};
85 m_FCCServices[service] = elem;
87 res = service->start();
95 void eFCCServiceManager::FCCEvent(iPlayableService* service, int event)
97 std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.find(service);
98 if (it == m_FCCServices.end())
100 eDebug("[eFCCServiceManager] event for non registered FCC service");
106 case iPlayableService::evStart:
108 m_fccServiceChannels.addFCCService(it->second.m_service_reference);
111 case iPlayableService::evStopped:
113 m_fccServiceChannels.removeFCCService(it->second.m_service_reference);
116 case iPlayableService::evTuneFailed:
117 case iPlayableService::evFccFailed:
119 eDebug("[eFCCServiceManager::FCCEvent][%s] set service to state failed.", it->second.m_service_reference.toString().c_str());
120 it->second.m_state = fcc_state_failed;
127 RESULT eFCCServiceManager::cleanupFCCService()
129 if (m_FCCServices.size())
131 std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
132 for (;it != m_FCCServices.end();++it)
134 eDebug("[eFCCServiceManager] stop FCC service sref : %s", it->second.m_service_reference.toString().c_str());
138 m_FCCServices.clear();
143 RESULT eFCCServiceManager::stopFCCService(const eServiceReference &sref)
145 if (m_FCCServices.size())
147 std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
148 for (; it != m_FCCServices.end();)
150 if (it->second.m_service_reference == sref)
152 eDebug("[eFCCServiceManager] stop FCC service sref : %s", it->second.m_service_reference.toString().c_str());
154 m_FCCServices.erase(it++);
166 RESULT eFCCServiceManager::stopFCCService()
168 if (m_FCCServices.size())
170 std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
171 for (; it != m_FCCServices.end();)
173 if (it->second.m_state == fcc_state_failed)
175 eDebug("[eFCCServiceManager] stop FCC service sref : %s", it->second.m_service_reference.toString().c_str());
177 m_FCCServices.erase(it++);
190 RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr<iPlayableService> &service)
195 ePtr<iPlayableService> new_service = 0;
199 int get_fcc_decoding = 0;
201 /* stop previous decoding service */
202 std::map< ePtr<iPlayableService>, FCCServiceElem >::iterator it;
203 for (it = m_FCCServices.begin();it != m_FCCServices.end();++it)
205 if (it->second.m_state == fcc_state_decoding)
207 ASSERT(get_fcc_decoding == 0);
208 get_fcc_decoding = 1;
211 m_core->m_event(iPlayableService::evEnd);
213 /* kill service and event */
214 m_core->m_service_event_conn = 0;
215 m_core->m_runningService = 0;
217 if (it->second.m_useNormalDecode)
221 m_FCCServices.erase(it++);
225 /* connect to fcc event */
226 ePtr<eConnection> conn;
227 it->first->connectEvent(slot(*this, &eFCCServiceManager::FCCEvent), conn);
228 it->second.m_service_event_conn = conn;
229 it->second.m_state = fcc_state_preparing;
231 /* switch to FCC prepare state */
234 /* update FCCServiceChannels */
235 m_fccServiceChannels.addFCCService(it->second.m_service_reference);
241 /* search new service */
242 for (it = m_FCCServices.begin();it != m_FCCServices.end();++it)
244 if (it->second.m_service_reference == sref)
246 eDebug("[eFCCServiceManager] use FCC service sref : %s", it->second.m_service_reference.toString().c_str());
247 it->second.m_service_event_conn = 0; /* disconnect FCC event */
248 it->second.m_state = fcc_state_decoding;
249 new_service = it->first;
250 m_fccServiceChannels.removeFCCService(it->second.m_service_reference);
257 service = new_service;
260 else /* If new service is not found in FCC service list, cleanup all FCC prepared services and get new FCC service. */
263 m_core->stopService();
264 if (eFCCServiceManager::checkAvailable(sref))
266 ASSERT(m_core->m_servicehandler);
267 m_core->m_servicehandler->play(sref, service);
271 FCCServiceElem elem = {sref, 0, fcc_state_decoding, false};
272 m_FCCServices[service] = elem;
273 service->start(); // do FCC preparing
287 int eFCCServiceManager::isLocked(ePtr<iPlayableService> service)
289 ePtr<iFrontendInformation> ptr;
290 service->frontendInfo(ptr);
291 return ptr->getFrontendInfo(iDVBFrontend_ENUMS::locked);
294 PyObject *eFCCServiceManager::getFCCServiceList()
296 ePyObject dest = PyDict_New();
299 std::map< ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
300 for (;it != m_FCCServices.end();++it)
302 ePyObject tplist = PyList_New(0);
303 PyList_Append(tplist, PyInt_FromLong((long)it->second.m_state));
304 PyList_Append(tplist, PyInt_FromLong((long)isLocked(it->first)));
305 PyDict_SetItemString(dest, it->second.m_service_reference.toString().c_str(), tplist);
315 void eFCCServiceManager::printFCCServices()
318 eDebug(" [eFCCServiceManager::printFCCServices][*] total size : %d", m_FCCServices.size());
320 std::map< ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
321 for (;it != m_FCCServices.end();++it)
323 eDebug(" [eFCCServiceManager::printFCCServices][*] sref : %s, state : %d, tune : %d, useNormalDecode : %d", it->second.m_service_reference.toString().c_str(), it->second.m_state, isLocked(it->first), it->second.m_useNormalDecode);
330 int eFCCServiceManager::getFCCChannelID(std::map<eDVBChannelID, int> &fcc_chids)
332 eFCCServiceManager *fcc_mng = eFCCServiceManager::getInstance();
333 if (!fcc_mng) return -1;
334 return fcc_mng->m_fccServiceChannels.getFCCChannelID(fcc_chids);
337 bool eFCCServiceManager::checkAvailable(const eServiceReference &ref)
339 int serviceType = ref.getData(0);
340 eFCCServiceManager *fcc_mng = eFCCServiceManager::getInstance();
342 if ((ref.type == 1) && ref.path.empty() && (serviceType != 2) && (serviceType != 10) && fcc_mng) // no PVR, streaming, radio channel..
343 return fcc_mng->isEnable();
347 bool eFCCServiceManager::isStateDecoding(iPlayableService* service)
349 std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.find(service);
350 if (it != m_FCCServices.end())
352 return (it->second.m_state == fcc_state_decoding);
356 eDebug("[eFCCServiceManager] non registered FCC service");
362 void eFCCServiceManager::setNormalDecoding(iPlayableService* service)
364 std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.find(service);
365 if (it != m_FCCServices.end())
367 eDebug("[eFCCServiceManager::setNormalDecoding][%s] set to use normal decoding.", it->second.m_service_reference.toString().c_str());
368 it->second.m_useNormalDecode = true;
372 eDebug("[eFCCServiceManager] non registered FCC service");
376 DEFINE_REF(eFCCServiceManager);