cec: only poll devices that need to be polled. fix libcec initialisation
authorLars Op den Kamp <lars@opdenkamp.eu>
Mon, 28 Nov 2011 17:47:19 +0000 (18:47 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Mon, 28 Nov 2011 18:25:05 +0000 (19:25 +0100)
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h

index 772f1e2e2e36e0417a9d2ae92afdd594b0387003..132d01e4990f8440ba27b710f36b338cc9af7566 100644 (file)
@@ -131,7 +131,14 @@ bool CCECProcessor::Start(void)
       m_controller->AddLog(CEC_LOG_ERROR, "could not create a processor thread");
       return false;
     }
-    return true;
+
+    lock.Leave();
+    if (SetAckMask(m_logicalAddresses.AckMask()) &&
+        SetHDMIPort(m_iHDMIPort, true))
+    {
+      ScanCECBus();
+      return true;
+    }
   }
   else
     m_controller->AddLog(CEC_LOG_ERROR, "could not create a processor thread");
@@ -220,30 +227,19 @@ void *CCECProcessor::Process(void)
   cec_command           command;
   CCECAdapterMessage    msg;
 
+  if (m_logicalAddresses.IsEmpty() && !FindLogicalAddresses())
   {
-    if (m_logicalAddresses.IsEmpty() && !FindLogicalAddresses())
-    {
-      CLockObject lock(&m_mutex);
-      m_controller->AddLog(CEC_LOG_ERROR, "could not detect our logical addresses");
-      m_startCondition.Signal();
-      return NULL;
-    }
-
-    SetAckMask(m_logicalAddresses.AckMask());
-
-    ScanCECBus();
-
-    {
-      CLockObject lock(&m_mutex);
-      m_bStarted = true;
-      lock.Leave();
-
-      SetHDMIPort(m_iHDMIPort);
-
-      lock.Lock();
-      m_controller->AddLog(CEC_LOG_DEBUG, "processor thread started");
-      m_startCondition.Signal();
-    }
+    CLockObject lock(&m_mutex);
+    m_controller->AddLog(CEC_LOG_ERROR, "could not detect our logical addresses");
+    m_startCondition.Signal();
+    return NULL;
+  }
+  else
+  {
+    CLockObject lock(&m_mutex);
+    m_bStarted = true;
+    m_controller->AddLog(CEC_LOG_DEBUG, "processor thread started");
+    m_startCondition.Signal();
   }
 
   while (!IsStopped())
@@ -352,7 +348,7 @@ bool CCECProcessor::SetDeckInfo(cec_deck_info info, bool bSendUpdate /* = true *
   return bReturn;
 }
 
-bool CCECProcessor::SetHDMIPort(uint8_t iPort)
+bool CCECProcessor::SetHDMIPort(uint8_t iPort, bool bForce /* = false */)
 {
   bool bReturn(false);
 
@@ -361,7 +357,7 @@ bool CCECProcessor::SetHDMIPort(uint8_t iPort)
   AddLog(CEC_LOG_DEBUG, strLog);
 
   m_iHDMIPort = iPort;
-  if (!m_bStarted)
+  if (!m_bStarted && !bForce)
     return true;
 
   uint16_t iPhysicalAddress(0);
@@ -404,7 +400,7 @@ void CCECProcessor::ScanCECBus(void)
 
 bool CCECProcessor::CheckPhysicalAddress(uint16_t iPhysicalAddress)
 {
-  for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
+  for (unsigned int iPtr = 0; iPtr < 15; iPtr++)
   {
     if (m_busDevices[iPtr]->GetPhysicalAddress(false) == iPhysicalAddress)
       return true;
index 08a21a6e77a9d9b47c734363b132e308b8d04843..b20c664789aefaac474cef91994e9fc0b16c647e 100644 (file)
@@ -78,7 +78,7 @@ namespace CEC
       virtual bool SetActiveSource(cec_logical_address iAddress);
       virtual bool SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate = true);
       virtual bool SetDeckInfo(cec_deck_info info, bool bSendUpdate = true);
-      virtual bool SetHDMIPort(uint8_t iPort);
+      virtual bool SetHDMIPort(uint8_t iPort, bool bForce = false);
       virtual bool SetInactiveView(void);
       virtual bool SetLogicalAddress(cec_logical_address iLogicalAddress);
       virtual bool SetMenuState(cec_menu_state state, bool bSendUpdate = true);
index b54e0a5c636e5a89ea56edb61c7f616c4689f179..702b561c1016611bb9999484dac28537dd0a2bb1 100644 (file)
@@ -256,7 +256,8 @@ uint16_t CCECBusDevice::GetPhysicalAddress(bool bRefresh /* = true */)
     if (m_iPhysicalAddress == 0xFFFF || bRefresh)
     {
       lock.Leave();
-      RequestPhysicalAddress();
+      if (!RequestPhysicalAddress())
+        AddLog(CEC_LOG_ERROR, "failed to request the physical address");
       lock.Lock();
     }
   }
@@ -351,13 +352,62 @@ bool CCECBusDevice::MyLogicalAddressContains(cec_logical_address address) const
   return m_processor->HasLogicalAddress(address);
 }
 
-cec_bus_device_status CCECBusDevice::GetStatus(void)
+bool CCECBusDevice::NeedsPoll(void)
+{
+  bool bSendPoll(false);
+  switch (m_iLogicalAddress)
+  {
+  case CECDEVICE_PLAYBACKDEVICE3:
+    if (m_processor->m_busDevices[CECDEVICE_PLAYBACKDEVICE2]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_PLAYBACKDEVICE2:
+    if (m_processor->m_busDevices[CECDEVICE_PLAYBACKDEVICE1]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_RECORDINGDEVICE3:
+    if (m_processor->m_busDevices[CECDEVICE_RECORDINGDEVICE2]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_RECORDINGDEVICE2:
+    if (m_processor->m_busDevices[CECDEVICE_RECORDINGDEVICE1]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_TUNER4:
+    if (m_processor->m_busDevices[CECDEVICE_TUNER3]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_TUNER3:
+    if (m_processor->m_busDevices[CECDEVICE_TUNER2]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_TUNER2:
+    if (m_processor->m_busDevices[CECDEVICE_TUNER1]->GetStatus() == CEC_DEVICE_STATUS_PRESENT)
+      bSendPoll = true;
+    break;
+  case CECDEVICE_AUDIOSYSTEM:
+  case CECDEVICE_PLAYBACKDEVICE1:
+  case CECDEVICE_RECORDINGDEVICE1:
+  case CECDEVICE_TUNER1:
+  case CECDEVICE_TV:
+    bSendPoll = true;
+    break;
+  default:
+    break;
+  }
+
+  return bSendPoll;
+}
+
+cec_bus_device_status CCECBusDevice::GetStatus(bool bForcePoll /* = false */)
 {
   CLockObject lock(&m_mutex);
-  if (m_deviceStatus == CEC_DEVICE_STATUS_UNKNOWN)
+  if (m_deviceStatus == CEC_DEVICE_STATUS_UNKNOWN || bForcePoll)
   {
     lock.Leave();
-    bool bPollAcked = m_processor->PollDevice(m_iLogicalAddress);
+    bool bPollAcked(false);
+    if (bForcePoll || NeedsPoll())
+      bPollAcked = m_processor->PollDevice(m_iLogicalAddress);
 
     lock.Lock();
     m_deviceStatus = bPollAcked ? CEC_DEVICE_STATUS_PRESENT : CEC_DEVICE_STATUS_NOT_PRESENT;
index d8d751cca8fcb120f7774a2119927cab7c51d239..2ee12044674d1ea240e18c3c1911d701f6d581a6 100644 (file)
@@ -71,7 +71,7 @@ namespace CEC
     virtual cec_vendor_id         GetVendorId(void);
     virtual const char *          GetVendorName(void);
     virtual bool                  MyLogicalAddressContains(cec_logical_address address) const;
-    virtual cec_bus_device_status GetStatus(void);
+    virtual cec_bus_device_status GetStatus(bool bForcePoll = false);
 
     bool RequestCecVersion(void);
     bool RequestMenuLanguage(void);
@@ -108,6 +108,8 @@ namespace CEC
     virtual bool SendKeyRelease(bool bWait = true);
 
   protected:
+    bool NeedsPoll(void);
+
     cec_device_type       m_type;
     CStdString            m_strDeviceName;
     uint16_t              m_iPhysicalAddress;