「HDMI-CEC」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(→‎Native CEC: 翻訳)
37行目: 37行目:
 
Native CEC は主に ARM デバイスで[https://docs.kernel.org/admin-guide/media/cec.html#supported-hardware-in-mainline 見られます]。x86 世界では、[[#Tunneling over DisplayPort|DisplayPort経由のトンネリング]]が最も簡単なオプションです。それ以外では、一部の [[Chrome OS デバイス|Chrome OS]] デバイスと [https://www.seco.com SECO] [https://www.udoo.org UDOO] のシングルボードコンピューターのみが CEC を提供しています。
 
Native CEC は主に ARM デバイスで[https://docs.kernel.org/admin-guide/media/cec.html#supported-hardware-in-mainline 見られます]。x86 世界では、[[#Tunneling over DisplayPort|DisplayPort経由のトンネリング]]が最も簡単なオプションです。それ以外では、一部の [[Chrome OS デバイス|Chrome OS]] デバイスと [https://www.seco.com SECO] [https://www.udoo.org UDOO] のシングルボードコンピューターのみが CEC を提供しています。
   
  +
=== DisplayPort 経由のトンネリング ===
=== Tunneling over DisplayPort ===
 
   
This works with [[i915]], [[nouveau]] and [[AMDGPU|amdgpu]] drivers. The DisplayPort 1.3 standard (introduced in 2014) allows DisplayPort-to-HDMI adapters to use the auxiliary channel to forward CEC signals both ways. This is the sort of feature that adapters do not usually support unless mentioned, and is not commonly found, but it can counter-intuitively be cheaper and easier to use CEC tunneling over DisplayPort than a USB-CEC adapter. The kernel documentation page for the CEC submodule has [https://docs.kernel.org/admin-guide/media/cec.html#displayport-to-hdmi-adapters-with-working-cec a list of adapters] which have been confirmed to work.
+
これは [[i915]][[nouveau]][[AMDGPU|amdgpu]] ドライバーで機能します。2014 年に導入された DisplayPort 1.3 標準では、DisplayPort から HDMI アダプターを使用して補助チャネルを介して CEC 信号を双方向に転送することができます。これはアダプターが通常サポートしていない種類の機能であり、一般的ではありませんが、USB-CEC アダプターよりも直感に反して CEC のトンネリングを DisplayPort 経由で使用する方が安価で簡単な場合があります。CEC サブモジュールのカーネルドキュメントページには、動作が確認された[https://docs.kernel.org/admin-guide/media/cec.html#displayport-to-hdmi-adapters-with-working-cec アダプターのリスト]があります。
   
 
=== CEC adapter ===
 
=== CEC adapter ===

2024年4月5日 (金) 21:26時点における版

High-Definition Multimedia Interface - Consumer Electronics Control (HDMI-CEC) は、HDMI 接続内の追加の低速(50 B/s)バスであり、HDMI デバイスの「ネットワーク」が互いに通信するために使用できます。これにより、HDMI デバイスはお互いにオンまたはオフにすることを通知したり、テレビが入力を切り替えたり、リモコンのボタンが押されたりするなどの操作が可能になります。PC セットアップでは、通常、HTPC(ホームシアターPC)セットアップで遭遇します。

様々な理由から、ほとんどの PC GPU は CEC のハードウェアサポートを持っていません。ビデオゲームコンソールやセットトップボックスは通常、CEC ピンを駆動するために外部チップセットを含める必要があります。Raspberry Pi で見られる VideoCore GPU のようにネイティブ CEC サポートを持つデバイスもありますが、ほとんどのハードウェア構成では追加のハードウェアが必要です。

機能

CEC (Consumer Electronics Control) の主な目的は、テレビがそれに接続されているデバイスの状態を把握し、制御することを可能にすることです。そのため、特定の使用例に対応する「機能」のいくつかに分けられており、デバイスは発信者/フォロワーとしての役割、能力、ユーザー設定に基づいて、これらの機能をサポートするかどうかを選択できます。

標準化された機能は以下の通りです:

ワンタッチプレイ
デバイスが直ちにアクティブソースになることを希望していることを示し、自動的にテレビをオンにすることができます
ルーティング制御
テレビがHDMIスイッチを制御できるようにし、デバイスが現在アクティブなソースを確認できるようにします
リモートコントロールパススルー
デバイスが互いにリモコン信号を送信できるようにします。通常はテレビからアクティブソースへ送信されます
デッキコントロール
映画/音楽プレイヤーを制御し、その再生状態を照会する
スタンバイ/システムスタンバイ
デバイスが別の特定のデバイスの電源を切ることを要求したり、システム上のすべてのデバイスが今電源を切るべきだと放送することができます
電源状態
デバイスがスタンバイモードにあるか、オンになっているか、またはオンになるプロセス中にあるかを調べることができます
システムオーディオコントロール
テレビのオーディオリターンチャネルを介して接続されたAVレシーバーを制御できるようにし、音量を変更したりレシーバーの電源を入れたり切ったりできます
チューナーコントロール
任意のデバイスがチューナーデバイスに知られているテレビチャンネルのリストを通過し、アクティブなチャンネルの情報(アナログテレビのチャンネル番号やデジタルテレビのDVB/ATSC/ARIBトランスポートストリーム情報など)を照会できます
ワンタッチレコード
レコーダーがテレビが現在表示しているチャンネルを照会できるようにし、そのレコーダーが同じチャンネルにチューニングして録画を開始するか、既に現在アクティブなHDMIソースであれば自身や下流デバイスを録画すべきかを知ることができます
タイマープログラミング
テレビが特定の時間に特定のソースの録画を開始するためにレコーダー上のタイマーを設定できるようにします
OSD表示
デバイスがテレビ上にメッセージを表示できるようにします。1から13文字のASCII文字で
ダイナミックオートリップシンク
テレビがオーディオシンクへのプレゼンテーション遅延の変更を放送できるようにします。これは、独自のスピーカーを持つソース(PCなど)が画像との遅延補償に使用できます。
ヒント: リストにないもの:デバイスメニューコントロール(CEC 2.0で廃止)、OSD名転送(cec-ctlによって処理)、システム情報、ベンダー固有のコマンド(標準化されたメッセージなし)、オーディオレートコントロール(TV-AVのみ)、オーディオリターンチャネルコントロール(TV-AVのみ)

PC のようなデバイスにとって、これらの中で最も有用なのは「リモートコントロールパススルー」でしょう。HTPC にとっては「システムスタンバイ」が有用かもしれませんが、スクリーンがオフになったときに通常スリープ状態に入ることが期待されないより一般的な用途のマシンでは疑問の余地があります。「ルーティングコントロール」は、テレビがその入力を表示しようとするときにシステムを起動させるために使用できますが、接続されたPCがサスペンド中にCECトラフィックをリッスンする方法を持っている場合に限ります。「システムオーディオコントロール」は、一部の HDMI サウンド出力にとって便利ですが、現在、PipeWirePulseAudio といったもので音量制御の手段としては機能していません。

ハードウェアセットアップ

Linuxのカーネルには既に CEC イベントに自動的に応答し、処理するための組み込みのサブシステムがありますが、ハードウェアが正しく機能するためには最初に設定が必要になる場合があります。

Native CEC

Native CEC は主に ARM デバイスで見られます。x86 世界では、DisplayPort経由のトンネリングが最も簡単なオプションです。それ以外では、一部の Chrome OS デバイスと SECO UDOO のシングルボードコンピューターのみが CEC を提供しています。

DisplayPort 経由のトンネリング

これは i915nouveauamdgpu ドライバーで機能します。2014 年に導入された DisplayPort 1.3 標準では、DisplayPort から HDMI アダプターを使用して補助チャネルを介して CEC 信号を双方向に転送することができます。これはアダプターが通常サポートしていない種類の機能であり、一般的ではありませんが、USB-CEC アダプターよりも直感に反して CEC のトンネリングを DisplayPort 経由で使用する方が安価で簡単な場合があります。CEC サブモジュールのカーネルドキュメントページには、動作が確認されたアダプターのリストがあります。

CEC adapter

ノート: If you are looking to use HDMI-CEC with Kodi, know that it has built-in support for both Pulse-Eight and Raspberry Pi modes of CEC control and is incompatible with the following configuration.

PulseEight USB adapter

The PulseEight USB-CEC adapter works by passively extending all the pins of the HDMI connector on from the "PC side" connector to the "TV side" connector, save for the CEC pin, which is intercepted. The data going through that pin is instead exposed over a USB serial interface to let a PC control and monitor CEC traffic. The serial device needs to have its line discipline (a flag to signal to the kernel that a TTY is of a specific known type and requires a driver to work) configured manually before the kernel takes over and acknowledges it as a CEC adapter. This cannot be done automatically due to limitations around serial device APIs, so it is currently best achieved with a udev rule paired with a systemd unit (as udev rules cannot launch long-running or forking processes) to run inputattach --pulse8-cec ... when the device is plugged.

This serial interface appears as device node /dev/ttyACMX, and the inputattach utility is needed to set the line discipline and let the kernel drivers take over to create the /dev/cecX device that will be needed later. This requires the linuxconsole package.

ノート: Do not modify @$devnode in the following rule, it is a udev string substitution.
/etc/udev/rules.d/pulse8-cec-autoattach.rules
SUBSYSTEM=="tty" ACTION=="add" ATTRS{manufacturer}=="Pulse-Eight" ATTRS{product}=="CEC Adapter" TAG+="systemd" ENV{SYSTEMD_WANTS}="pulse8-cec-attach@$devnode.service"
/etc/systemd/system/pulse8-cec-attach@.service
[Unit]
# Should be called as "pulse8-cec-attach@-dev-ttyACM0.service" or similar
Description=Configure USB Pulse-Eight serial device at %I
ConditionPathExists=%I

[Service]
Type=forking
# inputattach is built without systemd daemon support by default, so systemd will have to guess the PID.
# https://sourceforge.net/p/linuxconsole/code/ci/a3366c0d5f82485e6aae7b005ec7a2d9a93bf458/tree/utils/inputattach.c#l1233

ExecStart=/usr/bin/inputattach --daemon --pulse8-cec %I

However, USB device connections are usually reset when the system wakes up from sleep (a step known as reset-resume) , meaning the serial connection will be lost if the computer is ever suspended, on top of serial connections usually hanging up on resume anyway. This means the above rule has to be triggered again somehow.

Unfortunately, the cdc_acm driver in charge of the ttyACM* object that the above rule reacts to does not raise any uevent about the connection being reset and the line discipline being lost, and the rule cannot be hooked on the USB device directly. Instead, the most reliable way to get the used rule above to trigger again at the right time is to delete and recreate the ttyACM* object by forcing the USB device to be reconfigured when it resets. In order to react to this and ensure the the connection is reopened, udev can keep track of when the USB device is reset and enumerated, as evidenced by the DEVNUM property being zeroed and later restored, and touching the bConfigurationValue sysfs attribute.

/etc/udev/rules.d/pulse8-cec-autoattach.rules
SUBSYSTEM=="tty" ACTION=="add" ATTRS{manufacturer}=="Pulse-Eight" ATTRS{product}=="CEC Adapter" TAG+="systemd" ENV{SYSTEMD_WANTS}="pulse8-cec-attach@$devnode.service"

# Force device to be reconfigured when reset after suspend, otherwise the ttyACM link is lost but udev will not notice.
# A usb_dev_uevent with DEVNUM=000 is a sign that the device is being reset before enumeration.
# Re-configuring causes ttyACM to be removed and re-added instead.
SUBSYSTEM=="usb" ACTION=="change" ATTR{manufacturer}=="Pulse-Eight" ATTR{product}=="CEC Adapter" ENV{DEVNUM}=="000" ATTR{bConfigurationValue}=="1" ATTR{bConfigurationValue}="1"

This essentially acts as if the USB adapter had been unplugged and re-plugged immediately upon coming out of sleep, ensuring the SUBSYSTEM=="tty" ACTION=="add" rule from before gets to run again. This ensures that the systemd service will be restarted as soon as the device is back to a usable state.

Software setup

CEC subsystem configuration

Now that the CEC subsystem has something to bind on and that /dev/cec0 has been created, it is now possible to configure the PC so other CEC devices know about it. When using the command-line, CEC devices are normally controlled via cec-ctl, which is part of v4l-utils.

One thing to be aware of is that the CEC pin alone does not have enough information on its own to send a valid CEC message. A CEC adapter that only monitors pin 13 (CEC) cannot know its "physical address" (its position in terms of port numbers in the "tree" of HDMI devices, such as 3.1.0.0), which it needs to be aware of in order to complete the logical address allocation procedure. Without a logical address, a device can only receive and send broadcast messages. The physical address is communicated over pin 16 (DDC/EDID), so configuring the CEC subsystem includes specifying which display output port is supposed to be associated with with that CEC object, in order for the physical address to be extracted from the display's EDID.

One way to find the name of the active connectors is to use xrandr --query (which also works on Wayland):

$ xrandr --query 
Screen 0: minimum 16 x 16, current 3840 x 2160, maximum 32767 x 32767
DP-1 connected primary 3840x2160+0+0 (normal left inverted right x axis y axis) 600mm x 340mm
   3840x2160     59.98*+
   2048x1536     59.95  
   ...
HDMI-A-1 connected 3840x2160+0+0 (normal left inverted right x axis y axis) 1440mm x 810mm
   3840x2160     59.98*+
   2048x1536     59.95  
   ...

Once the correct port has been identified (for example HDMI-A-1), then the sysfs port name can be found by using ls -1d /sys/class/drm/card*-HDMI-A-1 (such as card1-HDMI-A-1). In this case, the corresponding display's EDID data would be kept at /sys/class/drm/card1-HDMI-A-1/edid.

The physical address can be previewed like this:

$ edid-decode --physical-address /sys/class/drm/card1-DP-3/edid
4.0.0.0

Given how CEC configuration must be performed every time the cec device node is re-created, this is best handled with another udev rule that fires when the cec object appears.

ノート: Be sure to replace card1-HDMI-A-1 in the following rule by your connector name.
/etc/udev/rules.d/cec-configure-autostart.rules
SUBSYSTEM=="cec" KERNEL=="cec0" ACTION=="add" TAG+="systemd" ENV{SYSTEMD_WANTS}="cec0-configure@card1-HDMI-A-1.service"
/etc/systemd/system/cec0-configure@.service
[Unit]
# Should be called as "cec0-configure@card1-HDMI-A-1.service" or similar
Description=Configure CEC adapter cec0 assuming it runs on output %i
AssertPathExists=/sys/class/drm/%i/edid
BindsTo=dev-cec0.device

[Service]  
Type=exec  
# --phys-addr-from-edid-poll checks EDID every tenth of a second
# https://git.linuxtv.org/v4l-utils.git/tree/utils/cec-ctl/cec-ctl.cpp?id=0a195181d771090f3c99d4a6ddb8151352509061#n1977
# Use `Type=oneshot` if using `--phys-addr-from-edid` instead
ExecStart=/usr/bin/cec-ctl --device=0 "--osd-name=%H" --playback "--phys-addr-from-edid-poll=/sys/class/drm/%i/edid"

There are three device classes that an HDMI source can try to advertise itself as, which are "Recording device" (3 max), "Tuner" (4 max) and "Playback device" (3 max). This is important because HDMI devices do not use their physical address when communicating with each other over CEC, but a 4 bit "logical address", which identify devices as "Tuner #3" or "Playback Device #1", with a finite number of each. If address allocation fails because too many devices of one type are present, it may be assigned the "Backup" (2 max) role instead. These roles are intended to relate to the CEC features mentioned earlier, namely:

  • "Tuner" is supposed to support "Tuner Control"
  • "Recording device" is the only type that can use One Touch Record, as TVs are supposed to ignore related messages coming from other addresses
  • "Playback device" is for general purpose video sources. Computers, like video game consoles, are considered "Playback devices".

The above cec0-configure@.service unit uses --playback to configure a Playback device. It is, however, generally OK to set the device class to Tuner (--tuner) or Recorder (--record), whether because there are no more unused playback addresses, or simply to have the PC stand out in the list on TVs that visually set apart each device class in their input menus.

Input-handling daemons

Userspace tools

User access to /dev/cec* devices can be granted by enrolling users into the video user group. The basic tool for controlling CEC devices is cec-ctl from v4l-utils. A similar one is cec-client from libcec, for which there are also Python bindings available in python-cecAUR.

See also