|
|
|
@ -36,12 +36,11 @@ internal class Av1ForwardTransformer |
|
|
|
internal static void Transform2d(Span<short> input, Span<int> coefficients, uint stride, Av1TransformType transformType, Av1TransformSize transformSize, int bitDepth) |
|
|
|
{ |
|
|
|
Av1Transform2dFlipConfiguration config = new(transformType, transformSize); |
|
|
|
ref int buffer = ref TemporaryCoefficientsBuffer[0]; |
|
|
|
IAv1Forward1dTransformer? columnTransformer = GetTransformer(config.TransformFunctionTypeColumn); |
|
|
|
IAv1Forward1dTransformer? rowTransformer = GetTransformer(config.TransformFunctionTypeRow); |
|
|
|
if (columnTransformer != null && rowTransformer != null) |
|
|
|
{ |
|
|
|
Transform2dCore(columnTransformer, rowTransformer, ref input[0], stride, ref coefficients[0], config, ref buffer, bitDepth); |
|
|
|
Transform2dCore(columnTransformer, rowTransformer, input, stride, coefficients, config, TemporaryCoefficientsBuffer, bitDepth); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@ -55,7 +54,7 @@ internal class Av1ForwardTransformer |
|
|
|
/// <summary>
|
|
|
|
/// SVT: av1_tranform_two_d_core_c
|
|
|
|
/// </summary>
|
|
|
|
private static void Transform2dCore<TColumn, TRow>(TColumn transformFunctionColumn, TRow transformFunctionRow, ref short input, uint inputStride, ref int output, Av1Transform2dFlipConfiguration config, ref int buf, int bitDepth) |
|
|
|
private static void Transform2dCore<TColumn, TRow>(TColumn transformFunctionColumn, TRow transformFunctionRow, Span<short> input, uint inputStride, Span<int> output, Av1Transform2dFlipConfiguration config, Span<int> buf, int bitDepth) |
|
|
|
where TColumn : IAv1Forward1dTransformer |
|
|
|
where TRow : IAv1Forward1dTransformer |
|
|
|
{ |
|
|
|
@ -87,8 +86,13 @@ internal class Av1ForwardTransformer |
|
|
|
// ASSERT(txfm_func_col != NULL);
|
|
|
|
// ASSERT(txfm_func_row != NULL);
|
|
|
|
// use output buffer as temp buffer
|
|
|
|
ref int tempIn = ref output; |
|
|
|
ref int tempOut = ref Unsafe.Add(ref output, transformRowCount); |
|
|
|
Span<int> tempInSpan = output[..transformRowCount]; |
|
|
|
Span<int> tempOutSpan = output.Slice(transformRowCount, transformRowCount); |
|
|
|
ref int tempIn = ref tempInSpan[0]; |
|
|
|
ref int tempOut = ref tempOutSpan[0]; |
|
|
|
ref short inputRef = ref input[0]; |
|
|
|
ref int outputRef = ref output[0]; |
|
|
|
ref int bufRef = ref buf[0]; |
|
|
|
|
|
|
|
// Columns
|
|
|
|
for (c = 0; c < transformColumnCount; ++c) |
|
|
|
@ -98,7 +102,7 @@ internal class Av1ForwardTransformer |
|
|
|
uint t = (uint)c; |
|
|
|
for (r = 0; r < transformRowCount; ++r) |
|
|
|
{ |
|
|
|
Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); |
|
|
|
Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref inputRef, t); |
|
|
|
t += inputStride; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -108,20 +112,20 @@ internal class Av1ForwardTransformer |
|
|
|
for (r = 0; r < transformRowCount; ++r) |
|
|
|
{ |
|
|
|
// Flip upside down
|
|
|
|
Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref input, t); |
|
|
|
Unsafe.Add(ref tempIn, r) = Unsafe.Add(ref inputRef, t); |
|
|
|
t -= inputStride; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
RoundShiftArray(ref tempIn, transformRowCount, -shift[0]); // NM svt_av1_round_shift_array_c
|
|
|
|
transformFunctionColumn.Transform(ref tempIn, ref tempOut, cosBitColumn, stageRangeColumn); |
|
|
|
transformFunctionColumn.Transform(tempInSpan, tempOutSpan, cosBitColumn, stageRangeColumn); |
|
|
|
RoundShiftArray(ref tempOut, transformRowCount, -shift[1]); // NM svt_av1_round_shift_array_c
|
|
|
|
if (!config.FlipLeftToRight) |
|
|
|
{ |
|
|
|
int t = c; |
|
|
|
for (r = 0; r < transformRowCount; ++r) |
|
|
|
{ |
|
|
|
Unsafe.Add(ref buf, t) = Unsafe.Add(ref tempOut, r); |
|
|
|
Unsafe.Add(ref bufRef, t) = Unsafe.Add(ref tempOut, r); |
|
|
|
t += transformColumnCount; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -131,7 +135,7 @@ internal class Av1ForwardTransformer |
|
|
|
for (r = 0; r < transformRowCount; ++r) |
|
|
|
{ |
|
|
|
// flip from left to right
|
|
|
|
Unsafe.Add(ref buf, t) = Unsafe.Add(ref tempOut, r); |
|
|
|
Unsafe.Add(ref bufRef, t) = Unsafe.Add(ref tempOut, r); |
|
|
|
t += transformColumnCount; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -141,11 +145,11 @@ internal class Av1ForwardTransformer |
|
|
|
for (r = 0; r < transformRowCount; ++r) |
|
|
|
{ |
|
|
|
transformFunctionRow.Transform( |
|
|
|
ref Unsafe.Add(ref buf, r * transformColumnCount), |
|
|
|
ref Unsafe.Add(ref output, r * transformColumnCount), |
|
|
|
buf.Slice(r * transformColumnCount, transformColumnCount), |
|
|
|
output.Slice(r * transformColumnCount, transformColumnCount), |
|
|
|
cosBitRow, |
|
|
|
stageRangeRow); |
|
|
|
RoundShiftArray(ref Unsafe.Add(ref output, r * transformColumnCount), transformColumnCount, -shift[2]); |
|
|
|
RoundShiftArray(ref Unsafe.Add(ref outputRef, r * transformColumnCount), transformColumnCount, -shift[2]); |
|
|
|
|
|
|
|
if (Math.Abs(rectangleType) == 1) |
|
|
|
{ |
|
|
|
@ -154,7 +158,7 @@ internal class Av1ForwardTransformer |
|
|
|
int t = r * transformColumnCount; |
|
|
|
for (c = 0; c < transformColumnCount; ++c) |
|
|
|
{ |
|
|
|
ref int current = ref Unsafe.Add(ref output, t); |
|
|
|
ref int current = ref Unsafe.Add(ref outputRef, t); |
|
|
|
current = Av1Math.RoundShift((long)current * NewSqrt, NewSqrtBitCount); |
|
|
|
t++; |
|
|
|
} |
|
|
|
|