From: Lars Op den Kamp Date: Wed, 14 Nov 2012 02:43:14 +0000 (+0100) Subject: fixed - philips TVs ignore 'image view on' right after they were sent into standby... X-Git-Tag: upstream/2.2.0~1^2~12^2~20 X-Git-Url: https://git.piment-noir.org/?p=deb_libcec.git;a=commitdiff_plain;h=ebcedb051be7d8e1e19ecd3f0aa164baae252400 fixed - philips TVs ignore 'image view on' right after they were sent into standby. check the power status of the tv every 5 seconds, until it reports to have powered on --- diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index b304cb9..3e44752 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -643,6 +643,8 @@ bool CCECBusDevice::RequestPowerStatus(const cec_logical_address initiator, bool { MarkBusy(); bReturn = m_handler->TransmitRequestPowerStatus(initiator, m_iLogicalAddress, bWaitForResponse); + if (!bReturn) + SetPowerStatus(CEC_POWER_STATUS_UNKNOWN); MarkReady(); } return bReturn; diff --git a/src/lib/implementations/PHCommandHandler.cpp b/src/lib/implementations/PHCommandHandler.cpp index f8505c7..0d9f010 100644 --- a/src/lib/implementations/PHCommandHandler.cpp +++ b/src/lib/implementations/PHCommandHandler.cpp @@ -39,10 +39,43 @@ #include "lib/CECClient.h" using namespace CEC; +using namespace PLATFORM; #define LIB_CEC m_busDevice->GetProcessor()->GetLib() #define ToString(p) LIB_CEC->ToString(p) +#define TV_ON_CHECK_TIME_MS 5000 + +CImageViewOnCheck::~CImageViewOnCheck(void) +{ + StopThread(-1); + m_event.Broadcast(); + StopThread(); +} + +void* CImageViewOnCheck::Process(void) +{ + CCECBusDevice* tv = m_handler->m_processor->GetDevice(CECDEVICE_TV); + cec_power_status status(CEC_POWER_STATUS_UNKNOWN); + while (status != CEC_POWER_STATUS_ON) + { + m_event.Wait(TV_ON_CHECK_TIME_MS); + if (!IsRunning()) + return NULL; + + status = tv->GetPowerStatus(m_handler->m_busDevice->GetLogicalAddress()); + + if (status != CEC_POWER_STATUS_ON && + status != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON) + { + CLockObject lock(m_handler->m_mutex); + tv->OnImageViewOnSent(false); + m_handler->m_iActiveSourcePending = GetTimeMs(); + } + } + return NULL; +} + CPHCommandHandler::CPHCommandHandler(CCECBusDevice *busDevice, int32_t iTransmitTimeout /* = CEC_DEFAULT_TRANSMIT_TIMEOUT */, int32_t iTransmitWait /* = CEC_DEFAULT_TRANSMIT_WAIT */, @@ -51,9 +84,49 @@ CPHCommandHandler::CPHCommandHandler(CCECBusDevice *busDevice, CCECCommandHandler(busDevice, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending), m_iLastKeyCode(CEC_USER_CONTROL_CODE_UNKNOWN) { + m_imageViewOnCheck = new CImageViewOnCheck(this); m_vendorId = CEC_VENDOR_PHILIPS; } +CPHCommandHandler::~CPHCommandHandler(void) +{ + delete m_imageViewOnCheck; +} + +bool CPHCommandHandler::InitHandler(void) +{ + CCECBusDevice *primary = m_processor->GetPrimaryDevice(); + if (primary && primary->GetLogicalAddress() != CECDEVICE_UNREGISTERED) + { + //XXX hack to use this handler for the primary device + if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV && + primary && m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress()) + { + primary->SetVendorId(CEC_VENDOR_PHILIPS); + primary->ReplaceHandler(false); + } + } + + return CCECCommandHandler::InitHandler(); +} + +bool CPHCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = false */) +{ + + CCECBusDevice* tv = m_processor->GetDevice(CECDEVICE_TV); + if (m_busDevice->IsActiveSource() && + m_busDevice->IsHandledByLibCEC() && + tv && tv->GetCurrentPowerStatus() != CEC_POWER_STATUS_ON && + !bTransmitDelayedCommandsOnly) + { + // tv sometimes ignores image view on. check the power status of the tv in 5 seconds, and retry when it failed to power up + if (m_imageViewOnCheck && !m_imageViewOnCheck->IsRunning()) + m_imageViewOnCheck->CreateThread(false); + } + + return CCECCommandHandler::ActivateSource(bTransmitDelayedCommandsOnly); +} + int CPHCommandHandler::HandleUserControlPressed(const cec_command& command) { // tv keeps sending these until a button is pressed @@ -72,3 +145,16 @@ int CPHCommandHandler::HandleUserControlRelease(const cec_command& command) return CCECCommandHandler::HandleUserControlRelease(command); } + +int CPHCommandHandler::HandleDeviceVendorId(const cec_command& command) +{ + m_busDevice->SetPowerStatus(CEC_POWER_STATUS_ON); + return CCECCommandHandler::HandleDeviceVendorId(command); +} + +int CPHCommandHandler::HandleGiveDeviceVendorId(const cec_command& command) +{ + LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): vendor id feature abort", ToString(command.destination), command.destination, ToString(command.initiator), command.initiator); + m_processor->TransmitAbort(command.destination, command.initiator, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID); + return COMMAND_HANDLED; +} diff --git a/src/lib/implementations/PHCommandHandler.h b/src/lib/implementations/PHCommandHandler.h index 85338b4..a40d7b5 100644 --- a/src/lib/implementations/PHCommandHandler.h +++ b/src/lib/implementations/PHCommandHandler.h @@ -32,22 +32,46 @@ */ #include "CECCommandHandler.h" +#include "platform/threads/threads.h" namespace CEC { + class CPHCommandHandler; + + class CImageViewOnCheck : public PLATFORM::CThread + { + public: + CImageViewOnCheck(CPHCommandHandler* handler): + m_handler(handler) {} + virtual ~CImageViewOnCheck(void); + + void* Process(void); + + private: + CPHCommandHandler* m_handler; + PLATFORM::CEvent m_event; + }; + class CPHCommandHandler : public CCECCommandHandler { + friend class CImageViewOnCheck; public: CPHCommandHandler(CCECBusDevice *busDevice, int32_t iTransmitTimeout = CEC_DEFAULT_TRANSMIT_TIMEOUT, int32_t iTransmitWait = CEC_DEFAULT_TRANSMIT_WAIT, int8_t iTransmitRetries = CEC_DEFAULT_TRANSMIT_RETRIES, int64_t iActiveSourcePending = 0); - virtual ~CPHCommandHandler(void) {}; + virtual ~CPHCommandHandler(void); + + bool InitHandler(void); protected: + virtual bool ActivateSource(bool bTransmitDelayedCommandsOnly = false); virtual int HandleUserControlPressed(const cec_command& command); virtual int HandleUserControlRelease(const cec_command& command); - uint8_t m_iLastKeyCode; + virtual int HandleGiveDeviceVendorId(const cec_command& command); + virtual int HandleDeviceVendorId(const cec_command& command); + uint8_t m_iLastKeyCode; + CImageViewOnCheck* m_imageViewOnCheck; }; };