たくさんの自由帳

10 ビット HDR 動画を AV1 エンコードして WebM へ保存する機能を追加しました

投稿日 : | 0 日前

文字数(だいたい) : 4429

どうもこんばんわ
なんか今のAndroid Studio(Otter 2025.2.1)めちゃめちゃ CPU 使うんだけど。

cpu

ちなみに文字打ってるだけでこれです。JetpackCompose@Previewがあるわけでもない。明らかになんかおかしくないですか?
Intel Core i5 第8世代まだ頑張れ!

本題

自作アプリの話。
10 ビット HDR 動画を再エンコードする際にAV1が選べるようになりました。オープン技術が好きな人!!

AV1_HDR_AVAILABLE

以下の構成が選べるようになります!2つあります!
AV1 + Opus + WebMはどれもオープンでロイヤリティフリー!の特徴がありますのでオススメです。なんかAV1MP4よりもWebMに入っていてほしいですよね(VP9並感)、いや私だけかもですが、、
AACMP4の権利とかはわからないです。一説によるとFirefoxAACダメらしい?

映像コーデック音声コーデックコンテナ
AV1AACMP4
AV1OpusWebM

まあAV1のハードウェアエンコーダーがGoogle Pixel 8 以降にしか搭載されてなく、それ以外はCPUによるソフトウェアエンコーダーを使うので時間がかかるんですけど、、、

アプリ

今のところこれしか対応してません、

動画編集アプリでもやりたいところです。
↑のアプリでは自前でWebMに書き込む処理が別モジュールとして実装されているので、これをライブラリに切り出して呼び出せば良いという話はそう。

ことの始まり

いままでは面倒くさがってHEVC(使って良いのかよくわからない)のみでしたが、HEVCAV1を許可するようにコードを修正した訳とは・・!

時は2025年。Pixel 10 シリーズのカメラアプリにはAV1で保存する機能が搭載されている!!
技術的にはPixel 8の時点でハードウェアエンコーダーが搭載されたので使えるハズですが、何故かその2年後のいま、Pixel 10まで実装されませんでした。
(なお過去の端末にはバックポートされてないっぽい)

camera_app

(小声、AV1よりHEVCのが互換性が優れてる~説明はちょっと盛ってないか・・?)

で、これで撮影してみると確かにAV1でした。音声コーデックはAACで、コンテナフォーマットはMP4でした。

vlc

だから何という話ですが、このままでは負けてしまう(誰に?)と思い、
急遽AV1での10 ビット HDR 動画の調査と、MP4だけだとまだ負けると思い(何に?)、WebMに入れるための調査を行いました。
どーせ一生やらんやろって思ってたらAV1カメラ撮影機能来てしまった。

AV1 と 10 ビット HDR 動画

これは特にはないはずです。

MediaCodecAV1を指定して、そこに10 ビット HDRの映像(Camera2 APIでカメラ映像とか)を渡せば、AV1でエンコードされた10 ビット HDR 動画のデータが取得できます。
調べると仕様的にはVP9でもHDR 動画が作れるらしいんですけど、MediaCodecがエラーを返してしまうので使えませんでした。。。これをAV1にすると動くんで間違ってはないはずなんですが。

というわけでエンコーダーに関しては問題無しで、MP4に書き込む処理も特になし。
問題はWebMに書き込む方。

WebM に 10 ビット HDR 動画を保存する

保存するためには、HDR用のパラメーターが必要です。というのも、HDRにはいくつか種類があって、種類に合わせてデコーダーを起動しないと色がかすれたりします。
HLGHDR10と呼ばれてるやつですね。

どこに保存するか、は、WebMの構造の説明が必要なのでそれが分かってないと何だかわからないと思うのですが、
Colour親要素と、その中に入るMatrixCoefficientsTransferCharacteristicsPrimariesHDR 動画に必要な値のはずです。(インターネットの動画を見る限りこの3つが入ってた)

webm

キー
MatrixCoefficients9 (Rec.2020)
TransferCharacteristics18 (ガンマカーブがHLG) もしくは 16 (ガンマカーブがPQ)
Primaries9 (Rec.2020)

Androidに最初からMediaMuxerクラスがあり、同じく低レイヤーAPIであるMediaCodecがエンコードした映像・音声をMP4WebMに保存する担当を担います。
が、このアプリではMP4以外は自前でWebMを作っています。バイト配列をいじくり回してます。

WebMのパーサーを作ったんだから自前で作りたいという気持ちもありますが、どっちかと言うとMediaMuxerクラスの制約があり使えなかったが正解になります。
なんかどっかで書いたような気もしないけど。これだとAV1コーデックが保存できない(VP9はもちろん行ける)んですよね。多分AV1的にはWebMは非公式?な感じなのです。
が、ブラウザで再生できちゃうので。実質入れられるみたいな

なお再生に関してはWebM + AV1 + HDRちゃんと眩しいです。パラメーターちゃんと取れてるっぽい。そりゃそうか。

おまけ

どうやらPS5の画面録画機能ではWebM + VP9採用されているらしいです。その上HDR動画で録画出来るっぽいです。(ガンマカーブはPQ (ST2084)らしい)
持ってないので正しくは分からないです。

録画ファイルどこかからダウンロード出来たりしますかね、私も見てみたいHDRゲームプレイ録画。
録画くれるひと~

イケイケな?コーデックとコンテナを選んでいるので動画編集の際にはひと手間必要らしいです。
私のアプリはAndroidに最初からあるMP4/WebMパーサー(デマルチプレクサ)を使ってるのでいい感じに動くはずです

今回対応したのでHEVCにもできるしAV1 (mp4 か webm)にも出来ます。HDRが保持された状態で!!
HEVCが無理?じゃあAV1 + WebMで再エンコードするからChromeで開いて見て。ができます。

おわりに

Pixel 8 (2年前)(Tensor G3)Pixel 10 Pro Fold (今年)(Tensor G5)Xperia 1 VII (今年)(Snapdragon 8 Elite)でそれぞれ動作確認している写真です。
HEVC + 60fps + 10ビットHDRです。

speedtest

Pixel 8 ProPixel 10 Pro FoldXperia 1 VII

【悲報】わたしのあぷり、なぜか2世代前のPixel 8 Proのほうが速い

スマホでゲームしないのでベンチマークスコアとかには全く興味がないのですが、、、、が、なんで?だ?