0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】【続編】360°動画の再生速度を変化させたら、またメモリリークが発生した話

Posted at

🏁 はじめに

前回の記事(【Unity】VideoPlayerで発生するメモリリークを徹底検証してみた)では、
2D再生時に発生していたメモリリークを特定・改善し、安定動作を確認できました。

しかし今回、動画の再生速度を動的に変更したところ、
再びメモリリークが発生していることを確認しました。
特に、パーティクル演出をONにした状態で発生頻度が高まる傾向が見られました。

💻 検証環境

項目 内容
Unity 6.0(2025)
動画形式 360°動画(単眼・両眼)および2D動画
表示方式 MeshRendererを使用(Skyboxは未使用)
カメラ構成 単眼/両眼(LeftCam・RightCam)
エフェクト Particle System(ON/OFFで比較)
動画時間 約5分
実行環境 Unity Editor上でシミュレーション実行

📸 現象の概要

  • 動画の再生速度を変化(遅く/速く)させる操作を繰り返すと、メモリリークが発生します
  • 再生速度を変更しない場合は、メモリリークは発生しません
  • 発生頻度は「2D > 360°両眼 > 360°単眼」の順です
  • パーティクル演出をONにしている場合、発生が顕著です
  • 下記のように、頻繁に警告が、まれにエラーが出力されます

⚠️ 発生する警告・エラー内容

前回と同様の警告に加え、稀にエラーも出力されます。

[Warning] Internal: JobTempAlloc has allocations that are more than the maximum lifespan of 4 frames old - this is not allowed and likely a leak
[Warning] To Debug, run app with -diag-job-temp-memory-leak-validation cmd line argument.
[Error] Invalid memory pointer was detected in ThreadsafeLinearAllocator::Deallocate!

再生速度を変更するたびにメモリ使用量が少しずつ増加し、これらの警告が継続的に出力されます。
アプリが落ちることはありませんが、長時間実行するとメモリが圧迫されていく挙動が見られます。

🔬 再現条件まとめ

条件 メモリリーク発生 備考
2D+パーティクルOFF+速度固定 なし 安定動作
2D+パーティクルON+速度変更 あり 最も発生頻度が高い
360°単眼+パーティクルON+速度変更 あり 最も発生頻度は低い
360°両眼+パーティクルON+速度変更 あり 頻度は中程度

🧠 現時点での考察

  • VideoPlayer.playbackSpeed を頻繁に変更することで、内部バッファやデコードキャッシュが再生成され、古いリソースが解放されずに残存している可能性があります
  • パーティクル描画との併用時に RenderTextureの解放漏れ が起きているように見えます
  • 両眼表示時はCameraが増えるため、GPUリソース競合によって発生タイミングが変化していると思われます

🧩 実施した暫定対策と結果

今回のメモリリークは、動画再生+パーティクル描画+再生速度の変更という複合条件下で発生しました。
根本解決には至っていませんが、以下3つの対策を実施しました。


① 「ScreenのMaterial Override」を廃止し、RenderTextureを使用

■ 背景

従来はVideoPlayerの出力先をオブジェクトのマテリアルに直接設定していました。
しかし、再生速度を頻繁に変更する場合、この方法ではテクスチャ参照の再割り当てが頻発し、GPUメモリ上でRenderTextureが再生成され続けることがあると考えられます。

■ 実施内容

  • VideoPlayerのRender Modeを「Render Texture」に設定
  • 出力先に専用のRenderTexture(例:Video RT)を指定
  • RenderTextureの設定を以下のように調整しました
項目 設定値 補足
Dimension 2D 通常の動画描画に十分です。
Size 2D表示時:1280×720 / 360°表示時:1536×768 2D時は画質とメモリのバランスを考慮。360°動画では全方位表示のため、横幅をやや広く設定しています
Anti-aliasing None 不要です
Color Format R16G16B16A16_SFloat HDR素材対応(通常はDefaultでも可)
Depth Stencil Format D16_UNORM 最小限の深度バッファ
MipMap OFF 不要(動画では縮小描画しないため)
Dynamic Scaling OFF(重要) 再生速度を頻繁に変更するため。Dynamic ScalingがONだと、サイズ変更のたびにGPUリソースが再確保され、リークを誘発する恐れがあります
Random Write ON ポストプロセスやパーティクルとの併用を考慮
Wrap Mode Clamp 継ぎ目アーティファクト防止
Filter Mode Bilinear 滑らかに見せたい場合に適当
Shadow Sampling Mode None 不要です

⚠️「RenderTextures with depth are forced to have an Aniso Level of 0」という警告が出ても問題ありません。深度を持つRenderTextureではAniso設定が無効化される仕様です。

■ 効果

  • メモリ使用量の上昇ペースが大幅に緩やかになりました
  • 再生速度変更を繰り返しても、警告発生までの時間が延びました
    RenderTextureを明示的に管理することで、暗黙的な再生成が減少したと考えられます

② パーティクルのLifetimeを短くする

■ 背景

Particle Systemでは、各パーティクルが生存している間、
頂点情報や描画バッファを保持します。
Lifetimeが長いと、生成と破棄のバランスが崩れ、
一時的なGPUメモリが滞留しやすくなると思われます。

■ 実施内容

  • 「Start Lifetime」を3秒 → 1秒に短縮しました
  • パーティクル数やEmission設定は変更していません

■ 効果

  • メモリリーク発生頻度が減少しました
  • 警告発生までの時間が延びました
    パーティクルの生存期間短縮により、GPUメモリ解放が早まり、蓄積が緩和したと考えられます。

③ VideoPlayerの「Skip On Drop」をTrue(デフォルト)のままとする

■ 背景

「Skip On Drop」は、処理落ち時に古いフレームをスキップして再生を追いつかせる機能です。
Falseにすると、すべてのフレームを描画しようとするため、再生遅延やメモリ滞留が起きやすくなります。

■ 設定理由

今回の環境では、動画の再生速度を頻繁に変更するため、
フレームスキップを許可しておく方が、タイミング管理上は安定します。
メモリリークに対して多少の効果がある可能性もありますが、
処理の安定性を優先し、True(デフォルト設定)のままとしました。

■ 所感

  • 再生タイミングが比較的安定し、カクつきが減少しました
  • フレーム蓄積による一時的な負荷上昇は抑えられたように見えます
    再生速度を頻繁に変化させるケースでは、Skip On DropをTrueに保つ方が現実的だと思われます。

🧾 まとめ

再生速度を変化させた際にメモリリークが再発することを確認しました。
特にパーティクルON時に顕著で、2D表示時が最も再現しやすい結果でした。

今回は、再生速度変更時に再び発生したメモリリークの挙動と、
それに対して実施した暫定的な対策をまとめました。

同じ症状に悩んでいる方の助けになれば幸いです。

RenderTextureの明示管理と負荷軽減策により、リーク発生頻度は下がりましたが、依然として VideoPlayer内部のメモリアロケータ(ThreadsafeLinearAllocator)まわり に問題が残っている可能性があります。ご注意ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?