Skip to content

OpenMAX のゼロコピー化 #83

Open
@dynamis

Description

@dynamis

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の形式で提供することで映像バッファのコピ
ーを回避するためのAPI OMX_UseEGLImage が提供されている。

同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向けのゼロ
コピー実装が存在する。

https://hg.mozilla.org/mozilla-central/file/2b520bbe1d52/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp

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変換が必須な場合、上記よりも工数が増大する可能性がある。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions