[FCC] Fix to perform normal decoding for usb tuner on FCC mode.
authorhschang <chang@dev3>
Thu, 31 Aug 2017 01:57:11 +0000 (10:57 +0900)
committerhschang <chang@dev3>
Thu, 31 Aug 2017 10:07:44 +0000 (19:07 +0900)
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/fcc.cpp
lib/dvb/fcc.h
lib/dvb/frontend.cpp
lib/dvb/frontend.h
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/service/servicedvbfcc.cpp
lib/service/servicedvbfcc.h

index bc79306..b7b831b 100644 (file)
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <fstream>
 
 DEFINE_REF(eDVBRegisteredFrontend);
 DEFINE_REF(eDVBRegisteredDemux);
 
 DEFINE_REF(eDVBRegisteredFrontend);
 DEFINE_REF(eDVBRegisteredDemux);
@@ -93,6 +94,8 @@ eDVBResourceManager::eDVBResourceManager()
                num_adapter++;
        }
 
                num_adapter++;
        }
 
+       setUsbTuner();
+
        int fd = open("/proc/stb/info/model", O_RDONLY);
        char tmp[255];
        int rd = fd >= 0 ? read(fd, tmp, 255) : 0;
        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<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))
 PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
 {
        if (!PyList_Check(list))
index ff9ea6f..3e9fc7f 100644 (file)
@@ -144,6 +144,7 @@ class eDVBResourceManager: public iObject, public Object
        eSmartPtrList<eDVBRegisteredDemux> m_demux;
        eSmartPtrList<eDVBRegisteredFrontend> m_frontend, m_simulate_frontend;
        void addAdapter(iDVBAdapter *adapter);
        eSmartPtrList<eDVBRegisteredDemux> m_demux;
        eSmartPtrList<eDVBRegisteredFrontend> m_frontend, m_simulate_frontend;
        void addAdapter(iDVBAdapter *adapter);
+       void setUsbTuner();
 
        struct active_channel
        {
 
        struct active_channel
        {
index e83dbc8..8b1021a 100644 (file)
@@ -81,7 +81,7 @@ RESULT eFCCServiceManager::playFCCService(const eServiceReference &ref, ePtr<iPl
                ePtr<eConnection> conn;
                service->connectEvent(slot(*this, &eFCCServiceManager::FCCEvent), conn);
 
                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();
                m_FCCServices[service] = elem;
 
                res = service->start();
@@ -116,7 +116,7 @@ void eFCCServiceManager::FCCEvent(iPlayableService* service, int event)
                case iPlayableService::evTuneFailed:
                case iPlayableService::evFccFailed:
                {
                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;
                }
                        it->second.m_state = fcc_state_failed;
                        break;
                }
@@ -189,6 +189,9 @@ RESULT eFCCServiceManager::stopFCCService()
 
 RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr<iPlayableService> &service)
 {
 
 RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr<iPlayableService> &service)
 {
+       if (!isEnable())
+               return -1;
+
        ePtr<iPlayableService> new_service = 0;
 
        printFCCServices();
        ePtr<iPlayableService> new_service = 0;
 
        printFCCServices();
@@ -211,17 +214,27 @@ RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr<iPl
                        m_core->m_service_event_conn = 0;
                        m_core->m_runningService = 0;
 
                        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;
                }
        }
 
                }
        }
 
@@ -255,7 +268,7 @@ RESULT eFCCServiceManager::tryFCCService(const eServiceReference &sref, ePtr<iPl
 
                        if (service)
                        {
 
                        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
                        }
                                m_FCCServices[service] = elem;
                                service->start(); // do FCC preparing
                        }
@@ -307,7 +320,7 @@ void eFCCServiceManager::printFCCServices()
        std::map< ePtr<iPlayableService>, FCCServiceElem >::iterator it = m_FCCServices.begin();
        for (;it != m_FCCServices.end();++it)
        {
        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
        ;
        }
 #else
        ;
@@ -331,5 +344,34 @@ bool eFCCServiceManager::checkAvailable(const eServiceReference &ref)
        return false;
 }
 
        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);
 
 DEFINE_REF(eFCCServiceManager);
 
index aacd9d8..f47c07e 100644 (file)
@@ -24,6 +24,7 @@ typedef struct _tagFccElem
        eServiceReference m_service_reference;
        ePtr<eConnection> m_service_event_conn;
        int m_state;
        eServiceReference m_service_reference;
        ePtr<eConnection> m_service_event_conn;
        int m_state;
+       bool m_useNormalDecode;
 }FCCServiceElem;
 
 class eFCCServiceManager: public iObject, public Object
 }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; }
        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 */
 };
 
 #endif /* __dvb_fcc_h */
index 2892fe4..848b515 100755 (executable)
@@ -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)
 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
 #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 frontendNumber:
                        return m_slotid;
+               case isUsbTuner:
+                       return m_is_usbtuner;
        }
        return 0;
 }
        }
        return 0;
 }
index 41dc311..c7eb149 100644 (file)
@@ -77,6 +77,7 @@ private:
        bool m_simulate;
        bool m_enabled;
        bool m_fbc;
        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;
        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 setEnabled(bool enable) { m_enabled = enable; }
        bool isLoopTimerActive() { return m_tuneTimer->isActive(); }
        bool isScheduledSendDiseqc();
+       void setUSBTuner(bool yesno) { m_is_usbtuner = yesno; }
 };
 
 #endif // SWIG
 };
 
 #endif // SWIG
index d0d1043..bc444b3 100644 (file)
@@ -451,7 +451,7 @@ public:
        enum { stateIdle, stateTuning, stateFailed, stateLock, stateLostLock, stateClosed };
        enum { toneOff, toneOn };
        enum { voltageOff, voltage13, voltage18, voltage13_5, voltage18_5 };
        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);
 };
 
 SWIG_IGNORE(iDVBFrontend);
index d5a7800..fbd9b8f 100644 (file)
@@ -1165,6 +1165,9 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, int use_decode_dem
                if (!simulate)
                        eDebug("allocate Channel: res %d", res);
 
                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);
                ePtr<iDVBChannelList> db;
                if (!m_resourceManager->getChannelList(db))
                        db->getService((eServiceReferenceDVB&)m_reference, m_service);
index f26e453..fc5d849 100644 (file)
@@ -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
                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;
        };
 #ifndef SWIG
        Signal1<void,int> serviceEvent;
index 7cabb03..b2b53f9 100644 (file)
@@ -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),
 
 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);
 }
 {
        CONNECT(m_service_handler.serviceEvent, eDVBServiceFCCPlay::serviceEvent);
 }
@@ -43,19 +43,50 @@ void eDVBServiceFCCPlay::serviceEvent(int event)
                        pushbackFCCEvents(evTuneFailed);
                        break;
                }
                        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:
                {
                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();
 
                                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;
                }
                        }
                        break;
                }
@@ -125,7 +156,6 @@ void eDVBServiceFCCPlay::popFCCEvents()
        for (std::list<int>::iterator it = m_fcc_events.begin(); it != m_fcc_events.end(); ++it)
        {
                int event = *it;
        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);
        }
 }
                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();
 
        /* 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);
 }
 
        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)
 
 DEFINE_REF(eDVBServiceFCCPlay)
 
index 54a0dca..5401e49 100644 (file)
@@ -4,6 +4,8 @@
 #include <lib/service/servicedvb.h>
 #include <list>
 
 #include <lib/service/servicedvb.h>
 #include <list>
 
+#include <lib/dvb/fcc.h>
+
 class eDVBServiceFCCPlay: public eDVBServicePlay
 {
        DECLARE_REF(eDVBServiceFCCPlay);
 class eDVBServiceFCCPlay: public eDVBServicePlay
 {
        DECLARE_REF(eDVBServiceFCCPlay);
@@ -20,6 +22,9 @@ protected:
        void updateFCCDecoder(bool sendSeekableStateChanged=false);
        void FCCDecoderStop();
        void switchToLive();
        void updateFCCDecoder(bool sendSeekableStateChanged=false);
        void FCCDecoderStop();
        void switchToLive();
+       bool checkUsbTuner();
+       bool getFCCStateDecoding();
+       void setNormalDecoding();
 
        bool m_fcc_enable;
 
 
        bool m_fcc_enable;
 
@@ -42,6 +47,7 @@ protected:
        bool m_fcc_mustplay;
        std::list<int> m_fcc_events;
        int m_pmtVersion;
        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
 };
 
 #endif /* __servicedvbfcc_h */
\ No newline at end of file