SHA256
Fix Black Fallback Frame For Failed Readbacks
This commit is contained in:
1 file changed
+32
-5
+32
-5
@@ -154,14 +154,11 @@ namespace ADOFAIRenderer.Util
|
|||||||
}
|
}
|
||||||
Melon<RenderMod>.Logger.Warning($"[OOM Prevent] GPU Readback failed for frame {frame}. Queue deadlock prevented by sending a black frame.");
|
Melon<RenderMod>.Logger.Warning($"[OOM Prevent] GPU Readback failed for frame {frame}. Queue deadlock prevented by sending a black frame.");
|
||||||
|
|
||||||
var byteSize = state.Width * state.Height * 3 / 2;
|
var blackFrame = CreateBlackFrame(state, out var byteSize);
|
||||||
var blackFrame = ArrayPool<byte>.Shared.Rent(byteSize);
|
|
||||||
Array.Clear(blackFrame, 0, byteSize);
|
|
||||||
|
|
||||||
var capFrame = new RenderManager.CapturedFrame
|
var capFrame = new RenderManager.CapturedFrame
|
||||||
{
|
{
|
||||||
ManagedBuffer = blackFrame, Length = byteSize,
|
ManagedBuffer = blackFrame, Length = byteSize,
|
||||||
IsColorConverted = true
|
IsColorConverted = state.IsGPUConversion
|
||||||
};
|
};
|
||||||
PushToQueue(frame, capFrame);
|
PushToQueue(frame, capFrame);
|
||||||
RecycleState(state);
|
RecycleState(state);
|
||||||
@@ -190,6 +187,36 @@ namespace ADOFAIRenderer.Util
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a black frame in the same format as the frames of this reader, from ArrayPool<byte>.Shared
|
||||||
|
/// (returned to the pool by the render thread after encoding).
|
||||||
|
///
|
||||||
|
/// GPU conversion (NV12 / YUV420P, full range): Width × Height × 3 / 2 bytes.
|
||||||
|
/// Y plane (Width × Height bytes) = 0, U/V data (the rest) = 128.
|
||||||
|
/// 128 is the zero chroma value of the 8-bit full range: the U/V offset 0.5 of RGB2YUV_BT709_Full
|
||||||
|
/// in ColorConversion.compute, which the encoder input of this path uses.
|
||||||
|
/// Both NV12 (interleaved UV) and YUV420P (U plane, then V plane) store all chroma after the Y plane,
|
||||||
|
/// so the same fill applies to both.
|
||||||
|
/// No GPU conversion (RGBA input, converted by the encoder): Width × Height × 4 bytes, all 0.
|
||||||
|
/// </summary>
|
||||||
|
private static byte[] CreateBlackFrame(ReadbackRequestState state, out int byteSize)
|
||||||
|
{
|
||||||
|
var lumaSize = state.Width * state.Height;
|
||||||
|
byteSize = state.IsGPUConversion ? lumaSize * 3 / 2 : lumaSize * 4;
|
||||||
|
|
||||||
|
var frame = ArrayPool<byte>.Shared.Rent(byteSize);
|
||||||
|
if (state.IsGPUConversion)
|
||||||
|
{
|
||||||
|
Array.Clear(frame, 0, lumaSize);
|
||||||
|
frame.AsSpan(lumaSize, byteSize - lumaSize).Fill(128);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array.Clear(frame, 0, byteSize);
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
internal void RecycleState(ReadbackRequestState state)
|
internal void RecycleState(ReadbackRequestState state)
|
||||||
{
|
{
|
||||||
lock (_poolLock)
|
lock (_poolLock)
|
||||||
|
|||||||
Reference in new issue
Block a user