映像伝送遅延をきっちり測定する

# 1. 目的
- 映像伝送を行う環境を構築し、その環境での遅延を測定することがある。（例：「[【初心者】AWS Elemental MediaConnect を使ってみる](https://qiita.com/mksamba/items/ce6f1fc7391f90397ec7)」にて、AWS MediaConnectでの映像伝送遅延を測定）
- 秒レベルの遅延であれば目視でも確認可能だが、遅延が小さい（ミリ秒レベル）場合、測定が難しいという課題があった。
- なるべく正確に遅延を測定するための方法を確認する。

# 2. やったこと
- 映像をスマホ内蔵のカメラで撮影し、そのままHDMIで外部モニタに出力する。※スマホで通信はしておらず、ただビデオカメラとして使っているだけ。
- 現実の映像がスマホを経由して外部モニタに映るまでの遅延時間を測定する。今回は以下の2つの方法で測定する。
    - スマホで時計（ミリ秒更新）を撮影し、外部モニタに出力。映像ソースと伝送後の映像（外部モニタ）を一枚の写真として撮影し、時刻のずれを確認する。
    - 点滅する光源を撮影し、外部モニタに出力。元映像と伝送後の映像（外部モニタ）の点滅のタイミングのずれを、専用の装置（オシロスコープベース）で測定する。
 
# 3. 構成図

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/aa5693a9-4f7c-37e2-c62b-d862b1238fd5.png)

# 4. 測定方法
## 4.1 時計撮影による測定
### 時計の準備
- JavaScriptで動く時計をPCで表示する。WEB上にいろいろサンプルコードがあるが、今回は、「[CSSとJavaScriptでおしゃれなデジタル時計を実装する方法](https://web-dev.tech/front-end/javascript/digital-clock/)」を使用させて頂く。
- 以下を修正している。※コード(clock.js)はオリジナルからの変更点を抜粋して記載。
    - ミリ秒の表示（オリジナルは秒までの表示）
    - ミリ秒の表示の桁数揃え（例: 17:31:19:009ミリ秒の時、「17:31:19:9」ではなく、「17:31:19:009」と表示されるようにする）
    - 1ミリ秒間隔での表示更新（オリジナルは1秒間隔）

``` clock.js
const clock = () => {
  // msecの値を追加
  let msec = d.getMilliseconds();

  //msecの表示桁数を3桁に揃える
  if(msec < 10)
    {msec = "00" + msec;}
  else if (msec < 100)
    {msec = "0" + msec;}

  // 日付・時刻の文字列を作成（ミリ秒の表示追加）
  let time = `${hour}:${min}:${sec}:${msec}`;
};

// 1ミリ秒ごとにclock関数を呼び出す
setInterval(clock, 1);
```
### 測定方法・結果

- ノートPCのモニタでJavaScriptの時計を表示し、それを手前のスマホで撮影する。スマホの画面を、HDMI(USB Type-Cアダプタ経由)で奥の外部モニタへ出力する。
- 以下の図の場合、映像ソースでは 14:36:06.955、伝送後の映像は14:36:06:782であり、スマホを経由することで955-782=173ms程度の遅延が発生している。

![hikari01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/56befda7-2596-bc59-9588-cc75679da2b7.png)

## 4.2 専用装置（オシロスコープベース）による測定

### 既存手順（時計撮影）の課題
- 時計を写真に撮る上記方法の場合、ワンショットでおおよその遅延値を確認する分には問題ないが、数字がブレてしまい判別しづらかったり、「1秒ごとに100回測定してその最小/平均/最大を取りたい」などの詳細なデータ取得が困難だったり、という課題があった。
- 今回は、初心者でも簡単に映像遅延を測定可能な、オシロスコープベースの専用装置である、光パスコミュニケーション社「DPN2011B」を使用し、より正確な遅延時間の測定を実施する。

### 機材紹介
- 今回使用する「DPN2011B」の大まかな使用方法は以下の通り。
    - 本装置付属の点滅光源(LED)をカメラで撮影する。（光源の点滅タイミングは本装置により制御される。）
    - カメラで撮影した映像を伝送し、モニタに表示する。
    - モニタに表示されている伝送後の光源の情報を、本装置付属のフォトダイオードを通じて、本装置に入力する。
    - 本装置にて、光源の点滅タイミングと、伝送後の光源の点滅タイミングのずれを内蔵のオシロスコープで測定する。
    - 例えば1秒間隔に10回光源を点滅させ、ずれの値の最小/平均/最大を測定、表示することが可能。

- 遅延測定の原理に関する解説や、本製品の詳細仕様については製品開発元（光パスコミュニケーション社）の以下サイトを参照のこと。
    - 「[2. 遅延時間を測るには](https://h-path.co.jp/technologies/2-how-to-measure-latency/)」：そもそも映像伝送遅延を測るにはどうすればよいか？の原理が解説されている。
    - 「[7. 遅延時間測定ユニット](https://h-path.co.jp/service_product/7-latency-measurement-unit-dpn2011a/)」：本製品の詳細仕様解説。

### 測定方法・結果

- スマホで映した映像が外部モニタに表示されるまでの遅延を以下のように測定する。
    - 本装置に付属する点滅光源(LED)をスマホのカメラで撮影する。
    - スマホからHDMI(USB Type-Cアダプタ経由)で外部モニタへ画面を出力する。外部モニタには光源の点滅が少しだけ遅れて表示される。
    - 本装置に付属するフォトダイオードを、外部モニタ上の、光源が点滅している位置にセットする。（写真は該当の位置にセットする前の状態）
    - 本装置に付属する測定アプリにて、準備作業（プリスキャン）を行う。（フォトダイオードから入力される光の強さの値を測定し、「点灯」／「消灯」と判断すべき光の強さを決定する）
    - 回数を定めて遅延測定を行う。結果は測定アプリ上に表示され、データでのエクスポートも可能。

![hikari02.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/72002155-c051-8710-b873-05bbde0876f2.jpeg)

- 10回測定した結果が以下（測定アプリでの結果表示）。

![20220318-xperia10-hdmi出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/ae0eaf35-b600-cdd6-9d56-734329a5290d.png)

- 測定結果の代表値としては123ms(ピンクの背景の値)を採用することとした。
    - LED OFF->ON(消灯->点灯時の遅延) と、LED ON->OFF(点灯->消灯時の遅延) では、前者のほうがユースケースとしてイメージしやすいと判断。
    - 仮に消灯時の光の強さを0、点灯時を100とした時、何%まで光の強さが変化したら点灯とみなすかについては、少しでも光が来ていれば点灯とみなすという観点から、20%の値を採用。
    - 最小、平均、最大の値が出ているが、平均値を採用。
    - 上記より、測定方法の説明をする際は、「光の点滅の伝送遅延をオシロスコープで測定する。10回測定した平均値とする。消灯時の光の強さを0、点灯時の光の強さを100とした場合、元の光源が点灯した時から、伝送後の映像内の光源の光の強さが20に増加する時までの間を伝送遅延時間とする。」のようになる。



# 5. 所感
- 基本的には、遅延が大きい（秒単位以上）の場合や、大まかな値を取ればよい場合は時計撮影、ミリ秒単位の遅延を厳密に測定したい場合は専用装置、のように使い分けたいが、専用装置についても「ピカピカ点滅装置で測定しよう」という感じで、さまざまな環境での測定を行い、ノウハウを蓄積していきたい。
- 映像伝送の遅延値は、どの区間をどのように測定したのかによって値の意味も変わってくるため、測定を行う際には方法、条件についても併せて明確に定義し、記録しておくようにしたい。
- 余談として、構成図にいらすとやのイラストを使わせて頂いたが、オシロスコープのイラストが存在しており、マニアックなものまであるなと感心。