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.");
|
||||
|
||||
var byteSize = state.Width * state.Height * 3 / 2;
|
||||
var blackFrame = ArrayPool<byte>.Shared.Rent(byteSize);
|
||||
Array.Clear(blackFrame, 0, byteSize);
|
||||
|
||||
var blackFrame = CreateBlackFrame(state, out var byteSize);
|
||||
var capFrame = new RenderManager.CapturedFrame
|
||||
{
|
||||
ManagedBuffer = blackFrame, Length = byteSize,
|
||||
IsColorConverted = true
|
||||
IsColorConverted = state.IsGPUConversion
|
||||
};
|
||||
PushToQueue(frame, capFrame);
|
||||
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)
|
||||
{
|
||||
lock (_poolLock)
|
||||
|
||||
Reference in new issue
Block a user