SDL_net と Ethereal

引き続き Live Video Streaming というテーマ。
映像を、ネットで、低遅延で、ガスガス送る。
そのネットワーク部分。

Windows プログラムなので Winsock でも使えばいいのだろうけど
何かの間違いで Linux に移植とかあるかもなので
そのときの手間を考えて SDL_net を使うことに。

SDL_net はマルチプラットフォームなゲームライブラリである
SDL とあわせて使うように作られた
マルチプラットフォームなネットワークライブラリ。
その実体は、Winsock や Berkeley socket の薄ーいラッパ。

特に問題なく使えていたのだが、1つはまったところがあったのでメモ。

UDP で 24bpp 320pixel x 240pixel の画像を 30FPS で送る
(1フレームを300パケットに分割して)といったことをするのだが

それぐらいの大量のデータを送る場合
パケットの送信間隔が短いと大量のパケットロスが起きるのだ。

送信側の送信関数は成功してるのに、受信側で取ってみると
沢山のパケットが無くなっている。

ネットで調べると socket プログラミングにおいて
同様の問題にぶち当たった人がちらほら。
解決策は書いておらず。

原因を調べるために Ethereal を導入。

これを使うと、早い話
マシンからどんなパケットが出ていったのか
マシンにどんなパケットが入ってきたのか
が分かる。

参考ページ:
 Etherealを使おう

パケット監視。
すると、全パケット、送信元からでて、ちゃんと送信先に入っている。

つーことは、PCにパケットが入って、その先の処理…。
SDL_net のソース見ても recvfrom() を呼んでいるだけ。

recvfrom() なんかをキーワードにネット検索。

あ…

参考ページ:
 Programming UNIX Socket FAQ in Japanese
 Programming UNIX Sockets in C - Frequently Asked Questions: UDP/SOCK_DGRAM アプリケーションの作成

ソケットのバッファ? そんなんあるのか。
いや、あってもおかしくないか。
でー、それは、サイズ設定できるの?
…できるらしい。 setsockopt() 。

そんなわけで SDL_net のソースをいじる。

「SDL_net-1.2.5」で「SDLnetUDP.c」の 388 行目(SDLNet_UDP_Open() 内)に


// 送信バッファ拡張
{
int size = 1048576;
setsockopt(sock->channel, SOL_SOCKET, SO_SNDBUF, (char*)&size, (int)sizeof(size));
}

// 受信バッファ拡張
{
int size = 1048576;
setsockopt(sock->channel, SOL_SOCKET, SO_RCVBUF, (char*)&size, (int)sizeof(size));
}
と追加。

この送受信バッファの最大値はいくつなんだろうか。
Linux なんかだとそれを示す定数があるように書いてあったが
Windows の場合はどうなのか分からなかった。

とりあえず試行錯誤であふれない程度に拡張。
Research | - | trackbacks (0)