Android - MediaCodecの罠

明けましておめでとうございます!

エンジニアのTです。

Androidで動画生成を行う場合、MediaCodecAPIを利用する事になると思います。

サンプルはほどほどにネット上に転がっているので、実装するのはさほど難しいわけではありませんが、デバイスにより、ちょっとした落とし穴に嵌まる事があります。


まずはエンコードしてみる

まずは普通にエンコード成功した場合の動画の1画面です。
とくに問題なく、きっちりとエンコードされています。



次にSamsung Galaxy SC-03Eでエンコードした場合。
色が・・・・おいしい紅茶が突然人工的でまずそうな色に変わってしまいました。




最後に富士通ArrowsX F-02Eの場合。
・・・なんかゴーストが出てるし、下部が潰れてるし、これはひどい。




なぜ同じコードなのに機種によってここまで違うのか・・・

答えはハードウェアエンコーダーにあります。

1〜3枚目の動画で利用されていたエンコーダーはそれぞれ以下の通りです。
MediaCodecListからMediaCodecInfoを取得すると、利用可能なエンコーダー/デコーダーを取得する事ができます。

1枚目:OMX.qcom.video.encoder.avc
2枚目:OMX.SEC.AVC.Encoder
3枚目:OMX.Nvidia.h264.encoder

全然違いますね・・・
1枚目はQualcomm製で、2枚目はSamsung Exynos。3枚目はNVIDIA Tegra系の端末に搭載されているハードウェアエンコーダーです。


さて、それぞれの対応です。

Qualcomm
問題ないので、このまま!

Samsung Exynos
これはビットマップをYUV420SemiPlanarに変換する時に注意する必要があります。写真では黄色が青になっていると思いますが、実はこれ、が逆なんです。なので、YUVに変換する時に赤と青を入れ替えてやれば、正しくエンコードする事ができます!

NVIDIA Tegra
この場合は、ゴーストも出てるし、下部が潰れてるしで、Exynosのように色を入れ替えるなどでは対処できません!ネットでも情報が極端に少なく、諦めかけたその時に、光明が見えました・・・

原因は、なんと解像度でした。

この動画は全て640x360で作成しているのですが、Tegra系は16の倍数でないと正しくエンコードされないのです!

なので、16の倍数に収まるようにTegra系だけ出力サイズを変えてやる必要があります。縦幅が360だと16で割り切れないので、640x368として出力すると成功します!



あ〜なんて面倒くさいのでしょう。
全ての端末で検証する事も難しいですし、新しく発売される機種に搭載されるエンコーダーでも依存がでるかもしれないので、油断できない部分ですね。

動画、音声関係は搭載されているハードウェアに依存する部分も多いので、機種により差が出てくるパターンが多くなると思います。


しかし、インタラクティブなアプリは、見栄えも華やかになるので、ぜひ習得しておきたいポイントですよね!

それでは、また!


トンガルマンWebサイト
https://tongullman.co.jp/index.php
facebook
https://www.facebook.com/Tongullman

0 件のコメント:

コメントを投稿