Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@kjunichi

GLSLをサーバーサイドでレンダリングして、GPUが非力なkindle fireでみる

More than 1 year has passed since last update.

mrubyでこんなことやりました!的な記事です。

macOSで動かして試していますが、Linuxでも動くといいなぁと願いながら開発してます。

GLSLをサーバーサイドでレンダリングして、GPUが非力なkindle fireでみる

背景

今年つくったmrbgemのmruby-glslは標準出力にppm形式でレンダリングした画像を出力します。

一方ffmpegが標準入力からの複数の静止画を読み込んで動画にすることができます。

  • -f pipe_ppm や -f image2pipe -pix_fmt ppm

さらに、ffmpegはライブ動画の形式のHLS形式での出力もサポートしていることがわかりました。

HLSとは

Appleが作った規格。なので、iOSでは動く。また、kindle fireやAndroidでも動く。しかし、PCでは冷遇気味。
Edgeがちょっとサポートし始めたが、Chrome、Firefoxともに未サポート。当然macOSのSafariだと動く。

動画を10秒から数分程度のファイルに分け、直近の動画ファイルの数本を索引ファイルに書き込んで、ブラウザは、このファイルを読みんで、再生すべき動画ファイルをDLする、この方式の為、完全にリアルタイムで配信という訳ではないが、まぁ実用的にライブ放送っぽいことは出来る模様。

この応用で、GLSLの編集はkindle fire等のGPUが非力な端末で行い、サーバーサイドでレンダリングを行って、その結果を
HLS形式の動画で端末に返すことで結果を確認できる。結果が動画なのでさらに他の家族も同時にGLSLのレンダリング結果を楽しめるはず。

これで、kindle Fireを持ち歩いて高度なGLSLを家のどこでも書くことができるようになるはず!

~/work/mruby/glsl/mruby/bin/mruby ~/work/mruby/glsl/mruby-glsl/examples/plazuma.rb |ffmpeg -y \
-f ppm_pipe -r 30 -i - \
-f ssegment -s 320x240 -r 30 -c:v libx264 -preset fast -pix_fmt yuv420p -b:v 1024k -quality good \
-strict experimental \
-segment_list time.m3u8 \
-break_non_keyframes 1 -segment_list_type hls \
-segment_time 10 -segment_list_size 3 -segment_list_flags +live -threads 4 \
out%03d.ts

全体の構成

glsl2hlsSystemImage.png

redis

  • redisをジョブキューとして利用

WebServer

mruby-simplehttpserverで実装。ただし、後述するSafariのPOST対応の為、独自版を使用。

  • 静的ファイルの配信
  • なんちゃってWebAPI

フロントエンド

Fetch APIが開発当時のMobile Safariで使えず、XMLRequestでテキストフィールドに入力された、
GLSLのバーテックスシェーダーとフラグメントシェーダーのプログラムコードをJSON化して、なんちゃってWebAPIに投げます。

Link

サーバーサイド

  • POSTされたJSONをRedisに格納する(なんちゃってWebAPI)
  • Redisに投入されたGLSLプログラムコードをレンダリングして、HLSに

glsl2hlsの詳細

  • RedisにGLSLコードが投入されていないかチェック
  • 投入されたGLSLがあれば、レンダリングしてffmpeにPPM形式でパイプ経由で渡す

ログ周り

ようやく今年になってはじめたfluentdをつかって、やってみようとした。

にmrbgemがあったので、ありがたく利用させてもらいました。

ローカル環境では、PostgreSQLに出力するfluentdのPluginを入れて、Postgres.appに出力しています。

課題

  • 不要なtsファイルの削除
  • エラー処理
    • GLSLコードがコンパイルエラーだった時の処理

一連の作業で学べたこと

  • mruby-simplehttpserverとSafariのPOST
  • Cocoaなウィンドウを扱う(内部的にでも扱う)mrbgemsを組み込むとForkしてffmpegが扱えない
  • /dev/urandomはOSXでも存在した
  • gettimeofdayの使い方

Simple-http-serverとSafariのPOST問題

macOSのSafariだと、POST時にHTTPのヘッダ部を送信したら必ずflushするみたいで、
オリジナルのSimple-http-serverだとPOST出来なくてハマった。

ffmpegが使えない?!

当初、webdサーバーでリクエスト、受けたら、GLSL2HSLするプロセスをforkして実装。しようとしていた。
すると、以下のようなエラー

The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.

mruby-glslを組み込んだ状態でProcess#forkしてffmpegを動かせなかった。mruby-glslとffmpegそれぞれでCocoaのGUI周りの初期化をおこなう
APIを読んでおり、このAPIの一部が同一プロセスで1度だけしか呼び出しを許可していないことに起因している模様。

成果物

おわりに

この記事の検証目的も兼ねて、自作PCを刷新して、せめてVGAをNVIDIAのGeForce GTX 1060にアップグレードして試したかったのですが、かないませんでした。
そんな訳で、2012年製のMacBook Pro Retinaで動かしました。

参考資料

関連記事

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
kjunichi
WebRubyがきっかけで、mrubyで実装されたhttp2サーバーのtrusterdに絡んだ事をやってみたり、ElectronのIssue眺めたり、手元で動かしたり、node.js関連。WASMも少々。投稿する記事の内容は個人の意見であり、所属する企業の見解を代表するものではありません。
japan-systems
「2019年に50周年を迎えたIT企業です。最先端の技術により全国の企業、官公庁、自治体に多くの実績があります。」

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?