Description
H.264 再生に OpenMAX を使ってもバッファのコピーが発生しているのをなくして CPU 使用率削減をしたい件、長期間後回しにしていますがこちらに issue たてておきます&以前の調査時の報告を貼り付けておきます:
Ashie Takuro wrote on https://redmine.clear-code.com/issues/3869
はじめに
本文書はGeckoでのOpenMAXによるH.264の再生において、映像バッファのコピーを行わ
ずにデコードデータを直接参照(以下、ゼロコピー)することによりCPU使用率を削減
することが可能であるか否か、可能である場合はその実装方法について調査した結果を
まとめたものである。調査結果
OpenMAX ILにおけるゼロコピー実装
OpenMAX ILでは、映像バッファをEGLImageの形式で提供することで映像バッファのコピ
ーを回避するためのAPIOMX_UseEGLImage
が提供されている。
- https://www.khronos.org/openmax/il/
- http://maemo.org/api_refs/5.0/beta/libomxil-bellagio/group__buf.html#ga9d093a08220dd91e4a95f7adbaa30dc
同APIが実装されている場合はプラットフォームに依存しないゼロコピー手段を実装す
ることが可能である。しかしRZ/Gにおいて同APIをコールすると以下のようなログが出
力されることから、同APIは実装されていないと考えられる。ts:1512023249.299315 level:0x10000 func:OmxrMcApiProxy_UseEGLImage(1211) tid:1294 mes:This function is not implemented
同APIが実装されていない場合は、プラットフォームに依存した方法でのゼロコピーを
別途実装する必要がある。RZ/Gの場合、Qtでの実装例から見て、以下の方法で実装が可能であると考えられる。
- 同プラットフォームの独自APIであるmmngrbuf APIを使用して映像バッファの物理メ
モリ参照を取得- eglCreateImageKHR()のルネサス拡張機能を使用して、上記映像バッファに対応した
EGLImageを作成RZ/G向けGStremaerおよびQtでのゼロコピー実装
RZ/G上のQtでは、以下のパッチによってEGLImageによるゼロコピー実装が組み込まれる
ことを確認した。なお、本パッチはmeta-rzg-demosに存在するため、meta-rzg-demosを
使用せずmeta-qt5のみでQtをビルドした場合には、映像バッファのコピーが発生する。また、Qtでの動画再生ではバックエンドとしてGStreamerを使用しているが、主に以下
のパッチによってmmngrbuf APIによる物理メモリ参照を実現していることを確認した。Geckoへの組み込み方法
Geckoでの他のプラットフォーム向けの実装においては、例えばFirefox OS向けのゼロ
コピー実装が存在する。RZ/G向けのOpenMAX実装は上記実装をベースとしているため、基本となるメカニズムは
上記のものを使用可能である。ただし、Firefox OSでのメモリ共有の仕組みはAndroid
OSのGrallocをベースとしており、RZ/Gのそれとは実装が異なる。
この点についてはRZ/G向けにポーティングが必要であり、具体的には
PureOmxBufferData::GetPlatformMediaData()
の実装、およびVideoDataへのEGLImage
用追加実装が必要である。Geckoでのmmngrbuf APIの使用検証
詳細については割愛するが、上記GStraemerへのパッチを参考に、Geckoにおいて
mmngrbuf APIを実際に使用可能であることを確認した。そのコードの主要部分を
以下に抜粋する。already_AddRefed<MediaData> PureOmxBufferData::GetPlatformMediaData() { LOG_BUF(""); if (!mPlatformLayer.IsVideo()) return nullptr; #ifdef HAVE_MMNGRBUF OMXR_MC_VIDEO_DECODERESULTTYPE *decodeResult = (OMXR_MC_VIDEO_DECODERESULTTYPE*) mBuffer->pOutputPortPrivate; unsigned long physicalAddr = (unsigned long) decodeResult->pvPhysImageAddressY; int size = mPortDef.nBufferSize; int idExport, dmabufFd; int res = mmngr_export_start_in_user(&idExport, size, physicalAddr, &dmabufFd); if (res == R_MM_OK) { LOG_BUF("Succeeded to start export: local: %p, physical: %p\n", mBuffer->pBuffer, physicalAddr); } else { LOG_BUF("Failed to start export\n"); } mmngr_export_end_in_user(idExport); #endif return nullptr; }結論
- GeckoへのH.264再生のゼロコピー実装は可能である。
- mmngrbufによりデコードデータのDMAバッファを取得
- eglCreateImageKHR()のルネサス拡張で上記データからEGLImageを生成
- Gecko側VideDataクラスにEGLImageに対応した実装を追加
懸念事項
- Gecko向けの実装においてはYUV(NV12)データからルネサス拡張版eglCreateImageKHR()
を使用してEGLImageを作成予定であるが、現時点ではこれが実際に可能であるかどう
かの検証を行っておらず、またサンプル実装を見つけることもできていない(Qtにお
ける実装では、vspmfilterでRGBデータに変換してからEGLImageを生成している)。
vspmfilterによるRGB変換が必須な場合、上記よりも工数が増大する可能性がある。