Closed cosmo0920 closed 5 years ago
ちなみにRZ/G1では/usr/local/libにOpenMAXのライブラリがあったが、R-Car Gen3では/usr/libに移動されている。これについては対応済み。
R-Car M3ではOpenMAXの動作確認をする前に、以下のカーネルモジュールをロードしておく必要あり:
root@m3ulcb:~# modprobe -a mmngr mmngrbuf vspm_if uvcs_drv
未だに少ししか調べられてないが
ts:1508327328.478728 level:0x00010000 func:OmxrMcApiProxy_ComponentTun
nelRequest(1327) tid:3332 mes:not implemented
少しログを増やしてみたところ、OMX_GetHandle()
でそのままOMX_ErrorNotImplemented
が返ってきているようだ。あれこれ設定を施す前の初期化の段階で止まっている。
GStreamerでは再生できるようだし、初期化の段階ではOMX_GetHandle()
でハンドルを取得してOMX_GetState()
でOMX_StateLoaded
であることをチェックするだけで、基本的に違いはないはず。
ということでコード側で出来ることはあまり無いように見えている。その前の設定の問題だろうか?
R-Car Gen3のgst-omxとの違いをよく見ていけば原因はわかると思うが...
修正して https://github.com/webdino/meta-browser/tree/firefox-60esr に修正適用済み。
下記は調査時の記録。
Firefox 64-bit (RZ/G2E) 上ではデコードに失敗、Gstreamer 64-bit (RZ/G2E) では成功、Firefox 32-bit (RZ/G1) でも成功。
OMX ライブラリはバイナリだけで提供されており、アプリケーションは dlopen() から dlsym() して中の関数呼出しを行っている。
通常の初期化シーケンスとしては OMX_Init() から OMX_GetHandle() を行い、必要なコーデックに応じたハンドル(呼び出すべき関数ポインタのリストなどを含んだ構造体)を取得し、このハンドルを用いてハードウェアデコードを行っていく。
Firefox 64-bit ではこのハンドルを用いた関数呼出し(GetState, SetParameter など)の実行において、関数実行がエラーとなりうまく動作しない状況となっていた。
OMX_Types.h で定義されている OMX_U32 および OMX_S32 が以下のように定義されていた。
typedef unsigned long OMX_U32; typedef signed long OMX_S32;
long は ARM64 では 64-bit 値になるようで、OMX_U32 などの名前から期待される 32-bit 値にはならない。
一方ハンドルは OMX_Component.h の OMX_COMPONENTTYPE で定義されているが、(厳密にそうであることを確認したわけではないが)この中のメンバ OMX_VERSIONTYPE nVersion が OMX_U32 の意図せぬ 64-bit 化によって大きくなり、その結果として以降の構造体メンバが OMX_U32 が 32-bit だった場合と比較して 64-bit ずれる現象が起きていたと思われる(ずれが 64-bit になるのはメモリのアラインメントのため)。
このずれにより、このハンドルのメンバとして登録されている GetState の呼び出しを行うと、実際には構造体の次のメンバである ComponentTunnelRequest の呼び出しを行ってしまい、結果として引数として指定したパラメータの異常から関数呼出しがエラーとなっていた。
OMX_U32 および OMX_S32 を int で定義することとした。
typedef unsigned int OMX_U32; typedef signed int OMX_S32;
R-Car Gen3のgst-omxのOpenMAX ILのヘッダーは以下:
stdintの型に置き換えられている。
typedef uint32_t OMX_U32;
typedef int32_t OMX_S32;
以下のコミットでOpenMAX ILのヘッダーが更新されているようだ
バージョンを更新しないで中身が入れ替わってる? KhronosのOpenMAX ILのページは以下:
今ダウンロードできるものは更新されたもののみのようだ。
ちゃんと直すらなら、Firefox側のOpenMAX ILヘッダーも全て更新されたものに置き換えた方が良いか。
なるほど。OpenMAX IL のオリジナル側が正しく修正されているのであれば、それで置き換えてしまったほうが良さそうですね。時間のあるときに全置き換え版のパッチも作ってみて、問題なさそうであればそちらに置き換えてしまおうと思います。
実は当初の動作確認は stdint の型で修正して行っていたのですが、OpenMAX IL のヘッダとして stdint.h などを include して良いようなコンテキストを想定しているものかどうかもわからなかったので、一番保守的な(修正量が少ない)方法で今回は直していました。
renesas-rcar の方も一旦 int 化してからヘッダをアップデートしているので、同じような経緯をたどってはいるようですね。
https://github.com/renesas-rcar/gst-omx/commit/c003e37ece50ff0f964786bb3c4d04ddb45d29ea
なるほどなるほど。gst-omxもまったく同じ罠にはまっていた感じですかね。 私はそもそもcaller側でアライメントずれているという発想ができてなかったので感謝です!
RZ/G2(R-Car)でH.264のハードウェアデコードに対応させたい。 RZ/G1EやRZ/G1向けの #3 のOpenMAXパッチを当てた場合、モジュールの読み込みには成功するが初期化に失敗する。 この原因を調査してH.264のハードウェアデコードをサポートしたい。