You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/posts/hdmi-cec.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,7 @@ To debug that mess I first wrote down how every device identified itself on the
35
35
-**Playback devices** – logical addresses `4`, `8`, `B` (Apple TV, PS5, Switch 2 and Xbox all competing for the three playback slots[^playback-limit])
36
36
-**Broadcast** – logical address `F` (messages to everyone)
37
37
38
-
[^playback-limit]: Amazingly, HDMI-CEC only defines only [**three** playback logical addresses](https://feintech.eu/en/blogs/know-how/wozu-dient-hdmi-cec): `4` (Playback 1), `8` (Playback 2), and `11` (`0xB`) (Playback 3). That’s fine if you have one streaming box and a couple of consoles. I had **four** playback-class boxes (Apple TV, PS5, Switch 2, Xbox) connected to the Denon. According to HDMI-CEC, only three of them can ever be “real” playback devices at once, so when the fourth one wakes up the TV and AVR have to reshuffle logical addresses on the fly. In practice this looked unhinged: if the Switch was on, changing input to Xbox was impossible, I'd get a quick black screen and the input snaps back to Xbox. None of this was a Samsung or Denon bug; it was just me exceeding the three-playback-device limit baked into the CEC spec.
38
+
[^playback-limit]: Amazingly, HDMI-CEC only defines only [**three** playback logical addresses](https://feintech.eu/en/blogs/know-how/wozu-dient-hdmi-cec): `4` (Playback 1), `8` (Playback 2), and `11`/`B` (Playback 3). That’s fine if you have one streaming box and a couple of consoles. I had **four** playback-class boxes (Apple TV, PS5, Switch 2, Xbox) connected to the Denon. According to HDMI-CEC, only three of them can ever be “real” playback devices at once, so when the fourth one wakes up the TV and AVR have to reshuffle logical addresses on the fly. In practice this looked unhinged: if the Switch was on, changing input to Xbox was impossible, I'd get a quick black screen and the input snaps back to Xbox. This is wild, but fortunately I only use one console at a time so it’s not a big deal. Probably not worth trying to fix.
39
39
40
40
Topology-wise, it looks like this:
41
41
@@ -158,14 +158,14 @@ So I put the system in standby, start logging, then wake Apple TV. I got the exp
158
158
```text
159
159
>> 8f:82:32:00 # Apple TV (logical 8) -> Broadcast: Active Source
160
160
...
161
-
>> 8f:a6:06:10:56:10 # Apple TV (logical 8) -> Denon (logical 5): ???
161
+
>> 8f:a6:06:10:56:10 # Apple TV (logical 8) -> Broadcast: ???
162
162
>> 5f:72:01 # Denon (logical 5) -> Broadcast: Set System Audio Mode (on)
163
163
```
164
164
165
165
Translated:
166
166
167
167
1. Apple TV announces itself as the active source.
168
-
2. Apple TV sends some magic bits to the Denon??
168
+
2. Apple TV broadcasts some magic bits?
169
169
3. Very soon after, the Denon tells everyone “System Audio Mode is on,” and the TV happily keeps output set to **Receiver** instead of flipping back to TV speakers.
170
170
171
171
I did the exact same experiment with PS5, Xbox, Switch 2 and the result was different:
@@ -175,7 +175,7 @@ I did the exact same experiment with PS5, Xbox, Switch 2 and the result was diff
175
175
# ...a bunch of reports, but no 5f:72:01
176
176
```
177
177
178
-
So what was the `8f:a6:06:10:56:10` frame when Apple TV was involved? With debug logs, `cec-client` showed `UNKNOWN (A6)`. So, opcode `A6` is not a standard CEC opcode, so`libCEC` labels it unknown because it’s in the vendor-specific range. The following bytes (`06:10:56:10`) could be Apple’s proprietary payload, like some capability or extended control. It's possible Samsung and Apple have a private handshake here that ultimately results in the Denon doing the right thing. It’s neat, but I couldn't rely on it since it’s undocumented and sending it manually from the Raspberry Pi's logical address had no effect. Impersonating Apple TV over CEC is not realistically viable and likely brittle.
178
+
So what was the `8f:a6:06:10:56:10` frame when Apple TV was involved? With debug logs, `cec-client` showed `UNKNOWN (A6)`. I suspect`libCEC` labels it unknown because it’s in the vendor-specific range. The following bytes (`06:10:56:10`) could be Apple’s proprietary payload, like some capability or extended control. It's possible Samsung and Apple have a private handshake here that ultimately results in the Denon doing the right thing. It’s neat, but I couldn't rely on it since it’s undocumented and sending it manually from the Raspberry Pi's logical address had no effect. Impersonating Apple TV over CEC is not realistically viable and likely brittle.
179
179
180
180
However, with [cec-o-matic.com](https://www.cec-o-matic.com), it was easy to craft a CEC frame for the Raspberry Pi to send a normal system audio mode request:
181
181
@@ -196,7 +196,7 @@ So the solution started to emerge: whenever a console wakes up and claims Active
196
196
197
197
## Don’t spam the bus!
198
198
199
-
The most obvious thing to do is to write a bash script that loops `cec-client` every few seconds and blast `on 5`. That sort of works, but it's not ideal:
199
+
Now that we know the basis of the automation, the most obvious thing to do is to write a bash script that loops `cec-client` every few seconds and blast `on 5`. That sort of works, but it's not ideal:
200
200
201
201
* Using a loop means the automation is delayed instead of reacting to actual CEC events.
202
202
* Every iteration spins up a new `cec-client`, binds to `/dev/cec0`, sends one command, and tears down.
0 commit comments