From: hschang Date: Thu, 31 Aug 2017 01:57:11 +0000 (+0900) Subject: [FCC] Fix to perform normal decoding for usb tuner on FCC mode. X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=eb510064c67c19fec47fd04ea03017c17569e3c5;ds=sidebyside [FCC] Fix to perform normal decoding for usb tuner on FCC mode. --- diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index bc79306..b7b831b 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -15,6 +15,7 @@ #include #include #include +#include DEFINE_REF(eDVBRegisteredFrontend); DEFINE_REF(eDVBRegisteredDemux); @@ -93,6 +94,8 @@ eDVBResourceManager::eDVBResourceManager() num_adapter++; } + setUsbTuner(); + int fd = open("/proc/stb/info/model", O_RDONLY); char tmp[255]; int rd = fd >= 0 ? read(fd, tmp, 255) : 0; @@ -325,6 +328,59 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter) } +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::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::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)) diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index ff9ea6f..3e9fc7f 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -144,6 +144,7 @@ class eDVBResourceManager: public iObject, public Object eSmartPtrList m_demux; eSmartPtrList m_frontend, m_simulate_frontend; void addAdapter(iDVBAdapter *adapter); + void setUsbTuner(); struct active_channel { diff --git a/lib/dvb/fcc.cpp b/lib/dvb/fcc.cpp index e83dbc8..8b1021a 100644 --- a/lib/dvb/fcc.cpp +++ b/lib/dvb/fcc.cpp @@ -81,7 +81,7 @@ RESULT eFCCServiceManager::playFCCService(const eServiceReference &ref, ePtr 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(); @@ -116,7 +116,7 @@ void eFCCServiceManager::FCCEvent(iPlayableService* service, int event) 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; } @@ -189,6 +189,9 @@ RESULT eFCCServiceManager::stopFCCService() RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr &service) { + if (!isEnable()) + return -1; + ePtr new_service = 0; printFCCServices(); @@ -211,17 +214,27 @@ RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtrm_service_event_conn = 0; m_core->m_runningService = 0; - /* connect to fcc event */ - ePtr 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 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; } } @@ -255,7 +268,7 @@ RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtrstart(); // do FCC preparing } @@ -307,7 +320,7 @@ void eFCCServiceManager::printFCCServices() std::map< ePtr, 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 ; @@ -331,5 +344,34 @@ bool eFCCServiceManager::checkAvailable(const eServiceReference &ref) return false; } +bool eFCCServiceManager::isStateDecoding(iPlayableService* service) +{ + std::map, 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, 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); diff --git a/lib/dvb/fcc.h b/lib/dvb/fcc.h index aacd9d8..f47c07e 100644 --- a/lib/dvb/fcc.h +++ b/lib/dvb/fcc.h @@ -24,6 +24,7 @@ typedef struct _tagFccElem eServiceReference m_service_reference; ePtr m_service_event_conn; int m_state; + bool m_useNormalDecode; }FCCServiceElem; class eFCCServiceManager: public iObject, public Object @@ -62,6 +63,8 @@ public: 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 */ diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 2892fe4..848b515 100755 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -502,7 +502,7 @@ int eDVBFrontend::PreferredFrontendIndex=-1; 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 @@ -1053,6 +1053,8 @@ int eDVBFrontend::readFrontendData(int type) } case frontendNumber: return m_slotid; + case isUsbTuner: + return m_is_usbtuner; } return 0; } diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h index 41dc311..c7eb149 100644 --- a/lib/dvb/frontend.h +++ b/lib/dvb/frontend.h @@ -77,6 +77,7 @@ private: 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; @@ -165,6 +166,7 @@ public: 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 diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index d0d1043..bc444b3 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -451,7 +451,7 @@ public: 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); diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index d5a7800..fbd9b8f 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -1165,6 +1165,9 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_dem if (!simulate) eDebug("allocate Channel: res %d", res); + if (!res) + serviceEvent(eventChannelAllocated); + ePtr db; if (!m_resourceManager->getChannelList(db)) db->getService((eServiceReferenceDVB&)m_reference, m_service); diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index f26e453..fc5d849 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -192,6 +192,7 @@ public: 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 serviceEvent; diff --git a/lib/service/servicedvbfcc.cpp b/lib/service/servicedvbfcc.cpp index 7cabb03..b2b53f9 100644 --- a/lib/service/servicedvbfcc.cpp +++ b/lib/service/servicedvbfcc.cpp @@ -5,7 +5,7 @@ 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); } @@ -43,19 +43,50 @@ void eDVBServiceFCCPlay::serviceEvent(int event) 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; } @@ -125,7 +156,6 @@ void eDVBServiceFCCPlay::popFCCEvents() for (std::list::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); } } @@ -447,11 +477,27 @@ void eDVBServiceFCCPlay::switchToLive() /* 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) diff --git a/lib/service/servicedvbfcc.h b/lib/service/servicedvbfcc.h index 54a0dca..5401e49 100644 --- a/lib/service/servicedvbfcc.h +++ b/lib/service/servicedvbfcc.h @@ -4,6 +4,8 @@ #include #include +#include + class eDVBServiceFCCPlay: public eDVBServicePlay { DECLARE_REF(eDVBServiceFCCPlay); @@ -20,6 +22,9 @@ protected: void updateFCCDecoder(bool sendSeekableStateChanged=false); void FCCDecoderStop(); void switchToLive(); + bool checkUsbTuner(); + bool getFCCStateDecoding(); + void setNormalDecoding(); bool m_fcc_enable; @@ -42,6 +47,7 @@ protected: bool m_fcc_mustplay; std::list m_fcc_events; int m_pmtVersion; + bool m_normal_decoding; }; #endif /* __servicedvbfcc_h */ \ No newline at end of file