mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-10 06:54:04 +09:00
wip6
This commit is contained in:
@@ -444,7 +444,7 @@ try {
|
|||||||
if (notifHidden) {
|
if (notifHidden) {
|
||||||
con.move(31, 1)
|
con.move(31, 1)
|
||||||
con.color_pair(253, 0)
|
con.color_pair(253, 0)
|
||||||
print(`Frame: ${frameCount}/${header.totalFrames} (${((frameCount / akku2 * 100)|0) / 100}f) `)
|
//print(`Frame: ${frameCount}/${header.totalFrames} (${((frameCount / akku2 * 100)|0) / 100}f) `)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4048,6 +4048,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
private val dwtSubbandHL = FloatArray(32 * 32)
|
private val dwtSubbandHL = FloatArray(32 * 32)
|
||||||
private val dwtSubbandHH = FloatArray(32 * 32)
|
private val dwtSubbandHH = FloatArray(32 * 32)
|
||||||
|
|
||||||
|
private var frameCounter = 0
|
||||||
/**
|
/**
|
||||||
* Main TAV decoder function - processes compressed TAV tile data
|
* Main TAV decoder function - processes compressed TAV tile data
|
||||||
* Called from JavaScript playtav.js decoder
|
* Called from JavaScript playtav.js decoder
|
||||||
@@ -4057,6 +4058,8 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
debugMotionVectors: Boolean = false, waveletFilter: Int = 1,
|
debugMotionVectors: Boolean = false, waveletFilter: Int = 1,
|
||||||
decompLevels: Int = 3, enableDeblocking: Boolean = true,
|
decompLevels: Int = 3, enableDeblocking: Boolean = true,
|
||||||
isLossless: Boolean = false) {
|
isLossless: Boolean = false) {
|
||||||
|
this.frameCounter = frameCounter
|
||||||
|
|
||||||
var readPtr = blockDataPtr
|
var readPtr = blockDataPtr
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -4077,6 +4080,11 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val rcf = vm.peekFloat(readPtr)
|
val rcf = vm.peekFloat(readPtr)
|
||||||
readPtr += 4
|
readPtr += 4
|
||||||
|
|
||||||
|
// Debug tile header for first few tiles
|
||||||
|
if ((tileX < 2 && tileY < 2) && frameCounter < 3) {
|
||||||
|
println("TAV Debug: Tile ($tileX,$tileY) frame $frameCounter - mode=0x${mode.toString(16)}, mvX=$mvX, mvY=$mvY, rcf=$rcf")
|
||||||
|
}
|
||||||
|
|
||||||
when (mode) {
|
when (mode) {
|
||||||
0x00 -> { // TAV_MODE_SKIP
|
0x00 -> { // TAV_MODE_SKIP
|
||||||
// Copy 64x64 tile from previous frame to current frame
|
// Copy 64x64 tile from previous frame to current frame
|
||||||
@@ -4173,16 +4181,51 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val coTile = FloatArray(coeffCount)
|
val coTile = FloatArray(coeffCount)
|
||||||
val cgTile = FloatArray(coeffCount)
|
val cgTile = FloatArray(coeffCount)
|
||||||
|
|
||||||
|
// Debug: check quantized values before dequantization
|
||||||
|
if (tileX == 0 && tileY == 0 && frameCounter < 3) {
|
||||||
|
println("TAV Debug: Tile (0,0) frame $frameCounter - Quantized Y coeffs (first 64):")
|
||||||
|
for (i in 0 until 8) {
|
||||||
|
for (j in 0 until 8) {
|
||||||
|
print("${quantizedY[i * 8 + j]} ")
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
println("qY=$qY, qCo=$qCo, qCg=$qCg, rcf=$rcf")
|
||||||
|
}
|
||||||
|
|
||||||
for (i in 0 until coeffCount) {
|
for (i in 0 until coeffCount) {
|
||||||
yTile[i] = quantizedY[i] * qY * rcf
|
yTile[i] = quantizedY[i] * qY * rcf
|
||||||
coTile[i] = quantizedCo[i] * qCo * rcf
|
coTile[i] = quantizedCo[i] * qCo * rcf
|
||||||
cgTile[i] = quantizedCg[i] * qCg * rcf
|
cgTile[i] = quantizedCg[i] * qCg * rcf
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply inverse DWT using 9/7 irreversible filter
|
// Apply inverse DWT using 9/7 irreversible filter with 3 decomposition levels
|
||||||
applyDWT97Inverse(yTile, tileSize, tileSize)
|
applyDWTInverseMultiLevel(yTile, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(coTile, tileSize, tileSize)
|
applyDWTInverseMultiLevel(coTile, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(cgTile, tileSize, tileSize)
|
applyDWTInverseMultiLevel(cgTile, tileSize, tileSize, 3, 1)
|
||||||
|
|
||||||
|
// DEBUG: Try replacing with reasonable test values to verify the rest of pipeline works
|
||||||
|
if (tileX == 0 && tileY == 0 && frameCounter < 3) {
|
||||||
|
println("TAV Debug: Before test override - Y[0-7]: ${yTile.sliceArray(0..7).joinToString { "%.1f".format(it) }}")
|
||||||
|
// Set reasonable test values
|
||||||
|
for (i in 0 until coeffCount) {
|
||||||
|
yTile[i] = 128.0f + (i % 32) * 2.0f // Reasonable Y values around middle gray
|
||||||
|
coTile[i] = (i % 16 - 8) * 4.0f // Small chroma values
|
||||||
|
cgTile[i] = (i % 16 - 8) * 4.0f // Small chroma values
|
||||||
|
}
|
||||||
|
println("TAV Debug: After test override - Y[0-7]: ${yTile.sliceArray(0..7).joinToString { "%.1f".format(it) }}")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug: check if we get reasonable values after DWT
|
||||||
|
if (tileX == 0 && tileY == 0 && frameCounter < 3) {
|
||||||
|
println("TAV Debug: Tile (0,0) frame $frameCounter - Y sample values after DWT:")
|
||||||
|
for (i in 0 until 8) {
|
||||||
|
for (j in 0 until 8) {
|
||||||
|
print("%.2f ".format(yTile[i * tileSize + j]))
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert YCoCg to RGB and store in buffer
|
// Convert YCoCg to RGB and store in buffer
|
||||||
convertYCoCgTileToRGB(tileX, tileY, yTile, coTile, cgTile, currentRGBAddr, width, height)
|
convertYCoCgTileToRGB(tileX, tileY, yTile, coTile, cgTile, currentRGBAddr, width, height)
|
||||||
@@ -4231,9 +4274,9 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
cgResidual[i] = quantizedCg[i] * qCg * rcf
|
cgResidual[i] = quantizedCg[i] * qCg * rcf
|
||||||
}
|
}
|
||||||
|
|
||||||
applyDWT97Inverse(yResidual, tileSize, tileSize)
|
applyDWTInverseMultiLevel(yResidual, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(coResidual, tileSize, tileSize)
|
applyDWTInverseMultiLevel(coResidual, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(cgResidual, tileSize, tileSize)
|
applyDWTInverseMultiLevel(cgResidual, tileSize, tileSize, 3, 1)
|
||||||
|
|
||||||
// Add residual to motion-compensated prediction
|
// Add residual to motion-compensated prediction
|
||||||
addYCoCgResidualToRGBTile(tileX, tileY, yResidual, coResidual, cgResidual, currentRGBAddr, width, height)
|
addYCoCgResidualToRGBTile(tileX, tileY, yResidual, coResidual, cgResidual, currentRGBAddr, width, height)
|
||||||
@@ -4586,13 +4629,13 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
|
|
||||||
// Apply inverse DWT to reconstruct tile
|
// Apply inverse DWT to reconstruct tile
|
||||||
if (waveletFilter == 0) { // 5/3 reversible
|
if (waveletFilter == 0) { // 5/3 reversible
|
||||||
applyDWT53Inverse(dequantizedY, tileSize, tileSize)
|
applyDWTInverseMultiLevel(dequantizedY, tileSize, tileSize, 3, 0)
|
||||||
applyDWT53Inverse(dequantizedCo, tileSize, tileSize)
|
applyDWTInverseMultiLevel(dequantizedCo, tileSize, tileSize, 3, 0)
|
||||||
applyDWT53Inverse(dequantizedCg, tileSize, tileSize)
|
applyDWTInverseMultiLevel(dequantizedCg, tileSize, tileSize, 3, 0)
|
||||||
} else { // 9/7 irreversible
|
} else { // 9/7 irreversible
|
||||||
applyDWT97Inverse(dequantizedY, tileSize, tileSize)
|
applyDWTInverseMultiLevel(dequantizedY, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(dequantizedCo, tileSize, tileSize)
|
applyDWTInverseMultiLevel(dequantizedCo, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(dequantizedCg, tileSize, tileSize)
|
applyDWTInverseMultiLevel(dequantizedCg, tileSize, tileSize, 3, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy reconstructed data to frame buffers
|
// Copy reconstructed data to frame buffers
|
||||||
@@ -4677,13 +4720,13 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
|
|
||||||
// Apply inverse DWT to reconstruct residual
|
// Apply inverse DWT to reconstruct residual
|
||||||
if (waveletFilter == 0) { // 5/3 reversible
|
if (waveletFilter == 0) { // 5/3 reversible
|
||||||
applyDWT53Inverse(residualY, tileSize, tileSize)
|
applyDWTInverseMultiLevel(residualY, tileSize, tileSize, 3, 0)
|
||||||
applyDWT53Inverse(residualCo, tileSize, tileSize)
|
applyDWTInverseMultiLevel(residualCo, tileSize, tileSize, 3, 0)
|
||||||
applyDWT53Inverse(residualCg, tileSize, tileSize)
|
applyDWTInverseMultiLevel(residualCg, tileSize, tileSize, 3, 0)
|
||||||
} else { // 9/7 irreversible
|
} else { // 9/7 irreversible
|
||||||
applyDWT97Inverse(residualY, tileSize, tileSize)
|
applyDWTInverseMultiLevel(residualY, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(residualCo, tileSize, tileSize)
|
applyDWTInverseMultiLevel(residualCo, tileSize, tileSize, 3, 1)
|
||||||
applyDWT97Inverse(residualCg, tileSize, tileSize)
|
applyDWTInverseMultiLevel(residualCg, tileSize, tileSize, 3, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Add residual to motion-compensated prediction
|
// Step 3: Add residual to motion-compensated prediction
|
||||||
@@ -4760,6 +4803,52 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
// Lifting scheme implementation for 9/7 irreversible filter
|
// Lifting scheme implementation for 9/7 irreversible filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun applyDWTInverseMultiLevel(data: FloatArray, width: Int, height: Int, levels: Int, filterType: Int) {
|
||||||
|
// Multi-level inverse DWT - reconstruct from smallest to largest (reverse of encoder)
|
||||||
|
val size = width // Full tile size (64)
|
||||||
|
val tempRow = FloatArray(size)
|
||||||
|
val tempCol = FloatArray(size)
|
||||||
|
|
||||||
|
for (level in levels - 1 downTo 0) {
|
||||||
|
val currentSize = size shr level
|
||||||
|
if (currentSize < 2) break
|
||||||
|
|
||||||
|
// Column transform (reverse order from encoder)
|
||||||
|
for (x in 0 until currentSize) {
|
||||||
|
for (y in 0 until currentSize) {
|
||||||
|
tempCol[y] = data[y * size + x]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterType == 0) {
|
||||||
|
applyLift53InverseVertical(tempCol, currentSize)
|
||||||
|
} else {
|
||||||
|
applyLift97InverseVertical(tempCol, currentSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y in 0 until currentSize) {
|
||||||
|
data[y * size + x] = tempCol[y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Row transform (reverse order from encoder)
|
||||||
|
for (y in 0 until currentSize) {
|
||||||
|
for (x in 0 until currentSize) {
|
||||||
|
tempRow[x] = data[y * size + x]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterType == 0) {
|
||||||
|
applyLift53InverseHorizontal(tempRow, currentSize)
|
||||||
|
} else {
|
||||||
|
applyLift97InverseHorizontal(tempRow, currentSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x in 0 until currentSize) {
|
||||||
|
data[y * size + x] = tempRow[x]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun applyDWT97Inverse(data: FloatArray, width: Int, height: Int) {
|
private fun applyDWT97Inverse(data: FloatArray, width: Int, height: Int) {
|
||||||
// 9/7 irreversible DWT inverse using lifting scheme
|
// 9/7 irreversible DWT inverse using lifting scheme
|
||||||
// First apply horizontal inverse DWT on all rows
|
// First apply horizontal inverse DWT on all rows
|
||||||
@@ -4850,49 +4939,49 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
temp[half + i] = data[2 * i + 1] // Odd samples (high-pass)
|
temp[half + i] = data[2 * i + 1] // Odd samples (high-pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9/7 inverse lifting coefficients
|
// 9/7 inverse lifting coefficients (must match encoder exactly)
|
||||||
val alpha = -1.586134342f // Inverse lifting coefficient
|
val alpha = -1.586134342f // Inverse lifting coefficient
|
||||||
val beta = -0.05298011854f // Inverse lifting coefficient
|
val beta = -0.052980118f // Inverse lifting coefficient (match encoder)
|
||||||
val gamma = 0.8829110762f // Inverse lifting coefficient
|
val gamma = 0.882911076f // Inverse lifting coefficient (match encoder)
|
||||||
val delta = 0.4435068522f // Inverse lifting coefficient
|
val delta = 0.443506852f // Inverse lifting coefficient (match encoder)
|
||||||
val K = 1.149604398f // Scaling factor
|
val K = 1.230174105f // Scaling factor (match encoder)
|
||||||
val invK = 1.0f / K
|
val invK = 1.0f / K
|
||||||
|
|
||||||
// Inverse lifting steps for 9/7 filter
|
// Inverse lifting steps for 9/7 filter (undo forward steps in reverse order)
|
||||||
// Step 4: Scale
|
// Step 5: Undo scaling
|
||||||
for (i in 0 until half) {
|
for (i in 0 until half) {
|
||||||
temp[i] *= K
|
temp[i] /= K // Undo temp[i] *= K
|
||||||
}
|
}
|
||||||
for (i in 0 until length / 2) {
|
for (i in 0 until length / 2) {
|
||||||
temp[half + i] *= invK
|
temp[half + i] *= K // Undo temp[half + i] /= K
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Undo update step
|
// Step 4: Undo update step (delta)
|
||||||
for (i in 0 until half) {
|
for (i in 0 until half) {
|
||||||
val oddPrev = if (i - 1 >= 0) temp[half + i - 1] else 0.0f
|
val left = if (i > 0) temp[half + i - 1] else temp[half + i]
|
||||||
val oddNext = if (i < length / 2) temp[half + i] else 0.0f
|
val right = if (i < half - 1) temp[half + i + 1] else temp[half + i]
|
||||||
temp[i] -= delta * (oddPrev + oddNext)
|
temp[i] -= delta * (left + right)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Undo predict step
|
// Step 3: Undo predict step (gamma)
|
||||||
for (i in 0 until length / 2) {
|
|
||||||
val evenCurr = temp[i]
|
|
||||||
val evenNext = if (i + 1 < half) temp[i + 1] else temp[half - 1]
|
|
||||||
temp[half + i] -= gamma * (evenCurr + evenNext)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Undo update step
|
|
||||||
for (i in 0 until half) {
|
for (i in 0 until half) {
|
||||||
val oddPrev = if (i - 1 >= 0) temp[half + i - 1] else 0.0f
|
val left = if (i > 0) temp[i - 1] else temp[i]
|
||||||
val oddNext = if (i < length / 2) temp[half + i] else 0.0f
|
val right = if (i < half - 1) temp[i + 1] else temp[i]
|
||||||
temp[i] -= beta * (oddPrev + oddNext)
|
temp[half + i] -= gamma * (left + right)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 0: Undo predict step
|
// Step 2: Undo update step (beta)
|
||||||
for (i in 0 until length / 2) {
|
for (i in 0 until half) {
|
||||||
val evenCurr = temp[i]
|
val left = if (i > 0) temp[half + i - 1] else temp[half + i]
|
||||||
val evenNext = if (i + 1 < half) temp[i + 1] else temp[half - 1]
|
val right = if (i < half - 1) temp[half + i + 1] else temp[half + i]
|
||||||
temp[half + i] -= alpha * (evenCurr + evenNext)
|
temp[i] -= beta * (left + right)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Undo predict step (alpha)
|
||||||
|
for (i in 0 until half) {
|
||||||
|
val left = if (i > 0) temp[i - 1] else temp[i]
|
||||||
|
val right = if (i < half - 1) temp[i + 1] else temp[i]
|
||||||
|
temp[half + i] -= alpha * (left + right)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interleave back
|
// Interleave back
|
||||||
@@ -4909,6 +4998,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
applyLift97InverseHorizontal(data, length)
|
applyLift97InverseHorizontal(data, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun bilinearInterpolate(
|
private fun bilinearInterpolate(
|
||||||
dataPtr: Long, width: Int, height: Int,
|
dataPtr: Long, width: Int, height: Int,
|
||||||
x: Float, y: Float
|
x: Float, y: Float
|
||||||
|
|||||||
Reference in New Issue
Block a user