NMOSの動きを追っかけてみた① 検知・登録編(IS-04)

以前のBLOGでNMOSサーバーの構築[NMOSサーバの構築と機器の制御]を行いましたが、今回はもう少しNMOSの動きについて調査してみました。

今回は今まで自分たちでも曖昧な理解をしていたNMOSの動きについて、一つずつ追っかけてみることにしました。
規格を読むことも必要ですが、 "百聞は一見に如かず" 動きを追っかけるほうが理解が早いのでは?と考えて、動きをみてみることにしました。
このブログを読んでいただいたら、なんとなくNMOSの動きが理解できた"気が"します!?。

[NMOSの動きを追っかけてみた② 制御編(IS-05)はこちら]

準備

まずNMOSを動作を追っかけて確認するうえで準備したことです。

  • Wireshark : 実際にNMOSに関するパケットの中身を確認するのに使いました。
  • NMOS Explorer(Riedel) : 自分のPCにNMOS Explorerをいれて、NODE(IP機器)との通信をWiresharkでキャプチャして確認しました。
  • IP機器 : IPゲートウェイ(AJA IPT-10G2-SDI,IPR-10G2-SDI)・GrandMaster(telestream SPG9000)・波形モニタ(telestream PRISM) NMOS制御できる機器で動きを確認しました。

自分のPCにWiresharkとNMOS Explorerをいれて、IP機器と制御ネットワークで接続させます。
これで準備は完了。パケットを確認していきます。

このあと記事中によくでてくる単語
registry : NMOSのレジストリーサーバのことですが、今回は自分のPCがそれにあたります。
NODE : IP機器のこと

機器を検知する

まずは検知のフローから。
正直に言うと実はまだ一部検知のフローについて正確には理解できていません。今回は理解できている部分の流れのみとなります。

まずmDNS(マルチキャストDNS)によって、マルチキャストで各機器がネットワークにパケットを流します。

mDNS
マルチキャストアドレス:224.0.0.251
ソースIPアドレス:mDNSを出力するデバイスのIP
port:UDP5353

nmos explorerを立ち上げるとそのPCからmDNSとして以下のクエリーがでます。

_nmos-node._tcp.local: type PTR, class IN, "QM" question
nmos-cpp_node_xxxxxx._nmos-node._tcp.local: type SRV, class IN, "QM" question

1行目でnmos-nodeのサービス提供している機器は応答してくださいと問いをローカルネットワークに流し、2行目でnmos-cpp_node_xxxxxx._nmos-node._tcp.localというサービスを提供している機器のホスト名やポート番号をおしえてくださいという問いをローカルネットワークに流しています。

するとこれに対してnmos-cpp_node_xxxxxx._nmos-node._tcp.localのサービスを提供している機器がレスポンスします。

nmos-cpp_node_xxxxxx._nmos-node._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 80, target spg9000-s010972.local
spg9000-s010972.local: type A, class IN, cache flush, addr [NODE機器のIP]

これでそのサービスを提供しているNODEのホスト名、IPと受付ポートが80だということがわかり、ここから登録の作業に入ります。

機器の登録

機器の登録には以下の6つの登録作業が行われます。

  • 機器自体のNODEの情報(self)
  • 機器に実装されているデバイスの情報(devices)
  • 機器に実装されているIPストリームを出力するsenderの情報(senders)
  • 機器に実装されているIPストリームを受信するreceiverの情報(receivers)
  • senderが流すストリームの情報(flows)
  • flowのソースの情報(sources)
    わからないのはflowsとsourcesの違い。
    flowsには映像の解像度や色空間情報、音声のサンプリング周波数などがあり、sourcesには映像のフレームレートや音声のチャンネルの情報があります。
    もう少し勉強が必要みたいです。

これら6つの情報の登録のために、registry(自分のPC)は各ノードに対してHTTPでアクセスします。

参考(AMWA IS-04 NMOS Discovery and Registration Specification: Overview|AMWA)

NODEの情報取得

registryからNODEに対して以下のGETメソッドでアクセスします。

GET /x-nmos/node/v1.3/self/ HTTP/1.1

ここでフォルダ構造はNMOSで規定されているので、どこのフォルダに何があるかということはいちいちNODEからregistryに伝える必要はないみたいです。
するとNODEから

{
  "api": {
    "endpoints": [
      {
        "authorization": false,
        "host": "[NODEのIP]",
        "port": 4003,
        "protocol": "http"
      }
    ],
    "versions": [
      "v1.2",
      "v1.3"
    ]
  },
  "caps": {},
  "clocks": [
    {
      "gmid": "00-90-56-ff-fe-08-81-29",
      "locked": true,
      "name": "clk0",
      "ref_type": "ptp",
      "traceable": true,
      "version": "IEEE1588-2008"
    }
  ],
  "description": "AJA NMOS Node",
  "hostname": "IPT-10G2-SDI-1PT240401",
  "href": "http://[ノードのIP]:4003",
  "id": "a3b4f60e-7441-3682-b55c-8b4282ab18e0",
  "interfaces": [
    {
      "chassis_id": "00-0c-17-4c-64-b5",
      "name": "eth1",
      "port_id": "00-0c-17-4c-64-b5"
    },
    {
      "chassis_id": "00-0c-17-4c-64-b6",
      "name": "eth2",
      "port_id": "00-0c-17-4c-64-b6"
    }
  ],
  "label": "IPT-10G2-SDI-1PT240401-Node",
  "services": [],
  "tags": {},
  "version": "5:345346310"
}

のような情報がかえってきます。
nmos explorer上でみるとNODEに"IPT-10G2-SDI-1PT240401-Node"(label情報)が登録されていました。

デバイス情報の登録

デバイス情報取得は

GET /x-nmos/node/v1.3/devices/ HTTP/1.1

によって取得可能。
NODEからは

[
  {
    "controls": [
      {
        "authorization": false,
        "href": "http://[NODEのIP]:4003/x-nmos/connection/v1.0/",
        "type": "urn:x-nmos:control:sr-ctrl/v1.0"
      },
      {
        "authorization": false,
        "href": "http://[NODEのIP]:4003/x-nmos/connection/v1.1/",
        "type": "urn:x-nmos:control:sr-ctrl/v1.1"
      }
    ],
    "description": "IPT 10G2 SDI Converter",
    "flows": [
      "8abdcf1d-1f92-3693-9c17-cf689ba55715",
      "e24ab533-c4d9-33c6-98a2-fa0ad88605e8"
    ],
    "id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "label": "IPT-10G2-SDI-1PT240401-Device1",
    "node_id": "a3b4f60e-7441-3682-b55c-8b4282ab18e0",
    "receivers": [],
    "senders": [
      "f5524e1c-32af-3ad1-a313-b850412e4713",
      "1be5ffd1-25eb-30f2-8f4e-ea11b9452d59"
    ],
    "sources": [
      "0e81a186-e643-38e1-8eb1-4a407cbc59d9",
      "7e8f6ff9-4c21-3190-906c-6d8eb8194f15"
    ],
    "tags": {},
    "type": "urn:x-nmos:device:pipeline",
    "version": "5:345424645"
  }
]

このようなjsonが返ってきました。
まず一つのNODEで複数のdevice情報を持つことが想定されていますね。
またflowsが二つありますが、これは後程でてきますが、映像と音声のストリームを表しています。
この機器はストリームを出力するだけなので、sendersのみでreceivesがないことがわかります。

senders情報の取得

sendersの情報は

GET /x-nmos/node/v1.3/senders/ HTTP/1.1

で取得します。
すると以下のようなjsonが出力されます。

[
  {
    "description": "Video Sender",
    "device_id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "flow_id": "8abdcf1d-1f92-3693-9c17-cf689ba55715",
    "id": "f5524e1c-32af-3ad1-a313-b850412e4713",
    "interface_bindings": [
      "eth1",
      "eth2"
    ],
    "label": "IPT-10G2-SDI-1PT240401-TxVideo1",
    "manifest_href": "http://[NODEのIP]:4003/sdp/f5524e1c-32af-3ad1-a313-b850412e4713",
    "subscription": {
      "active": false,
      "receiver_id": null
    },
    "tags": {},
    "transport": "urn:x-nmos:transport:rtp.mcast",
    "version": "1757644887:991787270"
  },
  {
    "description": "Audio Sender",
    "device_id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "flow_id": "e24ab533-c4d9-33c6-98a2-fa0ad88605e8",
    "id": "1be5ffd1-25eb-30f2-8f4e-ea11b9452d59",
    "interface_bindings": [
      "eth1",
      "eth2"
    ],
    "label": "IPT-10G2-SDI-1PT240401-TxAudio1",
    "manifest_href": "http://[NODEのIP]:4003/sdp/1be5ffd1-25eb-30f2-8f4e-ea11b9452d59",
    "subscription": {
      "active": false,
      "receiver_id": null
    },
    "tags": {},
    "transport": "urn:x-nmos:transport:rtp.mcast",
    "version": "1757644887:992005895"
  }
]

ここからはsenderとして映像と音声があるのがわかります。
またそれぞれのSDP(Session Description Protocol)ファイルのある場所も指定されています。

recievers情報の取得

同様に

GET /x-nmos/node/v1.3/receivers/ HTTP/1.1

receivers(ストリームの受信側)の情報もこれで取得できます。
今回は映像をだすNODEなため、この情報は何も取得できませんでした。

flows情報の取得

flows情報の取得は

GET /x-nmos/node/v1.3/flows/ HTTP/1.1

取得した結果はjsonで

[
  {
    "colorspace": "BT709",
    "components": [
      {
        "bit_depth": 10,
        "height": 2160,
        "name": "Y",
        "width": 1920
      },
      {
        "bit_depth": 10,
        "height": 2160,
        "name": "Cb",
        "width": 960
      },
      {
        "bit_depth": 10,
        "height": 2160,
        "name": "Cr",
        "width": 960
      }
    ],
    "description": "Video Flow",
    "device_id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "format": "urn:x-nmos:format:video",
    "frame_height": 2160,
    "frame_width": 1920,
    "id": "8abdcf1d-1f92-3693-9c17-cf689ba55715",
    "interlace_mode": "interlaced_tff",
    "label": "IPT-10G2-SDI-1PT240401-Flow-Video1",
    "media_type": "video/raw",
    "parents": [],
    "source_id": "0e81a186-e643-38e1-8eb1-4a407cbc59d9",
    "tags": {},
    "version": "1757644887:991655175"
  },
  {
    "bit_depth": 24,
    "description": "Audio Flow",
    "device_id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "format": "urn:x-nmos:format:audio",
    "id": "e24ab533-c4d9-33c6-98a2-fa0ad88605e8",
    "label": "IPT-10G2-SDI-1PT240401-Flow-Audio1",
    "media_type": "audio/L24",
    "parents": [],
    "sample_rate": {
      "numerator": 48000
    },
    "source_id": "7e8f6ff9-4c21-3190-906c-6d8eb8194f15",
    "tags": {},
    "version": "1757644887:991883015"
  }
]

とかえってきました。
映像のflowsには"BT709"という色空間の情報と映像の解像度の情報垂直2160 水平1920というのがわかります。
ここで垂直方向2160というのがなかなかおもしろい発見ですね。
もちろんこれはHDの1920x1080の映像を表しています。どうもそういうものみたいです。
あとは映像がY/Cb/Cr 4:4:4なのか4:2:2なのかといった情報もここでわかります。
音声のflowにはリニアPCMの24bitでサンプリングレート48khzというのがわかります。

sources情報の取得

sources情報は

GET /x-nmos/node/v1.3/sources/ HTTP/1.1

で取得します。以下のようなjsonが返答されます。

[
  {
    "caps": {},
    "clock_name": "clk0",
    "description": "Video Source",
    "device_id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "format": "urn:x-nmos:format:video",
    "grain_rate": {
      "denominator": 1001,
      "numerator": 30000
    },
    "id": "0e81a186-e643-38e1-8eb1-4a407cbc59d9",
    "label": "IPT-10G2-SDI-1PT240401-Src-Video1",
    "parents": [],
    "tags": {},
    "version": "1757644887:991586055"
  },
  {
    "caps": {},
    "channels": [
      {
        "label": "Left audio source channel",
        "symbol": "L"
      },
      {
        "label": "Right audio source channel",
        "symbol": "R"
      },
      【中略】
    ],
    "clock_name": "clk0",
    "description": "Audio Source",
    "device_id": "38bcfb66-cecb-3de3-b728-777c385ae13e",
    "format": "urn:x-nmos:format:audio",
    "id": "7e8f6ff9-4c21-3190-906c-6d8eb8194f15",
    "label": "IPT-10G2-SDI-1PT240401-Src-Audio1",
    "parents": [],
    "tags": {},
    "version": "1757644887:991834885"
  }
]

映像のフレームレート29.97とか音声のチャンネル情報などはここにのるんですね。
なぜflowsにまとめないのかはよくわかりませんでした。何か理由があるのでしょう。

機器の死活監視

ここも正解が難しい。
規格を読む限り、NODEからregistryに対してHTTPでアクセスして死活監視するとあるように読めるのですが、NMOS explorerの動きは違いました。

定期的にregistryから

nmos-cpp_node_xxxxxx._nmos-node._tcp.local: type SRV, class IN, "QM" question

のようなクエリーをmDNSとして投げて、それに対してNODEが応答

nmos-cpp_node_xxxxxx._nmos-node._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 80, target spg9000-s010972.local
spg9000-s010972.local: type A, class IN, cache flush, addr [NODEのIP]

のような返答をまっているようです。
この返答が返ってこないと、数秒間隔で複数回同じクエリーをリトライして、失敗が続くとNODEがいなくなったと判断しているようです。

とりあえずIP機器をmDNSで検知する仕組みはわかった

とりあえず検知の仕組みはなんとなくこれでわかりました。
やはりパケットをキャプチャして中身をおっかけてみるのは理解しやすいですね。
次回は実際に制御を行うIS-05の挙動を追っかけてみたので、[NMOSの動きを追っかけてみた② 制御編(IS-05)]こちらもよろしくお願いします。

Next Post Previous Post