メディアエンジンのAPI調査

SoC上のパフォーマンスがなかなか確保できない状況に有るので、カットシーンをプリレンダにすることを検討した。結論から言うとリアルタイムレンダリングの方が良いと判断した(制作の必要があるゲームアセットの量は変わらない)のでメディアエンジンもほぼ活用されない。BGMのために追加する可能性は有るが、この手のメディアエンジンAPIはフレーム単位の投入を良くサポートしていないので、ループの処理が困難である等の問題が有る。
SoCは伝統的に

で構成され、3Dアクセラレータやメディアエンジンはチップベンダが提供するバイナリblobで実現されるのが一般的であるため、チップベンダがどのようなAPIを提供するかが重要なポイントとなる。
幸い、3Dアクセラレータは事実上OpenGL ES以外のモバイルAPIは存在していないので、アプリケーションはOpenGL ESをターゲットに開発すれば十分と言える。
問題はメディアエンジンで、これは良い標準が無い。最大公約数はAndroidのMediaPlayer系APIということになる(これはOpenMAX ALに相当する - エフェクト等は別のAPIに分離されている)。例えばSnapdragonのDSP(Hexagon)はそのVLIWプロセサ向けのSDKNDAで提供しているが( https://developer.qualcomm.com/mobile-development/maximize-hardware/multimedia-optimization-hexagon-sdk )、これを通常のSDKから使うにはAndroidのメディアフレームワークに頼る必要がある。

(Androidのメディアフレームワーク)

Allwinnerのようないわゆる中国系のSoCベンダのチップを使用するなら、Androidのメディアフレームワークに頼るしかない。彼らのチップは基本的にAndroidを動作させることに特化しており、SDKも提供されない。
通常のLinuxではlibhybrisを使ったローダ等が書かれているが、Allwinnerならば libvdpau-sunxi のようなリバースエンジニアリングによるドライバも有る。
しかしながら、AllwinnerやRockchipのようなチップベンダはこの手のeffortやIPの状況に興味を示していないので、簡単に状況が改善することは無いだろう。(これは3DアクセラレータにおけるPowerVRの状況に似ているように感じる。)
Banana PiやpcDuinoのようなAllwinner SoCを採用したLinuxボードはそれなりに数が有るが、これらはメディアエンジンのAPIを提供していない(OpenGLはARMのライブラリでサポートできるので提供されている)。同じことはSnapdragonにも言える。
率直に言って、この状況はモバイルLinuxプラットフォームがAndroidに収斂したという残酷な現実をそのまま表わしている。GStreamerやOpenMAXはMaemoのような2000年代初頭から存在する他のモバイルLinuxに強く支持されていたが、これらが(タブレットスマートフォン市場から)事実上消滅した現在としてはAndroidが唯一の現実的なハードウェア抽象化レイヤとして機能している。FirefoxOSのようにAndroidをドライバとしてそのまま採用するシステムは今後も表われるかもしれないが..
AndroidのメディアフレームワークはOpenMAX ALとOpenSL ESを経由して公開されている。いづれもバージョンは1.0で独自の省略と拡張が有る。

GStreamer

何気にGStreamerはSoC業界における事実上の標準の地位を占めつつある。GStreamerは最初からバイナリblobとの親和性を目標の一つに据え、広範なパーサのサポート、C API等必要なポイントをよく抑えている。Gstreamerには0.10と1.0の2つのAPIシリーズが有るが、基本的には1.0をサポートすれば良い状況になっている。(Tegraのように0.10を標準としているケースも有るが、1.0も提供されている。)

上のi.MX実装を見ると解るように、メディアエンジンのCODECを通常のデコーダのように公開している。GStreamerは入出力バッファに専用のMIMEタイプを振ることでタイル化されたバッファなど特殊なレイアウトのバッファも持つことができる。これによりメディアエンジンネイティブフォーマットを直接扱えるように工夫している。
OMAPのようなプラットフォームでは、OpenMAX→GStreamer wrapperを使ってCODECを公開している時期も有った。これはバッファの管理等が難しく、現状ではほぼ全てのベンダはネイティブのGStreamerプラグインを提供しているように見える。
GStreamerはPC(LinuxWindowsMacOS X)の良いサポートを持っていることも注目に値する。つまり、ビデオの入力等の機能も同様にwrapしているため、同じコードが流用できる可能性がある。ただし、使用すべきプラグインが異なってくるためwrite once run anywareにはならない。基本的には、アプリケーション側にもハードウェアの知識が必要になる。GStreamerはこれをwrapするためのplaybinのような仕組みを備えてはいるが、単純なuse caseにしか対応できない。
問題としては、GStreamerはglibをベースにデザインされているため、Linux以外のプラットフォームでもglibの流儀に合わせたファイル配置やコードにする必要が有る点。このため、WindowsMacOSにおけるGtkくらい良く動かない。GStreamerは事実上gnomeの一部なのでgnomeが動作するプラットフォームには基本的に移植されている。GStreamerはAndroid向けのバイナリも存在する。

OpenMAX IL

OpenMAX ILは、まさにメディアエンジンのためのAPIとして規格されている。現状では良いPC実装は存在しない。Tizoniaは現状Linux向けだがそれなりの数のCODECを既にwrapしている。

歴史の有るSoCでは、ほとんどの実装がOpenMAX ILをサポートしている。また、AndroidのstagefrightがOpenMAX ILを前提としている。

  • OpenMAX Integration Layer (IL)

The OpenMAX IL provides a standardized way for Stagefright to recognize and use custom hardware-based multimedia codecs called components. You must provide an OpenMAX plugin in the form of a shared library named libstagefrighthw.so. This plugin links your custom codec components to Stagefright. Your custom codecs must be implemented according to the OpenMAX IL component standard.

(Allwinnerのようなベンダは、OpenMAX ILコンポーネントを用意するかわりにMediaPlayer、つまり、libstagefrightを直接提供している。このため、全てのAndroidチップがOpenMAX ILをサポートしているわけではない。)
注目の実装としてはBroadcom VideoCoreが有る。VideoCoreはRaspberry Piに採用されており、BroadcomSDKはGStreamerを提供せずOpenMAX ILのみを提供しているので、メディアエンジンを活用するつもりならOpenMAXを使用する必要がある。
もっとも、GStreamerはOpenMAX ILコンポーネントをwrapしてGStreamerエレメントにするwrapperを提供しているので、GStreamerを使いたければそれを使用できる。
Android NDKは、OpenMAX ALを採用しているがALからはCODECを直接操作することはできない。

まとめ

結局のところ、GStreamerもOpenMAX ILもゲームオーディオ/ビデオの要求を直接的に満たすものではなさそうに見える。
ゲームオーディオについて:

  • AndroidならOpenMAX ALとOpenSL ESでAndroid固有のエフェクトも含めてアクセスできる。
  • Raspberry PiならOpenMAX ILが有るが、エフェクトやミキサに関しては未知数。そのうち調査したい。
  • LinuxWindowsMacOS Xなら素直にOpenALを使う。

今のところ、オーディオは未だに固定パイプラインの時代と言える。直近でプログラマブルオーディオが流行するとも思えないので、しばらくはハードウェア(実際にはDSPだけど)の機能の公約数をとってサウンドデザインを行っていくしかない。つまり、エフェクトはLPF、リバーブはプリセットを数種類、ピッチ変更はできたりできなかったり。。