From 7b01619d3e08506efea013b3bd34b0148803a120 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Thu, 2 Aug 2012 18:26:20 +0200 Subject: [PATCH] cec: fixed - ensure that the vendor commands are always sent for panasonic, and that the deck status for lg isn't reset. fixes some buttons not working after a second or delayed source switch --- src/lib/implementations/CECCommandHandler.cpp | 9 ++- src/lib/implementations/CECCommandHandler.h | 2 + src/lib/implementations/SLCommandHandler.cpp | 7 ++ src/lib/implementations/SLCommandHandler.h | 2 + src/lib/implementations/VLCommandHandler.cpp | 66 +++++++++++++++---- src/lib/implementations/VLCommandHandler.h | 7 +- 6 files changed, 78 insertions(+), 15 deletions(-) diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 46edf98..05f5606 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -1121,10 +1121,15 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f // update the power state and menu state m_busDevice->SetPowerStatus(CEC_POWER_STATUS_ON); - m_busDevice->SetMenuState(CEC_MENU_STATE_ACTIVATED); // TODO: LG + m_busDevice->SetMenuState(CEC_MENU_STATE_ACTIVATED); + + // vendor specific hook + VendorPreActivateSourceHook(); // power on the TV - bool bActiveSourceFailed = !m_busDevice->TransmitImageViewOn(); + bool bActiveSourceFailed(false); + if (m_processor->GetDevice(CECDEVICE_TV)->GetPowerStatus(m_busDevice->GetLogicalAddress()) != CEC_POWER_STATUS_ON) + bActiveSourceFailed = !m_busDevice->TransmitImageViewOn(); // check if we're allowed to switch sources bool bSourceSwitchAllowed = SourceSwitchAllowed(); diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index 45e3522..61f9f47 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -138,6 +138,8 @@ namespace CEC virtual int HandleVendorRemoteButtonUp(const cec_command & UNUSED(command)) { return CEC_ABORT_REASON_REFUSED; } virtual void UnhandledCommand(const cec_command &command, const cec_abort_reason reason); + virtual void VendorPreActivateSourceHook(void) {}; + virtual size_t GetMyDevices(std::vector &devices) const; virtual CCECBusDevice *GetDevice(cec_logical_address iLogicalAddress) const; virtual CCECBusDevice *GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress) const; diff --git a/src/lib/implementations/SLCommandHandler.cpp b/src/lib/implementations/SLCommandHandler.cpp index 32902c2..f495b8b 100644 --- a/src/lib/implementations/SLCommandHandler.cpp +++ b/src/lib/implementations/SLCommandHandler.cpp @@ -416,3 +416,10 @@ bool CSLCommandHandler::PowerOn(const cec_logical_address iInitiator, const cec_ return CCECCommandHandler::PowerOn(iInitiator, iDestination); } + +void CSLCommandHandler::VendorPreActivateSourceHook(void) +{ + CCECPlaybackDevice *device = m_busDevice->AsPlaybackDevice(); + if (device) + device->SetDeckStatus(!device->IsActiveSource() ? CEC_DECK_INFO_OTHER_STATUS : CEC_DECK_INFO_OTHER_STATUS_LG); +} diff --git a/src/lib/implementations/SLCommandHandler.h b/src/lib/implementations/SLCommandHandler.h index 8cc64f1..2cbef7b 100644 --- a/src/lib/implementations/SLCommandHandler.h +++ b/src/lib/implementations/SLCommandHandler.h @@ -74,6 +74,8 @@ namespace CEC void SetSLInitialised(void); bool ActiveSourceSent(void); + void VendorPreActivateSourceHook(void); + bool m_bSLEnabled; bool m_bActiveSourceSent; PLATFORM::CTimeout m_resetPowerState; diff --git a/src/lib/implementations/VLCommandHandler.cpp b/src/lib/implementations/VLCommandHandler.cpp index e78f942..e74daac 100644 --- a/src/lib/implementations/VLCommandHandler.cpp +++ b/src/lib/implementations/VLCommandHandler.cpp @@ -52,7 +52,7 @@ using namespace PLATFORM; #define ToString(p) LIB_CEC->ToString(p) // wait this amount of ms before trying to switch sources after receiving the message from the TV that it's powered on -#define SOURCE_SWITCH_DELAY_MS 1000 +#define SOURCE_SWITCH_DELAY_MS 3000 CVLCommandHandler::CVLCommandHandler(CCECBusDevice *busDevice, int32_t iTransmitTimeout /* = CEC_DEFAULT_TRANSMIT_TIMEOUT */, @@ -60,7 +60,8 @@ CVLCommandHandler::CVLCommandHandler(CCECBusDevice *busDevice, int8_t iTransmitRetries /* = CEC_DEFAULT_TRANSMIT_RETRIES */, int64_t iActiveSourcePending /* = 0 */) : CCECCommandHandler(busDevice, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending), - m_iPowerUpEventReceived(0) + m_iPowerUpEventReceived(0), + m_bCapabilitiesSent(false) { m_vendorId = CEC_VENDOR_PANASONIC; } @@ -82,8 +83,6 @@ bool CVLCommandHandler::InitHandler(void) if (primary->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE) return m_processor->GetPrimaryClient()->ChangeDeviceType(CEC_DEVICE_TYPE_RECORDING_DEVICE, CEC_DEVICE_TYPE_PLAYBACK_DEVICE); - - m_processor->GetTV()->RequestPowerStatus(primary->GetLogicalAddress(), false); } return CCECCommandHandler::InitHandler(); @@ -96,6 +95,8 @@ int CVLCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &comman command.parameters[2] != 0x45) return CEC_ABORT_REASON_INVALID_OPERAND; + // XXX this is also sent when the TV is powered off +#if 0 if (command.initiator == CECDEVICE_TV && command.parameters.At(3) == VL_UNKNOWN1) { @@ -108,7 +109,9 @@ int CVLCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &comman // mark the TV as powered on m_processor->GetTV()->SetPowerStatus(CEC_POWER_STATUS_ON); } - else if (command.initiator == CECDEVICE_TV && + else +#endif + if (command.initiator == CECDEVICE_TV && command.destination == CECDEVICE_BROADCAST && command.parameters.At(3) == VL_POWER_CHANGE) { @@ -122,6 +125,9 @@ int CVLCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &comman } // mark the TV as powered on m_processor->GetTV()->SetPowerStatus(CEC_POWER_STATUS_ON); + + // send capabilties + SendVendorCommandCapabilities(m_processor->GetLogicalAddress(), command.initiator); } else if (command.parameters.At(4) == VL_POWERED_DOWN) { @@ -189,6 +195,34 @@ int CVLCommandHandler::HandleStandby(const cec_command &command) return CCECCommandHandler::HandleStandby(command); } +void CVLCommandHandler::VendorPreActivateSourceHook(void) +{ + bool bTransmit(false); + { + CLockObject lock(m_mutex); + bTransmit = m_bCapabilitiesSent; + } + if (bTransmit) + SendVendorCommandCapabilities(m_processor->GetLogicalAddress(), CECDEVICE_TV); +} + +void CVLCommandHandler::SendVendorCommandCapabilities(const cec_logical_address initiator, const cec_logical_address destination) +{ + cec_command response; + cec_command::Format(response, initiator, destination, CEC_OPCODE_VENDOR_COMMAND); + uint8_t iResponseData[] = {0x10, 0x02, 0xFF, 0xFF, 0x00, 0x05, 0x05, 0x45, 0x55, 0x5c, 0x58, 0x32}; + response.PushArray(12, iResponseData); + + if (Transmit(response, false, true)) + { + if (PowerUpEventReceived()) + { + CLockObject lock(m_mutex); + m_bCapabilitiesSent = true; + } + } +} + int CVLCommandHandler::HandleVendorCommand(const cec_command &command) { // some vendor command voodoo that will enable more buttons on the remote @@ -197,13 +231,7 @@ int CVLCommandHandler::HandleVendorCommand(const cec_command &command) command.parameters[1] == 0x01 && command.parameters[2] == 0x05) { - cec_command response; - cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND); - uint8_t iResponseData[] = {0x10, 0x02, 0xFF, 0xFF, 0x00, 0x05, 0x05, 0x45, 0x55, 0x5c, 0x58, 0x32}; - response.PushArray(12, iResponseData); - - Transmit(response, false, true); - + SendVendorCommandCapabilities(m_processor->GetLogicalAddress(), command.initiator); return COMMAND_HANDLED; } @@ -231,3 +259,17 @@ int CVLCommandHandler::HandleSystemAudioModeRequest(const cec_command &command) return CCECCommandHandler::HandleSystemAudioModeRequest(command); } + +int CVLCommandHandler::HandleReportPowerStatus(const cec_command &command) +{ + if (command.initiator == m_busDevice->GetLogicalAddress() && + command.parameters.size == 1 && + (cec_power_status)command.parameters[0] == CEC_POWER_STATUS_ON) + { + CLockObject lock(m_mutex); + if (m_iPowerUpEventReceived == 0) + m_iPowerUpEventReceived = GetTimeMs(); + } + + return CCECCommandHandler::HandleReportPowerStatus(command); +} diff --git a/src/lib/implementations/VLCommandHandler.h b/src/lib/implementations/VLCommandHandler.h index d1b25d2..3ad80b4 100644 --- a/src/lib/implementations/VLCommandHandler.h +++ b/src/lib/implementations/VLCommandHandler.h @@ -58,8 +58,13 @@ namespace CEC bool SourceSwitchAllowed(void); - private: + protected: + void VendorPreActivateSourceHook(void); + void SendVendorCommandCapabilities(const cec_logical_address initiator, const cec_logical_address destination); + int HandleReportPowerStatus(const cec_command &command); + PLATFORM::CMutex m_mutex; uint64_t m_iPowerUpEventReceived; + bool m_bCapabilitiesSent; }; }; -- 2.34.1