前回はHDMI出力側でしたが今回は入力側を試してみました.
今回もexStickGEと弊社のIPコアe7UDP/IPを使用してUDP/IP経由でHDMI映像の一瞬を切り取り表示します.
ソースコードはここの「exStickGE_hdmi2dram2udp」にアップしてあります.
動かしてみた
受信用ソフトウェアはNode.jsとElectronで書かれているのでGUIで操作できます.
適切なIPアドレスとポートであれば「Start」を押すことで受信を開始します.
少々時間がかかりますがこのようにPCから出力されているHDMI映像を画像として取り出すことが出来ます.
実装
今回のおおまかな構成はこのようになっています.
PCの映像出力をexStickGEで取り込み,UDP/IP経由で転送します.
FPGAの内部構成は以下のとおりです.映像信号をRGBデータに変換し,DRAMへ格納します.受信ソフトウェア側から要求があればDRAMの内容を読み出します.
FPGA
FPGAでは映像を変換してDRAMに格納します.映像を格納するのはUDP/IPパケットで書き込みリクエストが来たときだけにします.1枚の画像を転送するのに時間がかかるため転送中に新しく書き込まれると映像が乱れてしまうためです.受信ソフトウェアから読み出すときは1パケットにつき64ピクセル分(4バイト1ピクセル)のデータを転送します.
受信ソフトウェア
受信ソフトウェアでは受信開始時にキャプチャ要求パケットを送信します.中身としては単純な1です.そうすることでFPGA側で映像を画像としてキャプチャされます.その後データ読み出し要求を行い,描画していきます.読み出し要求のパケットは1ワード目,上位31ビットがアドレス,下位1ビットが0(リード要求),2ワード目はリードサイズ-1です.前回の画像を転送するための要求と逆のことを行っている形です.
以下の画像の場合,最初のパケットがキャプチャ要求,2パケット目がアドレス0,64ワード分読み出しするという意味です.3パケット目はその応答であり,あとは繰り返しになります.
映像受信とEDID
送信する側の機器は自身と受信する機器が対応している解像度で出力をしなければ適切に映像を転送することが出来ません.基本的に送信から受信への単方向であるため,何かしら伝える手段が必要になります.
そこでI2Cを使用してEDIDとよばれる対応状況をまとめたデータをやり取りして適切な解像度やリフレッシュレートで送信します.逆にその情報がない場合は送信側はどの解像度で送ればいいかわからないため,データが送られてきません.
ビルドと動作確認
ソースコードから実際にビルドして動作するまでの確認方法について紹介します.
環境はVivado 2019.1, Node.js v12.16.1で行いました.
まずはgithub.comからソースコードをクローンしてきます.
FPGA
弊社のe7UDP/IP IPコアのedifをクローンしたディレクトリ内のedif内にコピーします.
次に「Vivado 2019.1 Tcl Shell」を起動し, クローンしたディレクトリへ移動しプロジェクトの合成を行います.
cd ~/exstickge_samples/exStickGE_hdmi2dram2udp vivado -mode batch -source create_project.tcl
このプロジェクトも環境にもよりますが数十分もあれば終わるのではないでしょうか.
FPGAにbitファイルを書き込めばFPGA側の準備は終了です.
受信ソフトウェア
まずNICの設定を以下の通り変更します
- IPアドレス 10.0.0.1
- ネットマスク 255.0.0.0
その後クローンしたディレクトリに移動後
cd ~/exstickge_samples/exStickGE_hdmi2dram2udp/tool/ npm install npm install electron -g
インストールが出来たら以下のコマンドで受信ソフトウェアが起動します.
electron src
動作確認が終わったらNICの設定をもとに戻しておきましょう.
コメント