#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <fstream>
DEFINE_REF(eDVBRegisteredFrontend);
DEFINE_REF(eDVBRegisteredDemux);
num_adapter++;
}
+ setUsbTuner();
+
int fd = open("/proc/stb/info/model", O_RDONLY);
char tmp[255];
int rd = fd >= 0 ? read(fd, tmp, 255) : 0;
}
+void eDVBResourceManager::setUsbTuner()
+{
+ std::ifstream in("/proc/bus/nim_sockets");
+ std::string line;
+
+ int res = -1;
+ int fe_idx = -1;
+ int usbtuner_idx[8] = {0};
+ int usbtuner_count = 0;
+
+ if (in.is_open())
+ {
+ while(!in.eof())
+ {
+ getline(in, line);
+ if ((res = sscanf(line.c_str(), "NIM Socket %d:", &fe_idx)) == 1)
+ continue;
+
+ if ((fe_idx != -1) && (line.find("\tName: ") == 0) && (line.find("VTUNER") != -1))
+ usbtuner_idx[usbtuner_count++] = fe_idx;
+ }
+ in.close();
+ }
+
+ if (usbtuner_count)
+ {
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_frontend.begin()); it != m_frontend.end(); ++it)
+ {
+ int slotid = it->m_frontend->getSlotID();
+ for (int i=0; i < usbtuner_count ; i++)
+ {
+ if (slotid == usbtuner_idx[i])
+ {
+ it->m_frontend->setUSBTuner(true);
+ break;
+ }
+ }
+ }
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_simulate_frontend.begin()); it != m_simulate_frontend.end(); ++it)
+ {
+ int slotid = it->m_frontend->getSlotID();
+ for (int i=0; i < usbtuner_count ; i++)
+ {
+ if (slotid == usbtuner_idx[i])
+ {
+ it->m_frontend->setUSBTuner(true);
+ break;
+ }
+ }
+ }
+ }
+}
+
PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
{
if (!PyList_Check(list))
eSmartPtrList<eDVBRegisteredDemux> m_demux;
eSmartPtrList<eDVBRegisteredFrontend> m_frontend, m_simulate_frontend;
void addAdapter(iDVBAdapter *adapter);
+ void setUsbTuner();
struct active_channel
{
ePtr<eConnection> conn;
service->connectEvent(slot(*this, &eFCCServiceManager::FCCEvent), conn);
- FCCServiceElem elem = {ref, conn, fcc_state_preparing};
+ FCCServiceElem elem = {ref, conn, fcc_state_preparing, false};
m_FCCServices[service] = elem;
res = service->start();
case iPlayableService::evTuneFailed:
case iPlayableService::evFccFailed:
{
- eDebug("[eFCCServiceManager][%s] set service to state failed.", it->second.m_service_reference.toString().c_str());
+ eDebug("[eFCCServiceManager::FCCEvent][%s] set service to state failed.", it->second.m_service_reference.toString().c_str());
it->second.m_state = fcc_state_failed;
break;
}
RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr<iPlayableService> &service)
{
+ if (!isEnable())
+ return -1;
+
ePtr<iPlayableService> new_service = 0;
printFCCServices();
m_core->m_service_event_conn = 0;
m_core->m_runningService = 0;
- /* connect to fcc event */
- ePtr<eConnection> conn;
- it->first->connectEvent(slot(*this, &eFCCServiceManager::FCCEvent), conn);
- it->second.m_service_event_conn = conn;
- it->second.m_state = fcc_state_preparing;
+ if (it->second.m_useNormalDecode)
+ {
+ /* stop service */
+ it->first->stop();
+ m_FCCServices.erase(it++);
+ }
+ else
+ {
+ /* connect to fcc event */
+ ePtr<eConnection> conn;
+ it->first->connectEvent(slot(*this, &eFCCServiceManager::FCCEvent), conn);
+ it->second.m_service_event_conn = conn;
+ it->second.m_state = fcc_state_preparing;
- /* switch to FCC prepare state */
- it->first->start();
+ /* switch to FCC prepare state */
+ it->first->start();
- /* update FCCServiceChannels */
- m_fccServiceChannels.addFCCService(it->second.m_service_reference);
+ /* update FCCServiceChannels */
+ m_fccServiceChannels.addFCCService(it->second.m_service_reference);
+ }
+ break;
}
}
if (service)
{
- FCCServiceElem elem = {sref, 0, fcc_state_decoding};
+ FCCServiceElem elem = {sref, 0, fcc_state_decoding, false};
m_FCCServices[service] = elem;
service->start(); // do FCC preparing
}
std::map< ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
for (;it != m_FCCServices.end();++it)
{
- eDebug(" [eFCCServiceManager::printFCCServices][*] sref : %s, state : %d, tune : %d", it->second.m_service_reference.toString().c_str(), it->second.m_state, isLocked(it->first));
+ 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);
}
#else
;
return false;
}
+bool eFCCServiceManager::isStateDecoding(iPlayableService* service)
+{
+ std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.find(service);
+ if (it != m_FCCServices.end())
+ {
+ return (it->second.m_state == fcc_state_decoding);
+ }
+ else
+ {
+ eDebug("[eFCCServiceManager] non registered FCC service");
+ }
+
+ return false;
+}
+
+void eFCCServiceManager::setNormalDecoding(iPlayableService* service)
+{
+ std::map<ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.find(service);
+ if (it != m_FCCServices.end())
+ {
+ eDebug("[eFCCServiceManager::setNormalDecoding][%s] set to use normal decoding.", it->second.m_service_reference.toString().c_str());
+ it->second.m_useNormalDecode = true;
+ }
+ else
+ {
+ eDebug("[eFCCServiceManager] non registered FCC service");
+ }
+}
+
DEFINE_REF(eFCCServiceManager);
eServiceReference m_service_reference;
ePtr<eConnection> m_service_event_conn;
int m_state;
+ bool m_useNormalDecode;
}FCCServiceElem;
class eFCCServiceManager: public iObject, public Object
static bool checkAvailable(const eServiceReference &ref);
void setFCCEnable(int enable) { m_fcc_enable = (enable != 0); }
bool isEnable() { return m_fcc_enable; }
+ bool isStateDecoding(iPlayableService* service);
+ void setNormalDecoding(iPlayableService* service);
};
#endif /* __dvb_fcc_h */
eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
:m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
- ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false)
+ ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false), m_is_usbtuner(false)
#if HAVE_DVB_API_VERSION < 3
,m_secfd(-1)
#endif
}
case frontendNumber:
return m_slotid;
+ case isUsbTuner:
+ return m_is_usbtuner;
}
return 0;
}
bool m_simulate;
bool m_enabled;
bool m_fbc;
+ bool m_is_usbtuner;
eDVBFrontend *m_simulate_fe; // only used to set frontend type in dvb.cpp
int m_dvbid;
int m_slotid;
void setEnabled(bool enable) { m_enabled = enable; }
bool isLoopTimerActive() { return m_tuneTimer->isActive(); }
bool isScheduledSendDiseqc();
+ void setUSBTuner(bool yesno) { m_is_usbtuner = yesno; }
};
#endif // SWIG
enum { stateIdle, stateTuning, stateFailed, stateLock, stateLostLock, stateClosed };
enum { toneOff, toneOn };
enum { voltageOff, voltage13, voltage18, voltage13_5, voltage18_5 };
- enum { bitErrorRate, signalPower, signalQuality, locked, synced, frontendNumber, signalQualitydB };
+ enum { bitErrorRate, signalPower, signalQuality, locked, synced, frontendNumber, signalQualitydB, isUsbTuner };
};
SWIG_IGNORE(iDVBFrontend);
if (!simulate)
eDebug("allocate Channel: res %d", res);
+ if (!res)
+ serviceEvent(eventChannelAllocated);
+
ePtr<iDVBChannelList> db;
if (!m_resourceManager->getChannelList(db))
db->getService((eServiceReferenceDVB&)m_reference, m_service);
eventMisconfiguration, // a channel was not found in any list, or no frontend was found which could provide this channel
eventNoDiskSpace, // no disk space available
eventStartPvrDescramble, // start PVR Descramble Convert
+ eventChannelAllocated,
};
#ifndef SWIG
Signal1<void,int> serviceEvent;
eDVBServiceFCCPlay::eDVBServiceFCCPlay(const eServiceReference &ref, eDVBService *service)
:eDVBServicePlay(ref, service, false), m_fcc_flag(0), m_fcc_mode(fcc_mode_preparing), m_fcc_mustplay(false),
- m_pmtVersion(-1)
+ m_pmtVersion(-1), m_normal_decoding(false)
{
CONNECT(m_service_handler.serviceEvent, eDVBServiceFCCPlay::serviceEvent);
}
pushbackFCCEvents(evTuneFailed);
break;
}
+ case eDVBServicePMTHandler::eventChannelAllocated:
+ {
+ bool is_usb_tuner = checkUsbTuner();
+ bool fcc_state_decoding = getFCCStateDecoding();
+ int slotId = getFrontendInfo(iDVBFrontend_ENUMS::frontendNumber);
+
+ if (is_usb_tuner)
+ {
+ if (fcc_state_decoding)
+ {
+ m_normal_decoding = true;
+ setNormalDecoding();
+ }
+ else
+ {
+ eDVBServicePlay::serviceEvent(eDVBServicePMTHandler::eventTuneFailed);
+ pushbackFCCEvents(evTuneFailed);
+ }
+ }
+ break;
+ }
case eDVBServicePMTHandler::eventNewProgramInfo:
{
- eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
- if (m_timeshift_enabled)
+ if (m_fcc_flag & fcc_tune_failed)
+ return;
+
+ eDebug("eventNewProgramInfo %d %d %d", m_timeshift_enabled, m_timeshift_active, m_normal_decoding);
+ if (m_normal_decoding)
+ {
+ eDVBServicePlay::serviceEvent(event);
+ }
+ else
+ {
+ if (m_timeshift_enabled)
updateTimeshiftPids();
- if (!m_timeshift_active)
- processNewProgramInfo();
+ if (!m_timeshift_active)
+ processNewProgramInfo();
- if (!m_timeshift_active)
- {
- m_event((iPlayableService*)this, evUpdatedInfo);
- pushbackFCCEvents(evUpdatedInfo);
+ if (!m_timeshift_active)
+ {
+ m_event((iPlayableService*)this, evUpdatedInfo);
+ pushbackFCCEvents(evUpdatedInfo);
+ }
}
break;
}
for (std::list<int>::iterator it = m_fcc_events.begin(); it != m_fcc_events.end(); ++it)
{
int event = *it;
-// eDebug("[eDVBServiceFCCPlay::popFCCEvents][%s] send event : %s", m_reference.toString().c_str(), eventDesc[event]);
m_event((iPlayableService*)this, event);
}
}
/* free the timeshift service handler, we need the resources */
m_service_handler_timeshift.free();
- //updateDecoder(true);
m_fcc_flag &=~fcc_ready;
m_fcc_flag &=~fcc_decoding;
processNewProgramInfo(true);
}
+bool eDVBServiceFCCPlay::checkUsbTuner()
+{
+ return (bool)getFrontendInfo(iDVBFrontend_ENUMS::isUsbTuner);
+}
+
+bool eDVBServiceFCCPlay::getFCCStateDecoding()
+{
+ eFCCServiceManager *fcc_service_mgr = eFCCServiceManager::getInstance();
+ return fcc_service_mgr->isStateDecoding((iPlayableService*)this);
+}
+
+void eDVBServiceFCCPlay::setNormalDecoding()
+{
+ eFCCServiceManager *fcc_service_mgr = eFCCServiceManager::getInstance();
+ return fcc_service_mgr->setNormalDecoding((iPlayableService*)this);
+}
+
DEFINE_REF(eDVBServiceFCCPlay)
#include <lib/service/servicedvb.h>
#include <list>
+#include <lib/dvb/fcc.h>
+
class eDVBServiceFCCPlay: public eDVBServicePlay
{
DECLARE_REF(eDVBServiceFCCPlay);
void updateFCCDecoder(bool sendSeekableStateChanged=false);
void FCCDecoderStop();
void switchToLive();
+ bool checkUsbTuner();
+ bool getFCCStateDecoding();
+ void setNormalDecoding();
bool m_fcc_enable;
bool m_fcc_mustplay;
std::list<int> m_fcc_events;
int m_pmtVersion;
+ bool m_normal_decoding;
};
#endif /* __servicedvbfcc_h */
\ No newline at end of file