6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

格安で遠隔視点型HMDを作る (AndroidスマホでGstreamer)

Last updated at Posted at 2022-12-07

やりたいこと

当方ゲーマーではないのですが、HMD(ヘッドマウントディスプレイ、VRゴーグル)ってどんなんだろう、と少し興味がわきました、(想像ですが、映像にフィルタ掛ければ漫画の中に入れる体験とかできんの?2次元の世界に没入できたら楽しそうだなぁ、とか、)
とはいえVIVEとかMetaとか5万以上かかるしなぁ、貧乏人の自分がいきなり買うのは高そうだなぁ、、

そうだ!余ってるスマホを活用(Gstreamerとか組み込んで)して、VRゴーグル風に2眼分映せば何か感じ取れるんじゃね?

今回使う機材と構成

使うハード、ソフト(ライブラリ)

  1. 端末A Galaxy S10 (カメラ/映像送信機) ⇒眠ってたAndroid端末その1
  2. 端末B Pixel 6 (VRゴーグルの画面部/映像受信機) ⇒眠ってたAndroid端末その2
  3. ダンボールゴーグル (VRゴーグルの筐体) ⇒前に100均(セリア)で買った
  4. Gstreamer(Android版) https://gstreamer.freedesktop.org/ ⇒今回のキモ
    ※Android版Gstreamerライブラリのリンク方法や叩き方は割愛、後述の参照[2]のソース等を見てください。基本JNIで叩くだけだけ
              

構成とデータの流れ

 端末Aで撮った映像をローカル無線(テザリングネットワーク)上にH264/RTP映像を流し、端末Bで2眼それぞれで表示してVR風に表示させることを目指します。

Gstreamerとは

GStreamerとは動画の一連の処理(デマックス、デコード、フィルタ、ストリーム分岐、など)をカスタマイズする事が容易なメディアフレームワーク。予め用意された機能(プラグイン)を'!'(接続子)で繋げる事でパイプラインとして設計し、柔軟にデータ処理をプログラミングする事が出来ます。(参照[1])

コマンドライン例

コマンド (Windows版Gstreamerコマンドで確認)
gst-launch-1.0 -v filesrc location=hoge.mp4 ! qtdemux name=demux  demux.audio_0 ! queue ! decodebin ! audioconvert ! audioresample ! autoaudiosink   demux.video_0 ! queue ! decodebin ! videoconvert ! videoscale ! autovideosink

解説

ローカルにある"hoge.mp4"をqtdemux(Quicktime形式のデマクス処理)で映像と音声に分岐し、decodebin(自動でコーデック判別して最適なデコーダを選択するもの)でデコードし、autovideosink/autoaudiosink(最適な映像/音声レンダラを自動で提供)で出力
※普通のMP4プレイヤを模擬すると上記のようなパイプライン処理になります

今回構成でのGstreamerパイプライン

1. 送信側

カメラで撮った映像を分岐させ、1つめはSurfaceViewへ表示、2つめはh264エンコードしてRTPで送信
※glimagesinkはAndroidのSurfaceView、ahcsrcはAndroidのカメラとリンク可能なエレメントです。(参照[2])

パイプライン
"ahcsrc name=ahcsrc ! capsfilter name=filter caps=video/x-raw,width=640,height=480,framerate=30/1 ! tee name=tee tee. ! queue name=video_queue ! glimagesink name=vsink tee. ! queue name=udp_queue ! videoconvert ! openh264enc bitrate=5000000 ! h264parse ! rtph264pay pt=100 mtu=1400 config-interval=3 ! udpsink host=\"192.168.xx.yy\" port=9000"

2. 受信側

 port9000で受信したRTPをデコードして2分岐、それぞれを別のSurfaceViewで表示
※左右の目で見せるSurfaceViewを用意し、teeで分岐させたglimagesinkにリンクさせてます

パイプライン
"udpsrc port=9000 ! application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconvert ! tee name=tee tee. ! queue name=video01_queue ! glimagesink name=vsink_01 tee. ! queue name=video02_queue ! glimagesink name=vsink_02"

完成!!

動作している送信機と受信機

ゴーグル化!​

あとがき(この試作の利用?発展させる方向性)

・外部から映像を受け取って、受信機(2眼)で見るってのは応用が利きそう
 ⇒映像ソース側でフィルタとか加工すれば面白いVRコンテンツとか作れるかも
・今回はRTPだったりWiFiのローカルNWでのP2Pだったが、別の構成やGstremaerパイプラインを使うことで、
 別の映像プロトコルつかったりインターネット経由で遠距離伝送もできそう。
・本物のVRゴーグルも使ってみたいなぁ、、

参照URL

■[1] RustでもGStreamer理解がしたい! その0 〜まずはGStreamerパイプラインを書こう 〜
https://qiita.com/alivelime/items/50d796c09baabb765625

■[2] Example Android App for AHCSRC
https://github.com/justinjoy/gst-android-camera

6
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?