前回の記事では、画像のアップロード処理と、動画変換の処理を分けることで
fps の改善を図りました。
今回は、もっと根本的なところで、通信処理自体を見直すことでの
改善を図りましたので、その内容について掲載させていただきます。
■前回記事までのプログラムでの問題点(通信部分)
携帯端末から、1枚1枚画像をサーバにアップロードしていますが、
その際、http プロトコルを利用しており、
1枚アップロードするたびに、通信確立~通信切断までを実施しています。
fps を上げれば上げるだけ、通信確立~通信切断を繰り返すことになりますが、
この処理には時間を要するため、画像をアップロードできる枚数自体、
すぐに頭打ちになります。
■改善案
通信を一度確立した後は、通信を切断せずに、
確立済みのコネクションを利用して、アップロードを繰り返すことができれば
1秒間に、より多くの画像をアップロードできるようになるはずです。
■改善方法
以前、記事として紹介した、Socket.IOを利用することにします。
Socket.IOについては、様々なサイトで詳しく説明されているので、
ここでは割愛します。
今回、改善したい部分は、画像のアップロード部分になるため、
構成としては以下のようになります。
・携帯端末(今回はAndroid)から、サーバへのアップロードは、Socket.IOを利用
・一定枚数画像を受信した後、動画変換を行う部分は、
別スレッドで実施する(前回記事と少し形が変わります)
・Oculusで動画を再生する仕組みは、これまで通りhttp(Apache)を利用
■携帯端末(Android)処理
Socket.IOを用いた通信部分を担当するWebViewと、
カメラで映っている画像を画面上に表示&定期的に取得するためのSurfaceViewがある
Activityを1つ用意します。
カメラから画像データを定期的に受けとったら、
そのバイナリデータをBase64形式に変換後、
WebView経由でサーバ側にアップロードします。
■サーバ処理
Base64形式で送られてくる画像データを、1つの動画としてまとめる枚数ごとに
サーバ内のフォルダに保存していきます。
所定の枚数保存したタイミングで、動画変換処理をサブスレッドにて実施します。
■Oculus側処理
上述のSocket.IOとは別に、サーバ上でApacheを起動しておきます。
Oculus側は、前回迄の仕組み通り、http通信にて動画を1つ1つ
ダウンロードして、再生します。
■改善結果
画像サイズが「320×240」である場合、
もともとの仕組みでは 4fps で限界が来ておりましたが、
今回の仕組みに変更したところ、24fps 迄上げることができました。
※30fps まで上げると、遅延が発生してしまいました。
また、画像サイズを「448×336」まで引き上げたところ、
15fps迄上げることができました。
※20fps まで上げると、遅延が発生してしまいました。
クライアント側については、特に改善していなくても、
どちらのケースでも動画再生を問題なく行えました。
■今後の改善について
現段階で、思い浮かぶ改善点は、以下の通りです。
・通信にWebViewを利用するのを止めて、Nativeから直接アップロードするように
修正することができれば、Base64変換が不要になる予定のため、
さらに速度が改善する可能性があります
・Androidの場合、カメラに映っている画像データを受け取ると、
形式が「YUV」のため、「RGB」への変換が必要になるのですが、
その処理を携帯端末内で実施すると、負荷が高くなります
サーバ負荷が上がるとしても、この処理をサーバ側に移譲する方が
良い可能性があります
※ただし、現状すでに、バイナリ値を直接操作する変換ロジックを
用いており、変換処理自体にはさほど時間を要していないものと
考えますので、改善の可能性は低いです
・複数の画像を一度にアップロードする方が、
通信負荷をさらに低減でき、速度が改善する可能性があります
次週は、通信周りについて、もう少し改善を進めます。
弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。