次にやることとしてPeerCastの動画パケット部分をUDPにできないか検討してる。 出来るかできないかで言えば当然できるんだけど、なんか大きな問題が無いかなぁという辺りを主に。
UDPってそんなに使ったことがないのでちゃんと調べてたんだけど、輻輳制御がないので自前でやらんとまずいよ的な話があるらしい。
そもそも輻輳制御ってなんだろう?調べると名前に反して簡単で、ネットワークが混んでそうなときはゆっくり送ろうというだけの話だった。なるほど。
TCPの輻輳制御ってどうなってんのか調べたら実装によるらしいが結構複雑なことやってんのね……。 基本的にはパケロス数カウントかRTTの変動を見るかその両方でウィンドウサイズを増減させてるようだ。
ウィンドウサイズを減らしてもその分パケット増えるから余計だめじゃん!と思ったんだけどTCPだからACKが返ってくるまでは待つんだった。RTT短くならなければウィンドウサイズを減らせば時間当たりの転送量は減るのね。RTTが短くなるならまだ余裕ありそうだからウィンドウサイズ増やしても大丈夫と。 でもUDPだとACKがないので送信側でRTTどころかパケロス検出もできなくて輻輳制御自動化は無理だぞと。なるほど。
輻輳制御はなんとなくわかったので、じゃあPeerCastStationでやるとしたらどうすればいいんだろう。 面倒なのでUDPでパケロスが多いようなら諦めてTCPにして輻輳制御をそっちにお任せしましょう!と思ったんだけど意味あるかこれ?
TCPで輻輳制御しちゃうよ! → 混んでるからゆっくり送るね! → ライブストリーミングなのに実時間で送りきれない!! → 完
だめだなこりゃ。
そもそもライブストリーミングという時点でUDPとかTCPとか関係なく輻輳制御の余地があんまりなさそう。 ライブストリーミングだとだいたい一定ビットレートでデータ生成されて平均して実時間で通信できないと詰まっちゃう。 それ以下にも以上にもなんないよね。一度にあんまり大きいパケット流さない、くらいはできるだろうけど。
混んでたらデータ量を減らせばいいのでビットレート下げればいいよね。でもPeerCastは自分でエンコードしておらず、エンコーダの出力を貰ってきてるだけなのでビットレート下げたりできない!さらに言えばバケツリレーなP2Pなので自分の接続先が大本とは限らず、自分の回線が細いからってもっと低いビットレートでくれと要求しようもないのだ。ぐぬぬ。
それでもやるとしたら、ネットワークが混んでたら別な経路を選択するくらいかなぁ。 といってもパケットが通る経路を選択できるわけもないので、単に別なノードに接続しに行くだけだが。
あともう一個は、もうピアキャス見るのを諦めて働く。これおすすめ。
混んでたら別な経路接続ってのは現在のPeerCastに遠回りながら実装されてんだよな。 PeerCastStationでは遠回りにも入ってなかったと思うが、パケットのSkipが起きたら切断ってのがそれ。
パケットの送信が詰まる(混んでるか何かでパケットが実時間で送りきれない) → 上流から受け取ってきたパケットを貯めとくキューが溢れて古いパケットが消える → 次のパケット送信をしようとしたらいくらか消えてるのでSkip検出 → 詰まってるから切ろう
これがSkipで切断。PeerCastって結構上手いことやってたんですねぇ。細かいところがちょっとアレだけれども。
UDPでやるならどうしたものかな。受信側である程度パケロスなり遅延を検出したら切るってのが一つ考えられる。 PeerCastだと送信側でSkip検出してるのでそれに合わせるとしたら、受信側でパケロス・遅延検出がある程度あったら送信側に通知してやるってのが簡単そう。 結局検出してるのは受信側なので合ってない気もするが、送信側だけじゃどうしても検出できないもんな。
送信側に通知してもらうってのがやっぱりいいかな。切断以外の選択肢も取れる余地は残しておきたいよね。
まとめると
こんなところか。
次はUDP拡張のプロトコル考えないとなー。
Playstation Mobileで開発できる奴の正式版が始まっていたので登録してSDK落としといた。
まだ実機で動かす/販売のための登録はしてないけど、XNAに引き続き毎年無駄にお金を吸いとられる日々が始まるお。 XNAの方はもう解約してもいいんじゃねぇかという気がするが。Windows Phoneアプリなんて当然作ってないし。
SDKの正式版を見たけどネットワーク機能やっぱりないわーとがっくりしてた。友人にHTTP通信くらいできなかったっけ?と言われてたけどドキュメント見ても描画とサウンドと入力と課金ぐらいしかクラスないじゃん!!でもガイドラインにはネットワーク使った時はこうしましょう的なのが書かれてて一体どういうことなんだ。
散々悩んでいたが、よく見たら標準ライブラリとしてmscorlibとかSystem.dllとか使えますんで、とさらっと書いてあった。そうか。そういやMonoだったんだ。すっかり忘れてた!!
XNAみたいにすごく制限されてるものだとすっかり思い込んでいたので、.NETというかMonoに含まれるクラスを忘れてしまっていた。中身見たら.NET 3.5レベルのコアなクラスはほとんど揃ってるな。HTTPどころかSocketそのままあるよこれ。ほんとに使えるんだろうか。特にTcpListenerとか。
System.Reflection.Emitなんかもちゃんとあった。これ動くならDLR、ひいてはIronRubyも動いちゃうんだが、本当に動くなら夢広がるなぁ。
ごく普通にMonoなのでSilverlightとかXNAみたいに専用のアセンブリ(またはPCL)使わなくてもMonoで動くアセンブリならそのままコピってきて動くんだろう。もちろんP/Invokeとか使ってない限りにおいて。これって素敵なことで、UIさえ作ってあげればロジック部分はリビルドすら必要なくPC版のをそのまま使えちゃうってことですよね。Mono for Androidとかピンと来てなかったけど、なるほどこれはすごい。
実機で動かすには年8000円が必要だけど、Mono for Androidって3万円以上するからそれを考えると悪くない値段ではあるなぁ。厳しい機種制限付きながらもAndroidでも動くんでしょ?Xperia Tabletとか欲しいね。買わないけど。
専用のUIビルダもついてるので、.NET 3.5くらいで作ってたゲームでないアプリを移植したいおっていうのもやりやすいかも。もちろんロジックがUIと切り離せる作りをしてる場合なので、適当に作ったものが移植しやすいとは限らんが。
たぶんPeerCastStationはそのままか、少ない改造で動きそうな感じ。しかしPeerCastStationはただのサーバ・クライアントなので動画受信してきても再生できなくてつまらんけどな。ぱっと見た感じだと動画のデコーダにアクセスできるクラスは今のところなさそうだ。自前でデコーダ書くという最後の手段は当然あるものの、ものすごく大変なのとモバイルなCPUでMonoで動画のデコーダとかまともな速度で動く未来はこれっぽっちも見えないので絶対やらない。
でもまあなんか楽しげなのでストアで販売までいかずとも何かしか作ってみるかもしれないな。