Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「騒ゲーハイライト」について【MIXI TECH CONFERENCE 2023】

YuukiARIA
March 02, 2023

「騒ゲーハイライト」について【MIXI TECH CONFERENCE 2023】

MIXI TECH CONFERENCE 2023 Day 1 でお話したスライドです。
https://techcon.mixi.co.jp/d1-3

YuukiARIA

March 02, 2023
Tweet

More Decks by YuukiARIA

Other Decks in Technology

Transcript

  1. ©MIXI ゲーム画面のキャプチャ CameraCaptureBridgeを使うとデリゲートを登録するだけで簡単 にキャプチャ処理を挟むことができる 15 void Execute(RenderTargetIdentifier renderTargetIdentifier, CommandBuffer commandBuffer)

    { using (new ProfilingScope(commandBuffer, _profilingSampler)) { commandBuffer.Blit(renderTargetIdentifier, _captureOutputRenderTarget, _material); } } CameraCaptureBridge.AddCaptureAction(_targetCamera, Execute);
  2. ©MIXI NV12 YUV420のピクセルフォーマットの一つ • Y-Plane と UV-Plane からなる Semi-planar 形式

    • UV-Plane では UVUV... のように並ぶ 31 Packed UV Planar Y Semi-planar YUV420のピクセルフォーマットたち • NV12 YYYY...UVUV... • NV21 YYYY...VUVU... • I420 YYYY...UU...VV... • YV12 YYYY...VV...UU...
  3. ©MIXI 音声のキャプチャ レコーダー側は音声データを受け取るのみで,録音の具体的な方法 には踏み込まない ◦ Unity Audioの場合はOnAudioFilterReadを使う ◦ CRI ADXの場合はCriAtomExOutputAnalyzerを使う

    ストブルはこちらの方法 音声はUnity C#側でリングバッファを用意して常時録音 mp4出力時にエンコーダへ音声データを書き込む 33
  4. ©MIXI OS機能のサポート • 他のアプリへファイル・テキストを共有 ◦ iOS: UIActivityViewController ◦ Android: Intent.createChooser

    • 「アルバム」へファイルを保存 ◦ iOS: PHPhotoLibrary ◦ Android: MediaStore API 36 特にiOSのアプリ内データはユーザーが触れづらいので, 外側に取り出す仕組みが必要。 もちろん開発時のデータ確認でも必要だった。
  5. ©MIXI MediaStore API • Android 10 以降で Scoped Storage が有効

    ◦ 生パスではなくコンテンツURIを介してファイルアクセス ◦ WRITE_EXTERNAL_STORAGE 権限が不要 • Android 9 以前では直接 Movies フォルダへコピー ◦ WRITE_EXTERNAL_STORAGE 権限が必要 37
  6. ©MIXI デフォルトが NV12 ではない端末がある • Zenfone 8 ◦ I420: Y,

    U, V の順の Planar 形式 • Y は正常 • U と V の取り方がかなり異なる ◦ 格子状に拡大したような状態になる 44
  7. ©MIXI 続・アライメント問題 • さらに一部の端末では16の倍数でもだめなことがある ◦ Pixel 3a XL (≧ Android

    12) • MediaCodec#getInputFormat の戻り値に含まれる stride, slice-height の値を使用する必要がある • stride, slice-height は含まれていないこともある ◦ その場合は16の倍数にアラインするのみとした 46
  8. ©MIXI 入力バッファのサイズ Y-Plane のサイズは 768 × 864 = 663,552 UV-Plane

    のサイズは 768 × 848 / 2 = 325,632 ∴計 989,184 49 問題 width = 752, height = 848 で MediaCodec を初期化したところ, 入力フォーマットに stride = 768, slice-height = 864 という値が含まれ ていた。このとき,入力バッファのサイズは何バイトか。
  9. ©MIXI 入力バッファのサイズ Y-Plane のサイズは 768 × 864 = 663,552 UV-Plane

    のサイズは 768 × 848 / 2 = 325,632 ∴計 989,184 50 問題 width = 752, height = 848 で MediaCodec を初期化したところ, 入力フォーマットに stride = 768, slice-height = 864 という値が含まれ ていた。このとき,入力バッファのサイズは何バイトか。 しかし実際には 989,169 15バイト少ない…
  10. ©MIXI パフォーマンス問題 NV12データを Unity C# から Android Java へ渡す部分 53

    byte[] frameData; AndroidJavaClass pluginClass; pluginClass.CallStatic("writeFrame", frameData); Unity 2019 vs 2020 で性能が2~3桁違う! 400,000 バイトの配列を渡してみると… Unity 2019 350 ms Unity 2020 0.5 ms (x700 faster!)