From d3caa81bbff5c84e49cdc9c4c1de5d0b583eb45d Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Mon, 12 Nov 2012 17:42:20 +0100 Subject: [PATCH] signal all waiting threads when receiving an active source message, cache the current active source address, so the info doesn't get lost when we don't know the physical address yet. fixes incorrect or slow active source queries --- src/lib/CECProcessor.cpp | 2 +- src/lib/devices/CECBusDevice.cpp | 9 ++++++-- src/lib/devices/CECDeviceMap.cpp | 22 ++++++++++++++++++- src/lib/devices/CECDeviceMap.h | 4 ++++ src/lib/implementations/CECCommandHandler.cpp | 7 +++--- src/testclient/main.cpp | 3 ++- 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index e432033..399e065 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -351,7 +351,7 @@ cec_logical_address CCECProcessor::GetActiveSource(bool bRequestActiveSource /* if (activeSource) return activeSource->GetLogicalAddress(); - if (bRequestActiveSource) + if (bRequestActiveSource && m_busDevices->GetActiveSourceAddress() == CEC_INVALID_PHYSICAL_ADDRESS) { // request the active source from the bus CCECBusDevice *primary = GetPrimaryDevice(); diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index 3be7adf..4234ec7 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -532,6 +532,9 @@ bool CCECBusDevice::SetPhysicalAddress(uint16_t iNewAddress) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X): physical address changed from %04x to %04x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress, iNewAddress); m_iPhysicalAddress = iNewAddress; + + if (m_processor->GetDevices()->GetActiveSourceAddress() == iNewAddress) + MarkAsActiveSource(); } return true; } @@ -966,7 +969,8 @@ void CCECBusDevice::MarkAsActiveSource(void) if (bWasActivated) { - m_processor->SetActiveSource(true, false); + if (IsHandledByLibCEC()) + m_processor->SetActiveSource(true, false); CCECClient *client = GetClient(); if (client) client->SourceActivated(m_iLogicalAddress); @@ -988,7 +992,8 @@ void CCECBusDevice::MarkAsInactiveSource(bool bClientUnregistered /* = false */) if (bWasDeactivated) { - m_processor->SetActiveSource(false, bClientUnregistered); + if (IsHandledByLibCEC()) + m_processor->SetActiveSource(false, bClientUnregistered); CCECClient *client = GetClient(); if (client) client->SourceDeactivated(m_iLogicalAddress); diff --git a/src/lib/devices/CECDeviceMap.cpp b/src/lib/devices/CECDeviceMap.cpp index 23e7a6f..1280de6 100644 --- a/src/lib/devices/CECDeviceMap.cpp +++ b/src/lib/devices/CECDeviceMap.cpp @@ -45,7 +45,8 @@ using namespace std; using namespace CEC; CCECDeviceMap::CCECDeviceMap(CCECProcessor *processor) : - m_processor(processor) + m_processor(processor), + m_iActiveSource(CEC_INVALID_PHYSICAL_ADDRESS) { for (uint8_t iPtr = CECDEVICE_TV; iPtr <= CECDEVICE_BROADCAST; iPtr++) { @@ -206,6 +207,9 @@ CCECBusDevice *CCECDeviceMap::GetActiveSource(void) const { for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++) { + if (m_iActiveSource != CEC_INVALID_PHYSICAL_ADDRESS && !it->second->IsActiveSource() && + m_iActiveSource == it->second->GetCurrentPhysicalAddress()) + it->second->MarkAsActiveSource(); if (it->second->IsActiveSource()) return it->second; } @@ -283,3 +287,19 @@ void CCECDeviceMap::GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) devices.push_back(it->second); } } + +void CCECDeviceMap::SetActiveSource(uint16_t iPhysicalAddress) +{ + m_iActiveSource = iPhysicalAddress; +} + +uint16_t CCECDeviceMap::GetActiveSourceAddress(void) const +{ + return m_iActiveSource; +} + +void CCECDeviceMap::SignalAll(cec_opcode opcode) +{ + for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++) + it->second->SignalOpcode(opcode); +} diff --git a/src/lib/devices/CECDeviceMap.h b/src/lib/devices/CECDeviceMap.h index c27a2dd..50271dc 100644 --- a/src/lib/devices/CECDeviceMap.h +++ b/src/lib/devices/CECDeviceMap.h @@ -63,6 +63,9 @@ namespace CEC void GetActive(CECDEVICEVEC &devices) const; void GetByType(const cec_device_type type, CECDEVICEVEC &devices) const; void GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) const; + void SetActiveSource(uint16_t iPhysicalAddress); + uint16_t GetActiveSourceAddress(void) const; + void SignalAll(cec_opcode opcode); void GetPowerOffDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const; void GetWakeDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const; @@ -79,5 +82,6 @@ namespace CEC CECDEVICEMAP m_busDevices; CCECProcessor *m_processor; + uint16_t m_iActiveSource; }; } diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 3b0187a..5a2afb1 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -209,12 +209,13 @@ int CCECCommandHandler::HandleActiveSource(const cec_command &command) if (command.parameters.size == 2) { uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]); + m_processor->GetDevices()->SetActiveSource(iAddress); CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iAddress); if (device) - { device->MarkAsActiveSource(); - return COMMAND_HANDLED; - } + + m_processor->GetDevices()->SignalAll(command.opcode); + return COMMAND_HANDLED; } return CEC_ABORT_REASON_INVALID_OPERAND; diff --git a/src/testclient/main.cpp b/src/testclient/main.cpp index a1f3190..945935a 100644 --- a/src/testclient/main.cpp +++ b/src/testclient/main.cpp @@ -864,8 +864,8 @@ bool ProcessCommandSCAN(ICECAdapter *parser, const string &command, string & UNU if (addresses[iPtr]) { uint64_t iVendorId = parser->GetDeviceVendorId((cec_logical_address)iPtr); - bool bActive = parser->IsActiveSource((cec_logical_address)iPtr); uint16_t iPhysicalAddress = parser->GetDevicePhysicalAddress((cec_logical_address)iPtr); + bool bActive = parser->IsActiveSource((cec_logical_address)iPtr); cec_version iCecVersion = parser->GetDeviceCecVersion((cec_logical_address)iPtr); cec_power_status power = parser->GetDevicePowerStatus((cec_logical_address)iPtr); cec_osd_name osdName = parser->GetDeviceOSDName((cec_logical_address)iPtr); @@ -888,6 +888,7 @@ bool ProcessCommandSCAN(ICECAdapter *parser, const string &command, string & UNU } } + activeSource = parser->GetActiveSource(); strLog.AppendFormat("currently active source: %s (%d)", parser->ToString(activeSource), (int)activeSource); PrintToStdOut(strLog); -- 2.34.1