From eac0d61d225fa86c7ba6980afd78a2095de1abe3 Mon Sep 17 00:00:00 2001 From: CoreELEC Build Date: Fri, 15 May 2026 06:22:30 +0000 Subject: [PATCH] libcec: fix HDMI input grab-back on routing change to external device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patches SetActiveRoute() and HandleSetStreamPath() to call MarkAsInactiveSource() on all libCEC-controlled devices when CEC routing changes to a known external device (one not handled by libCEC). Without this fix, m_bActiveSource stays true after the user switches input away via the TV remote. When the TV broadcasts REQUEST_ACTIVE_SOURCE ~30 seconds later, libCEC responds and steals the HDMI input back — a long-standing user-visible regression where the box yanks focus from whatever the user just switched to. The patch file landed in two follow-up fixes for the patch format itself (formerly separate commits, now squashed): - Fix a malformed blank context line between SetActiveRoute and SetStreamPath where the leading space had been stripped, causing `patch` to treat it as end-of-hunk and report the file as malformed. - Fix wrong old/new line counts in both hunks and trim the second hunk's leading context from 13 lines (needing fuzz 12) to 3 so the patch applies cleanly with default fuzz. End state is a single packages/mediacenter/libcec/patches/ libcec-001-fix-active-source-on-routing-change.patch that applies cleanly against the current libcec source tree. --- ...-fix-active-source-on-routing-change.patch | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 packages/devel/libcec/patches/libcec-001-fix-active-source-on-routing-change.patch diff --git a/packages/devel/libcec/patches/libcec-001-fix-active-source-on-routing-change.patch b/packages/devel/libcec/patches/libcec-001-fix-active-source-on-routing-change.patch new file mode 100644 index 0000000000..eab253f8b7 --- /dev/null +++ b/packages/devel/libcec/patches/libcec-001-fix-active-source-on-routing-change.patch @@ -0,0 +1,55 @@ +From: CoreELEC +Subject: [PATCH] Fix HDMI input grab-back when routing changes to external device + +When ROUTING_CHANGE or SET_STREAM_PATH points to a device not handled by +libCEC, mark our own devices as inactive sources. Without this fix, +m_bActiveSource stays true; when the TV broadcasts REQUEST_ACTIVE_SOURCE +(~30 seconds after the user switches away), libCEC responds and steals the +HDMI input back. + +Root cause: libcec issue #76, closed upstream as "not planned". Critical +for Amlogic/AOCEC where SET_STREAM_PATH to a known external device is the +only signal that the user has switched away. + +--- + src/libcec/devices/CECBusDevice.cpp | 9 ++++++++- + src/libcec/implementations/CECCommandHandler.cpp | 9 +++++++++ + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/libcec/devices/CECBusDevice.cpp b/src/libcec/devices/CECBusDevice.cpp +--- a/src/libcec/devices/CECBusDevice.cpp ++++ b/src/libcec/devices/CECBusDevice.cpp +@@ -1237,6 +1237,15 @@ void CCECBusDevice::SetActiveRoute(uint16_t iRoute) + if (newRoute && newRoute->IsHandledByLibCEC() && (!ActiveSourceSent() || !newRoute->IsActiveSource())) + { +- // we were made the active source, send notification ++ // routing to our device - activate it + newRoute->ActivateSource(); + } ++ else if (newRoute && !newRoute->IsHandledByLibCEC()) ++ { ++ // routing to external device - mark our devices inactive so we don't ++ // respond to REQUEST_ACTIVE_SOURCE and steal the input back ++ CECDEVICEVEC myDevices; ++ map->GetLibCECControlled(myDevices); ++ for (CECDEVICEVEC::iterator it = myDevices.begin(); it != myDevices.end(); it++) ++ (*it)->MarkAsInactiveSource(); ++ } + } +diff --git a/src/libcec/implementations/CECCommandHandler.cpp b/src/libcec/implementations/CECCommandHandler.cpp +--- a/src/libcec/implementations/CECCommandHandler.cpp ++++ b/src/libcec/implementations/CECCommandHandler.cpp +@@ -655,5 +655,13 @@ int CCECCommandHandler::HandleSetStreamPath(const cec_command &command) + device->TransmitActiveSource(true); + } + } ++ else ++ { ++ // stream path to known external device - deactivate our devices ++ CECDEVICEVEC myDevices; ++ m_processor->GetDevices()->GetLibCECControlled(myDevices); ++ for (CECDEVICEVEC::iterator it = myDevices.begin(); it != myDevices.end(); it++) ++ (*it)->MarkAsInactiveSource(); ++ } + return COMMAND_HANDLED; + }