第77話のlive cameraの前で、イトはもう一度手をたたいた。
現実の手が合わさる。
遠くのscreenでも、videoとaudioはぴたりと合っている。
けれどscreenの拍手は、420 msあとだった。
audio / video offset 0 ms
end-to-end latency 420 ms
viewer stalls 0
二本のtrackのtime mappingは直っている。
今度は、そろった二本がまとめて遅い。
イトはviewer側のbuffer dialへ手を伸ばした。
「待っている箱を0にすれば、もっと今に近づける」
次のrehearsalのacceptance lineは、end-to-end 320 ms以下、stall 0、audio / video offset 0。
同じarrival jitter traceを流し、三つを同時に満たさなければhandoffできない。
bufferを0にすると、画面が四回止まった
ユイは、viewer buffer 0の試作を一件だけ再生した。
screenの拍手は420 msから360 msへ近づいた。
しかしnetworkから届く間隔が揺れたところで、frameが足りなくなる。
六秒のtest中に、画面は四回止まった。
viewer buffer target 0 ms
end-to-end latency 360 ms
viewer stalls 4
acceptance FAIL
速く始めても、次のdataがpresentation時刻までにそろわなければ滑らかには続かない。
イト
待ち時間を全部なくすと、届く間隔の揺れを受け止める場所までなくなるんだ
ユイ
遅延を一つの箱だけのせいにせず、captureからscreenまで分けて測りましょう
マコト
残す待ちと、縮められる待ちを見分けるんだね
Picoはbuffer dialにもpipeline gateにも触れない。
cameraとscreenの間へ、五つのcyan markerを置いただけだった。
三つの直し方
A:viewer bufferを0にする
意図的な待ちは一つ減る。
けれど今回のjitter traceではstallが増え、320 msのlineにも届かなかった。
B:resolutionとbitrateを先に下げる
encode処理やupload容量がbottleneckなら、有効な場合がある。
しかし今回の測定前に画質を落としても、どのstageが180 ms待っているかは分からない。
C:同じunitへstage timestampを付け、largest controllable waitを一つ縮める
captureからviewer presentationまでを分ける。
合計だけでなく、各stageの差を見てから一か所だけ変え、同じjitter traceで再試験する。
イトはbuffer 0試作を閉じた。
resolution presetも元へ戻す。
「C。全部を急がせず、いちばん長く止めている場所から直す」
live latencyは、途中で使った時間の合計
この話でいうend-to-end latencyは、cameraが一件をcaptureしてからviewer screenへpresentするまでの時間だ。
イトは、同じclap unitが各markerを通った時刻を並べた。
capture 0 ms
encode ready +90 ms
chunk release +180 ms
server / network arrival +70 ms
viewer jitter buffer +60 ms
decode / render +20 ms
total 420 ms
+90 +180 +70 +60 +20 = 420。
「回線が遅い」でまとめると、encodeやchunk holdやviewer準備の時間が見えなくなる。
反対に、server / network 70 msだけを0にしても、残り350 msは消えない。
この数値は六秒のclosed lab fixtureであり、すべての配信へ共通する内訳ではない。
protocol、codec、端末、回線、配信設定、混雑でstageも値も変わる。
jitterとbufferは、遅延と同じ言葉ではない
latencyは、captureからpresentationまでどれくらい離れたか。
jitterは、dataが届く間隔の揺れ。
viewer bufferは、届いたdataを少し持ち、揺れがあってもpresentationを続けやすくする待機場所だ。
W3C WebRTC Statistics APIには、sampleやframeがjitter bufferへ入ってから出るまでを積算するjitterBufferDelay、target delay、freezeなどの観測項目がある。
Media Source Extensionsのbuffer modelでも、再生位置に必要なdataが足りなければplayback interruptionにつながる。
bufferを大きくすれば必ず正解でも、0なら必ず最速の成功でもない。
今回必要なのは、同じjitter traceを止めずに通せる範囲を残すことだ。
180 msのholdだけが長かった
五つの差のうち、最長はchunk release前の180 msだった。
encoderは90 msでunitを作り終えている。
それなのにpackaging gateが、次のまとまりを待って180 ms保持していた。
イトはsource video / audio、codec、resolution、bitrateを固定した。
viewer jitter buffer 60 msも外さない。
自分の両手で、center queueのhold gateだけを180 ms notchから60 ms notchへ移す。

changed stage chunk hold
before 180 ms
after 60 ms
viewer buffer 60 ms kept
source media changes 0
small chunkを早くreleaseすれば、送る回数やheader overheadなど別のtrade-offが増える場合もある。
だから60 msを全配信の正解にはしない。
このfixtureで一か所を変え、結果を測る。
一本のstreamを、途中で分けて届ける
encodeされたblue videoとamber audioは、一つのpaired unitとしてserverへ進んだ。
配信者がviewer一台ずつへ同じdataを直接作り直さなくても、serverやdelivery拠点から複数のviewerへ分けて届けられる構成がある。
server、CDN、edgeなどの名前だけを覚えても、delay budgetは決まらない。
どの地点で受け取り、どこで待ち、いつviewerへ渡したかを同じunitで追う。
420 msが300 msになり、四回の停止も消えた
イトはbuffer 0試作で使ったarrival jitter traceを、そのまま再注入した。
arrival variation 12 ms, 47 ms, 55 ms, 18 ms
viewer buffer 60 ms
frameはpresentation前にそろい、六秒のscreenは一度も止まらない。
audio / video offsetも0 msのままだ。
end-to-end latency 300 ms
viewer stalls 0
audio / video offset 0 ms
dropped test units 0
acceptance PASS
90 + 60 + 70 + 60 + 20 = 300。
イトは同じclapを三回流し、各stage markerとviewer resultを自分で照合した。
そこで初めて、live routeのhandoffを許可する。
viewer bufferは消えていない。
不要に長かったholdだけが、120 ms短くなった。
速くする前に、どこで待ったかを見る
今回の最初の一手は、bufferを0にすることではない。
1. captureとviewer presentationへ同じunitのmarkerを置く
2. stageごとの差とtotalを出す
3. largest controllable waitを一つ選ぶ
4. source条件を固定して一か所だけ変える
5. 同じjitter traceでlatency / stall / syncを再確認する
もし最大がencodeなら、codec設定や処理能力を調べる。
uploadが詰まっているなら、bitrateや回線条件が先になることもある。
offsetやstallが試行ごとに変わるなら、一回の最小値だけで完了にしない。
短い数字ではなく、同じ条件で続けて届くかを見る。
viewerからの光だけが、別の道を戻った
live screenは、audioとvideoをそろえたまま300 msで届いた。
遠くのviewerが、screenの横にあるcyan buttonを押す。
その反応の光は、video packageの枝を逆向きに戻らなかった。
細い別のrailへ入り、配信者側のlampを点けた。
viewerへ送るone-way streamと、viewerから返すsignalは同じ荷物ではない。
イトはcameraからscreenへ進む太いrailと、screenから戻る細いrailを見比べた。
bufferを全部外さず待ち場所を測ったから、今度は「戻り道」を送り道の遅さへ混ぜずに済んだ。
「見るだけの道に、返事の道を足すと何が変わるの?」
次回、ピコルート第79話。
リアルタイム通信は、どうやって往復する?

