Add Render Cleanup Logic

This commit is contained in:
copecone committed 2026-05-30 05:49:28 +09:00
1 parent 459b2f3b0e
commit f4062912a0
3 files changed
+143 -7

No files matched your search

+83 -3
View File
@@ -88,6 +88,8 @@ namespace ADOFAIRenderer.Core
public long wonFrame = -1;
// Private Instance Fields
private VideoFFmpeg? _activeVideoFFmpeg;
private readonly List<VideoFFmpeg> _allVideoFFmpegInstances = new List<VideoFFmpeg>();
private int _originalInputOffset;
private GameObject? _debugMonitorObj;
private GameObject? _escapeHandlerObj;
@@ -99,6 +101,49 @@ namespace ADOFAIRenderer.Core
Instance = this;
}
private void OnDestroy()
{
CleanUpActiveRender();
}
public void CleanUpActiveRender()
{
isRendering = isCapturing = false;
isRenderCancelled = true;
if (_activeVideoFFmpeg != null)
{
Melon<RenderMod>.Logger.Msg("게임 종료 또는 RenderManager 파괴 감지: FFmpeg 렌더 프로세스를 강제 종료합니다.");
_activeVideoFFmpeg.Kill();
_activeVideoFFmpeg = null;
}
lock (_allVideoFFmpegInstances)
{
if (_allVideoFFmpegInstances.Count > 0)
{
Melon<RenderMod>.Logger.Msg($"게임 종료 감지: 생성된 모든 FFmpeg 프로세스({_allVideoFFmpegInstances.Count}개)를 강제 수거 및 종료합니다.");
foreach (var instance in _allVideoFFmpegInstances)
{
try
{
instance.Kill();
}
catch
{
// Ignore
}
}
_allVideoFFmpegInstances.Clear();
}
}
if (RenderThread is { IsAlive: true })
{
RenderThread.Join(200);
}
}
private void Update()
{
if (_renderSetup && ADOBase.lm)
@@ -405,13 +450,19 @@ namespace ADOFAIRenderer.Core
RenderThread = new Thread(() =>
{
VideoFFmpeg? videoFFmpeg = null;
try
{
var effectiveVideoFps = Math.Min(videoFps, targetFps);
var videoFFmpeg = new VideoFFmpeg(Configuration.RenderWidth, Configuration.RenderHeight, effectiveVideoFps, videoFps, selectedCodec);
videoFFmpeg = new VideoFFmpeg(Configuration.RenderWidth, Configuration.RenderHeight, effectiveVideoFps, videoFps, selectedCodec);
SetupCaptureDirectory();
_activeVideoFFmpeg = videoFFmpeg;
lock (_allVideoFFmpegInstances)
{
_allVideoFFmpegInstances.Add(videoFFmpeg);
}
videoFFmpeg.Start(_currentOutPath, bitrate);
while (true)
@@ -464,12 +515,35 @@ namespace ADOFAIRenderer.Core
Thread.Sleep(1);
}
videoFFmpeg.Close();
endSuccessful = true;
if (isRenderCancelled)
{
videoFFmpeg.Kill();
}
else
{
videoFFmpeg.Close();
}
lock (_allVideoFFmpegInstances)
{
_allVideoFFmpegInstances.Remove(videoFFmpeg);
}
_activeVideoFFmpeg = null;
endSuccessful = !isRenderCancelled;
}
catch (Exception ex)
{
Melon<RenderMod>.Logger.Error($"FFmpeg 렌더링 스레드 오류: {ex}");
_activeVideoFFmpeg?.Kill();
if (videoFFmpeg != null)
{
lock (_allVideoFFmpegInstances)
{
_allVideoFFmpegInstances.Remove(videoFFmpeg);
}
}
_activeVideoFFmpeg = null;
}
})
{
@@ -511,6 +585,12 @@ namespace ADOFAIRenderer.Core
{
Melon<RenderMod>.Logger.Error("렌더링이 실패했거나 취소되었습니다. 상태 및 리소스를 안전하게 청소합니다.");
if (_activeVideoFFmpeg != null)
{
_activeVideoFFmpeg.Kill();
_activeVideoFFmpeg = null;
}
// 1. 메모리 누수 방지: 큐에 렌트된 임시 프레임 버퍼 풀 반환 및 클리어
lock (ImageQueue)
{