- 4Kモニターとして認識されていた安価な HDMIダミープラグを、1080p HDMIキャプチャデバイスのように見せるため、内蔵の EDID EEPROM をRaspberry Piで書き換えた
- ダミープラグはHPDピンのプルアップとI2C EEPROMだけで、コンピューターにモニター接続を検出させる。EDIDが対応解像度・オーディオ・色空間などの表示デバイス情報を決定する
- Raspberry PiのHDMIポートにはEDID用の I2Cコントローラー が接続されており、モデルごとのバス番号を合わせれば、ダミープラグとキャプチャデバイスのEDIDを読み取って比較できる
- 実際の作業は、I2Cの有効化、
i2c-toolsのインストール、0x50アドレスの確認、get-edidによるダンプ、i2csetループによる 256バイト書き込み の順に進める
- 誤ったI2Cバスや実際のモニターに書き込みコマンドを実行すると、EDIDや他のEEPROMを壊す可能性があるため、書き込み前の解析と対象確認が必須
4Kダミープラグを1080pキャプチャデバイスのように見せる
- 以前Amazonで購入した安価な HDMIダミープラグ が4Kモニターのように動作するため、より単純で4K解像度に対応していないデバイスのように見えるよう変更する作業
- 目的は、ダミープラグのEDIDを複数の1080p HDMIキャプチャデバイスのいずれかの EDIDコピー に置き換えること
- 置き換えが終わると、コンピューターは4KモニターではなくHDMIキャプチャデバイスが接続されたものとして認識する
HDMIダミープラグとEDIDの役割
- HDMIやDVIなどのダミープラグは映像信号を実際には処理せず、コンピューターなどの映像出力デバイスがモニターが接続されたと判断するための最小限の回路だけを備える
- 一般に必要な要素は2つ
- EDIDには、モニターのメーカー、製造日、対応解像度、オーディオチャンネル、色空間などの情報が含まれる
- こうしたダミープラグは、ヘッドレスマシンでOSにモニターが接続されていると思わせるのに役立つ
Raspberry PiのHDMI I2Cバス
- Raspberry Pi ZeroのHDMIポートには、EDIDを読み取るための I2Cコントローラー が正しいピンに接続されている
- Piモデルごとに確認すべきI2Cバスは以下の通り
- Pi 0-3:
/dev/i2c-2
- Pi 4:
/dev/i2c-20, /dev/i2c-21
- Pi 5:
/dev/i2c-11, /dev/i2c-12
- Raspberry Pi Zeroを使う場合は
edid_i2c=2に設定する
- 他のモデルでは上の一覧に合わせてバス番号を変更する必要がある
準備作業
- 新規のRaspberry Pi OS Lite環境では、まずI2Cアクセス環境を準備する
sudo raspi-configを実行し、Interface Optionsで I2Cを有効化
sudo apt install i2c-toolsでI2Cツールをインストール
- Pi Zeroではネットワークアクセスが問題になることがあるため、USB-Ethernetアダプターが必要になる場合がある
- 代替案として、SDカードをDebian/UbuntuデスクトップPCに挿し、
binfmt-supportとqemu-user-staticをインストールしたうえで、SDカードのrootfsにchrootしてapt installを実行することもできる
- 作業環境によってはHDMI-to-Mini-HDMIアダプターも必要
元のEDIDの読み取りと検証
- まず、ダミープラグがEDID EEPROMとして認識されるか確認する
edid_i2c=2
i2cdetect -y $edid_i2c
- 結果ではアドレス
0x50にI2Cデバイスが検出され、これはEDIDで使われるアドレス
- このダミープラグは
0x51から0x57までも応答し、これらのアドレスには同じEDIDのコピーが入っているように見える
- すべてのダミープラグがこのように動作するわけではなく、別のダミープラグでは
0x50だけが検出された
- 元のEDIDは次のコマンドでダンプする
get-edid -b $edid_i2c > edid-orig.bin
get-edidはI2Cバス2から 256バイトEDID を正常に読み取ったと出力した
- 同じダンプを2回行い、結果が同一か比較する
- その後
odで16進ダンプを出力し、edidreader.comに貼り付けて有効なEDIDか確認する
od -v -An -txC edid-orig.bin
キャプチャデバイスのEDIDをダミープラグへ書き込む
- ダミープラグの元のEDIDをバックアップしたあと、PiのHDMIポートからダミープラグを外してHDMIキャプチャデバイスを接続する
- 同じ方法でキャプチャデバイスのEDIDをダンプする
get-edid -b $edid_i2c > edid-capture-card.bin
- キャプチャデバイスのEDIDも有効なEDIDか確認する
- その後キャプチャデバイスを外してダミープラグを再接続し、キャプチャデバイスのEDIDをダミープラグのEEPROMへ書き込む
edidbytes=($(od -v -An -txC edid-capture-card.bin))
for i in "${!edidbytes[@]}"; do
byte=0x${edidbytes[$i]}
echo Writing byte $i: $byte...
i2cset -f -y $edid_i2c 0x50 $i $byte
done
- このスクリプトはダンプファイルのEDIDを2桁の16進文字列配列にし、各バイトの前に
0xを付けてi2csetでEEPROMへ順番に書き込む
- edid-checked-writerのようなツールもあるが、上記の方法は標準のLinux userspace I2Cツールとbashまたはdashだけで動作する
書き込み結果の確認
- 書き込み後、再びダミープラグからEDIDを読み取り、キャプチャデバイスのEDIDファイルと比較する
get-edid -b $edid_i2c > edid-test.bin
diff edid-test.bin edid-capture-card.bin
diffが何も出力しなかったため、新しいダンプが元のキャプチャデバイスEDIDと同一であることを確認できた
- ダミープラグのEEPROMはキャプチャデバイスの EDIDに再プログラム された
- その後テスト用コンピューターに挿して起動すると、コンピューターは4KモニターではなくHDMIキャプチャデバイスが接続されたかのように動作した
書き込み前に確認すべきリスク
- 実際のモニターが接続された状態でこの手順を実行し、そのモニターのEDIDが保護されていない場合、モニターを壊す可能性がある
- 必ずダミープラグのような 壊れてもよいデバイス をHDMIポートに接続した状態でのみ、書き込みコマンドを実行すること
- 正しいI2Cバスであると確信する必要があり、書き込み前にEDIDを読み取って解析し、実際にEDIDが入っているか確認する必要がある
- PCでこのコマンドを実行すると、RAMモジュールのSPD EEPROMのようなEDIDではないハードウェアを誤ってフラッシュしてしまう可能性がある
- 実PCでI2C書き込みを試すより、Raspberry Piを使うことでデスクトップPCを壊すリスクを減らせる
- 同じ方法は逆に、古い1080pダミープラグへ4K対応EDIDを入れる用途にも使える
1件のコメント
Hacker News のコメント
自宅で試そうとしている人へのちょっとした注意点: こうした安価なダミープラグは EEPROM が 256 バイトしかないため、高解像度・高リフレッシュレート設定に必要な複数の拡張 EDID ブロックを保存するには足りません。
1080p60 だけでよければ問題ありませんが、4k240 モニターを模倣する用途には使えません。
また、一部は書き込み保護線が high または low に固定されているため、実際に書き込むには多少のハードウェア作業が必要です。
こうしたダミープラグの限界の一つは、HDCP に対応していない点です。
ヘッドレスマシンで特定解像度の出力を強制的に作る用途には向いていますが、HDCP を要求するものを実行する用途では失敗します。
HDMI ダミープラグのように動作しつつ、HDCP ネゴシエーションまで行ってくれる良い解決策があるのか気になります。
フル解像度で再生するには HDCP が必要な動画ストリーミングアプリをテストする必要があるのですが、テストごとに TV を 1 台ずつ用意するのは不便です。
これまで見つけた解決策は HDMI マルチビューアで、各ポートごとに HDCP を個別にネゴシエートしているように見えます。
プリセットされた EDID を使うか、HDMI 出力 1 に接続した機器から EDID を学習したうえで、分配器に電源さえ入っていれば、出力に何も接続していなくても接続済みモニターのように見せてくれます。
コンピューターやコンソールと分配器の間では HDCP をネゴシエートし、出力モニターへは HDCP なしで信号を送っているものと理解しています。
https://www.amazon.com/dp/B07VP37KMB
HDMI を出力する組み込みシステムがあり、起動画面を別の HDMI ストリームに差し替えたいのです。静止画像で十分です。
いくつかの理由から組み込みシステム自体は一切変更したくないのですが、これを安価で堅牢に実現する方法があるのか気になります。
ただし購入者は注意が必要です。
HDCP 1.4 より新しいものが必要なら、おそらくほぼ不可能です。
関連して、EDID バイナリを集めた良いアーカイブや、より良い生成プログラムがあるのか気になります。
プログラマブル EDID エミュレータープラグがあるので、自分のモニターや他のモニターを複製することはできますが、特定の解像度や機能を設定したいときに方法がない場合があります。たとえば DSC を含む 8K などです。
https://github.com/bsdhw/EDID は知っていますが、最近のモニターについてはかなり限られています。
https://www.analogway.com/products/aw-edid-editor で自作してみたこともありますが、複数モードの細かな違いや優先順位の設定などを正しく合わせるのは、少なくとも私にはかなり難しいです。
おすすめはこうです: すでに挙がっている AW EDID Editor、Windows 専用の CRU、EDID テンプレートがある 010 Hex Editor、Linux では Flatpak の wxEDID、v4l-utils の edid-decode。
CRU は、モニターからダンプした EDID ファイルを修正する際、詳細解像度の領域を作るためにシリアル番号のようなディスクリプタを削除しますが、動作はします。Wine では実行できません。
wxEDID は、ディストリビューションのパッケージが WxWidgets でクラッシュしていた記憶があり、セクションを新規作成できるかどうかは分かりません。
edid-decode は git diff の textconv ツールとしても使えますが、EDID ファイルのエンコードには役立ちません。
HDMI EDID には CEA 拡張ブロックがあり、DP EDID には DisplayID 拡張ブロックがあるようです。
256 バイトを超えるマルチページ EDID は扱ったことがなく、どの EEPROM チップでエミュレートすべきか、読み書きのプロトコル/API も分かりません。
https://www1.kramerav.com/au/product/edid%20designer
どちらも無料ですが、自由に再配布できるソフトウェアではありません。
Extron のほうは、そのハードウェアを使うプロジェクトや組織で働いている必要があるかもしれません。
HDMI 経由で Dolby TrueHD まで対応する安価な5.1 サラウンドサウンドバーを買ったのですが、落とし穴は eARC 対応機器、つまり新しい TV でしか正常に動作しない点です。
PC に接続すると SPDIF や AUX を使う必要があり、品質が落ちます。
オーディオエクストラクターや分配器を買う以外に、PC の EDID を偽装してサウンドバーに eARC として認識させる方法があります。
まだ作業中で、残念ながら明確なガイドラインはありません。
最近探してみたのですが、どの機器がどの機能を備えているのか、より安価な製品の中に良いものがあるのかが明確ではありませんでした。
このような製品はパススルー付きの形でも購入でき、高解像度モニターで問題を起こす古いシステムに有用です。
2011年ごろの AMD FX8350 システムを持っていますが、内蔵の 880G ノースブリッジ+ビデオチップセットが 4K ディスプレイへ HDMI 映像をうまく出力できません。
間にこの種の機器を接続して 1080p 画像を送るよう伝えると正常に動作し、モニター側が 4K に 2 倍の整数アップスケーリングをしてくれます。
私が持っているものはかなり高級なタイプで、モニターから EDID を読み取って保存し、別のモニター向けのオーバーライドとして使えます。
さらに素晴らしい点は、モニターが常に検出されるよう強制できることです。
私のモニターの一つは、電源を切ると実質的に切断されたかのように振る舞っていろいろ問題が起きていましたが、パススルーが完全に解決してくれました。
私が使っている製品は THWT の HD-EWB です。
HDMI ダミープラグは、そもそも存在すべきでないソフトウェア問題を解決するためのハードウェア的解決策です。
なぜダミープラグが必要なのか気になります。
ソフトウェアではできず、ダミープラグでしかできないことが何なのか分かりません。ダミーなしで仮想ディスプレイを 18 台、問題なく使ったことがある立場からの質問です。
コンピューターには GPU が 2 枚あり、AMD GPU は Linux ホスト用、NVidia GPU は Windows ゲストにパススルーされています。
Looking Glass は NVidia GPU の出力をキャプチャして、私のデスクトップ上のウィンドウに表示します。
この方式なら VM 上で Windows ソフトウェアを使え、性能も悪くありません。Windows は 7 以降、事実上グラフィックスアクセラレーションがないと実用的に動きません。
問題は、NVidia GPU がディスプレイ未接続だと何もしないことです。
NVidia Quadro GPU ならモニターの EDID をダンプして、そのファイルを出力にマッピングできますが、コンシューマー向け GPU はこれをサポートしていません。
そのためダミープラグが必要になります。
ダミープラグの画面を PowerPoint の出力に使い、ノート PC の画面を発表者ノートに使えばよいのです。
そのうえでダミープラグ側の画面を共有します。
Hacker News 読者にとっては最高の答えではないかもしれませんが、教師や営業担当者にとっては本当に簡単です。
OBS 配信や Steam、Parsec などのゲームストリーミング設定のために必要になることがあります。
数年前の Linux の Xorg とオープンソースドライバー、Windows と Nvidia の組み合わせではある程度できましたが、MacOS や Windows+AMD/Intel GPU ではそれほどうまく動きませんでした。
OS をだましてディスプレイが接続されているように見せると、ユーザーの実際の配布環境にはない新しい変数が生まれますが、ダミープラグは安価なハードウェア的解決策です。
エンジニアに
echo on > /sys/whateverとその周辺ロジックを書かせるより、買って挿すほうが費用対効果が高い可能性があります。リモートゲームストリーミングのために、ソフトウェアでデスクトップに偽の 4K モニターを追加しましたが、予想よりずっと複雑でした。
https://pfy.ch/programming/4k-sunshine.html
面白いヒント:同じ手順で、通常のモニターやノート PC 画面に保存されている EDID も変更できます。
場合によっては別の I2C アドレスに書き込んで、TCON の各種設定まで変えられます。
Raspberry Pi が必須というわけでもなく、どのコンピューターでも可能です。
CRT のようにブラーのない映像を作るため、LED バックライトをストローブするよう改造していました。
DDC バスがバックライトなどを制御する別のレジスターも公開していることを見つけ、ストローブのために外部回路を接続しました。
フラッシュ ROM を読み書きするレジスターも見えたのでダンプし、8051 ディスアセンブラーを書いておおまかにリバースエンジニアリングし、最終的にストローブモードを含むよう ROM を修正しました。
このモードは輝度調整の低い範囲を占有するようにし、OSD や通常の DDC 輝度制御でオンにして調整できるようにしました。
フラッシュするときは内部を開けて書き込み線を接続する必要がありました。
都合のよいことに vblank 割り込みがあり、LED バックライトを制御するタイマーには、次の割り込み直前に点灯し、調整可能な時間後に消灯できるモードがありました。
LCD の更新が安定した直後にバックライトを点灯するのにちょうどよいタイミングでした。
もともとの目的は数秒間の起動ロゴを消すことだけで、それは成功しました。
省略しているのは低価格製品くらいだと思います。
保護がないと、読み取り中の電圧グリッチが書き込みに化けてフラッシュを壊す可能性があるため危険です。
「PC でこのコマンドを試すと、EDID ではないハードウェア、たとえば RAM モジュールの SPD EEPROM を誤ってフラッシュしてしまう可能性があります」
普通は事前にプログラム済みの EEPROM を買って基板に実装し、書き込み有効ピンが絶対に high にならないよう配線するはずです。
モニターのような製品に EEPROM を入れておき、書き込み可能なまま残しておくのは変ですが、市販ハードウェアではもっと奇妙なものも見たことがあります。
混乱しています。
プラグを GPIO の I2C ピンに接続する様子を期待していましたが、単に RPi に挿すだけで十分に見えます。
だとすると、HDMI が I2C インターフェイスを直接公開しているのか気になります。
記事で触れられているように、RPi にはその HDMI ポートのピンに接続された I2C コントローラーがあります。DDC 経由で EDID を読む必要があるためです。
KVM と Linux の問題を解決できる安価な DisplayPort EDID エミュレーターを知っている人がいるのか気になる
最後に確認したときは HDMI よりはるかに高価で、むしろ新しい KVM を買ったほうがよいほどだった
代わりに、はるかに扱いが複雑な DisplayPort 専用の高速 AUX バスを使用する
VESA に加入して NDA に大量に署名しない限り、まともなドキュメントすら見つけるのは難しそう
https://foosel.net/til/how-to-override-the-edid-data-of-a-mo...
ただし、仮想モニターを追加したい場合に https://askubuntu.com/questions/453109/add-fake-display-when... が動作するかはよく分からない
ダミープラグを デバイス・フィンガープリント追跡を変える目的にも使えるのか気になる