先週分の日記は書いたんだが、なんともまとまらん感じなので上げそこねた。
ここしばらく体調が安定せず。さりとて悪いというほど悪くもならず、だらだらと調子悪いなぁというのが続くのでなんともかんとも。 先週あたりは胃が痛くなってみて、良くなったと思ったら週末あたりから今週にかけて頭が痛い。 熱っぽいかと思ったんだけど測っても熱はなく、外に出る元気だけがないので月曜は休んでしまった。
まだぼーっとするんだがなんだろうなこれもう。生活リズムが乱れまくってたのがよくないかな。早く寝るように心掛けよう。
1.6.0は先週出した。すごいいろいろ変更したけどあんまり大きい変更はなかったような。 HTTPのBasic認証入れたくらいか。あった方がよさそうだから入れただけなので誰も喜ぶ人は居なかったかもしれない。
1.7.0は入れ残した変更とか、以前から気になってた部分の修正を入れたりとか。
JSON RPCで返すオブジェクトIDとしてObject.GetHashCodeを使ってたんだけど、当然こいつがユニークな保証なんざないのでどうにかしないとなーと思ってた。 それっぽく動いてるのが不思議なくらいだったわけだし。
.NETにはオブジェクトのアドレスとかRubyのobject_idみたいなのがないのでどうすればいいのか。 IronRubyのobject_idどうやってるのか見たらWeakReference使って自前のオブジェクトID管理をしてた。なるほどなー。
というわけでPeerCastStationも自前でユニークになるようなオブジェクトIDを作って管理するようにした。 シンプルな物なので大量のオブジェクトが登録されると重くなりそうだが、問題になるほど大量のオブジェクトが登録されることもなさそうなので気にしないようにした。
あとFLVがPeerCast(IM等)で上手く視聴・リレーできないのにも対応した、つもり。これは長くなるので後に書く。
まだIssueには要望とかそこそこあるけど飽きた。 不具合対応はまあ好きだからやるけど、要望対応はしばらくお休み。誰かやって。 俺は自分の作りたい機能を優先させるわ。
FLVの視聴をするにはPeerCastStationが必要と言われていた。
旧PeerCastだとFLVを認識できないのでContent-Typeを吐きだせず、プレイヤーが認識できないので再生できない。 ……という話だったら既知なんだが、実際にはプレイヤーがContent-Type無くてもFLV認識して再生できるので視聴できちゃった。
それならそれで良かったではないですかと思ってたんだが、 PeerCastIMでも見れるけど視聴・リレーが安定しないのでやっぱりPeerCastStationが必要という話が聞こえてきてて一体何故だろうなぁと。 Content-Typeがなくて見れないならともかく、見れるけど安定しないっていうのは全く想定外。 プレイヤーが対応さえしてくれれば視聴・リレー等は従来のPeerCastでも問題なくできるはずだったんだが。
安定しないという情報だけでは何が起きてるかはわからんので、自分でPeerCastIMを入れてFLV配信を見てみると確かにぷちぷち切れまくる。 PeerCastのログを見てみるとSend skip 136とかそんな感じのエラーが出てた。あーこれだー。
Send skipってログが出るのはコンテンツパケットバッファの溢れだったはず。ソースを確認してみるがやはりそうっぽい。 PeerCastは受け取ったコンテンツパケットをリングバッファにつっこんで、リレーや視聴に送るのはリングバッファから取り出してるんだけど、そのリングバッファが溢れてるようだ。
溢れる原因はおそらくコンテンツパケットが細かすぎるせいだな。PeerCastはパケットサイズにかかわらず64個しか保持してくれないので細かいパケットが沢山とんでくると溢れる。
実際に流れてる秒間あたりのコンテンツパケット数とサイズを調べてみると、1Mbps弱のWMVでは秒間16パケットで8kB/パケット程度だった一方で1Mbps弱のFLVだと秒間67パケットで1kB/パケット程度だった。やっぱり小さくて数多いな。PeerCastは64パケまでしか保持しないので、秒間67パケットだとプレイヤーが1秒以下のラグで受け取ってくれないと溢れてしまう。 PeerCastStationではなんとなく100個まで保持してたのでたまたま溢れず動いてるようだ。100個にしたのはなんとなくだし完全にたまたまじゃねーか!
コンテンツパケットはASFやFLVのパケット単位をそのまま使っているので、数とサイズはエンコーダやマルチプレクサに依存してしまうんだが、 コンテンツパケットなんざ所詮PCP(PeerCastのプロトコル)レベルの話なのでべつにそのまま使う必要もない。 複数のFLVパケット(FLVだとタグと呼ぶ)をまとめて一つのコンテンツパケットにすれば、パケットサイズを増やしてパケット数を減らせる。
FLVタグをいくつかまとめて一つのコンテンツパケットにするにはどうすればいいだろう。 新しいヘッダが来たりしたら以前のタグと一つにするわけにはいかんわな。 あとパケットサイズが16kB越えるとPeerCastが受け取ってくれないのであんまり沢山のパケットをくっつけるわけにもいかん。
そんなわけで新しいヘッダを受け取るか、コンテンツパケットのサイズが7.5kB越えるまでは貯めて、 貯まったやつをくっつけて1コンテンツパケットにするようにした。 FLVタグのサイズにもよるが8kB~10kB前後くらいのパケットが秒間10~20個程度流れるようになるはずだ。
適当に試したところ、秒間18パケット、パケットサイズ8kBくらいになってたのでまあいいんじゃないでしょうか。 ビットレートとかちゃんと設定してないので適当だけど、表示上は1.2Mbpsくらいだったのでそんなに悪くもない数字のはず。 あとは1.7.0(開発版)としてリリースしたので使ってもらって大丈夫なら大丈夫だろう。
せっかくFLV配信が一部で盛り上がってるのに視聴するだけでPeerCastStationを要求するってのは残念な話なので、 これでPeerCastIMでもFLV配信見れるようになってくれると嬉しい。わざわざ互換性持たせてるんだしな。
当面はこれで解決したとして、固定数のパケットバッファは以前から思ってたけど良くないよなこれ。 PeerCastが受け取ってくれるパケットが16KiBまでという制限もあるので、64個で1024KiB、頑張っても1MiBまでしか保持できない。 8Mbps越える配信ではどう頑張ってもプレイヤーが1秒未満のラグで受け取ってくれないと落ちちゃいますな。 実際にはおそらくパケットサイズが16KiB越えるか、パケットサイズはそんなに大きくならない場合はパケット数が増えるはずので8Mbpsの時点でも既に危ないだろう。 そんな高ビットレート配信見たことないしやる人も居ないと思うけど、今後もありえないとは言えない。LAN内に限れば普通にありうるし。
回避方法としてはパケットサイズの制限を上げるという手もあるし、既にPeerCastStationでは16KiBよりは大きくしといた気がするが1、やっぱり固定数のパケットバッファがよろしくない。パケットサイズおよびレートがエンコーダ・マルチプレクサ依存なくせに小さいパケット沢山送ったらバッファオーバーってのはどうなのよ。
対策としてPeerCastStationでは固定数じゃなくてパケットのタイムスタンプ見て経過時間で消せないか検討していたようだ。 ようだ、っつーのは自分でやっておいてすっかり忘れてたからなんだが、パケットにタイムスタンプ保持してるのを見て思い出した。 ただPCPのコンテンツパケットにタイムスタンプはくっついてこないので、自分のところに受信してからのタイムスタンプになってしまうが、まあそんなに問題ないか。 そこまで一気に変更するのもなんだしとりあえず動いてるからいいやと100個固定で放置してたけど、そろそろ考えた方がいいかもね。
今確認したら1MiBだった。十分すぎるでかさだ。 ↩