これは何
CMAFを利用すると低遅延のストリーミング配信を実現できるといいますが、その理由をHTTP/1.1の転送の仕組みと合わせて記述してみます。
HLSやMPEG-DASHの配信
HLSやMPEG-DASHでは、まず最初に動画の断片ファイル(セグメント)の一覧が書かれたマニフェストファイルをダウンロードします。マニフェストファイルには、「ストリーミングしたい動画のx秒目からy秒目までのn秒間のファイルの名前はこれです。」という情報が書かれています。リアルタイムに配信される場合は、マニフェストファイルがリアルタイムに更新されていきます。プレイヤーは、再生したい時刻に合致した断片ファイルをダウンロードして再生します。
この時の再生遅延は、おおむねセグメントに含まれる動画断片の再生時間が少なくともかかります。また途切れなく再生させる為には、通常複数のセグメントを先読みしておきます。なので、カメラから出力された映像が視聴者の元で再生されるまでには一般的に数十秒の遅延が発生することになります。
この遅延を短くするためには動画セグメントに含まれる動画の再生時間を短くすることが考えられますが、動画セグメントのダウンロードをするたびにリクエスト/レスポンスのオーバーヘッドがかかるので、分割数が多くなるにつれてオーバーヘッドが増えていきます。
CMAF
CMAFは別に低遅延伝送だけが取り柄ではないのですが、今回はそこだけにスポットを当てます。
CMAFでは、動画セグメントをさらにチャンクと呼ばれる単位に分割します。動画セグメントはその再生時間に縛られていましたが、チャンクは任意の長さにできます。そしてそれぞれのチャンクをHTTPで転送する時に、chunked形式で伝送を行うというのがキモになります。これにより、セグメント全てを受信しきらないと動画プレイヤーに渡せなかったのを、チャンクを受信したら動画プレイヤーは即座にそれを再生させるように努めます。
Transfer-Encoding: chunked
さて、上記の記述の中に、chunked形式という言葉が出てきました。これはHTTP/1.1の通信方式の話なので、一旦HTTP/1.1の通信方式に話を移します。
HTTP/1.1ではKeep-Aliveといって、1つのファイルの転送が終わってから同じTCPセッションを使って別のファイルのリクエストを行う機能があります。これにより、ファイルを転送するたびにTCPセッションの確立を行う必要がなくなります。TCPセッションの確立はそこそこ時間や転送量がかかるので、そこが節約できるというわけです。
1つのファイルを1つのTCPセッションで転送するときは、ファイルの転送が終わったら一方的にTCPセッションを切断するという方法で転送の終了を示すことができました。しかし複数のファイルを転送する場合にはそういうわけにはいきません。なので、Content-Length
リクエストヘッダーによって転送するファイルのサイズを予め明示することが必要になります。
とはいえライブストリーミングしている動画のように、予めファイルサイズが分からないような物を転送したいというケースもあります。そういう場合に使うのが、Transfer-Encoding: chunked
です。これは転送したいファイルを一度に送るという通常のHTTPでのファイルの伝送方法とは異なり、細切れにして少しずつ送っていくという伝送方法です。これによりHTTPサーバーは「とりあえず1kBだけ送信する」ということが可能になります。
Transfer-Encoding: chunked
とCMAF
chunked方式でのデータ転送を映像配信に応用できると、デコーダが対応していれば一旦途中まで受信したところまででデコーダにチャンクを渡してデコード処理を開始できるようになります。何秒間か分の動画セグメントの受信を完了するまで待つ必要がなく、届いたデータを即座にデコーダに渡すことが出来ます。HTTPのプロトコルの枠組みから離れる必要もありません。
これにより、動画セグメントが起因で発生する再生遅延を短くすることができるようになるのです。もちろん映像データを受信するクライアント側で、非同期で受信した映像データを、映像を再生している傍からプレイヤーに渡せるようにするといった対応は必須です。
HTTP/1.1 only
実は、Transfer-Encoding: chunked
はHTTP/1.1にしかありません。HTTP/2はそもそもデータの転送方式がフレーム単位になっていますし、DATAフレームを立て続けに送ることで同様のことを実現できます。しかしながらCMAFがHTTP/2にマッピングされる話は寡聞にして知りません。HTTP/2のHTTP/1.1と比べた時の利点は、
- Webサイトの表示のように小さなファイルを数多くダウンロードしようとする時に、multiplexingによってhead-of-line blockingを起こさない。
- TCPセッションのestablishmentのオーバーヘッドが減る。
なので、動画のストリーミングのように長時間・大容量のデータを転送する場合には、あまりHTTP/2を使うこと自体がメリットがありません。もちろんHTTP/2で転送できないわけではないのでしょうが、特にメリットがあるわけでも無いので今後も特に積極的にHTTP/2でどうこうしようということは起きないのかもしれません。