mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
rate control not quite working but committing anyway due to format change
This commit is contained in:
@@ -201,8 +201,20 @@ try {
|
||||
sys.memcpy(CURRENT_RGB_ADDR, PREV_RGB_ADDR, FRAME_PIXELS * 3)
|
||||
|
||||
} else if (packetType == TEV_PACKET_IFRAME || packetType == TEV_PACKET_PFRAME) {
|
||||
// Video frame packet
|
||||
// Video frame packet (always includes rate control factor)
|
||||
let payloadLen = seqread.readInt()
|
||||
|
||||
// Always read rate control factor (4 bytes, little-endian float)
|
||||
let rateFactorBytes = seqread.readBytes(4)
|
||||
let view = new DataView(new ArrayBuffer(4))
|
||||
for (let i = 0; i < 4; i++) {
|
||||
view.setUint8(i, sys.peek(rateFactorBytes + i))
|
||||
}
|
||||
let rateControlFactor = view.getFloat32(0, true) // true = little-endian
|
||||
//serial.println(`rateControlFactor = ${rateControlFactor}`)
|
||||
sys.free(rateFactorBytes)
|
||||
payloadLen -= 4 // Subtract rate factor size from payload
|
||||
|
||||
let compressedPtr = seqread.readBytes(payloadLen)
|
||||
updateDataRateBin(payloadLen)
|
||||
|
||||
@@ -232,9 +244,9 @@ try {
|
||||
continue
|
||||
}
|
||||
|
||||
// Hardware-accelerated TEV YCoCg-R decoding to RGB buffers
|
||||
// Hardware-accelerated TEV YCoCg-R decoding to RGB buffers (with rate control factor)
|
||||
try {
|
||||
graphics.tevDecode(blockDataPtr, CURRENT_RGB_ADDR, PREV_RGB_ADDR, width, height, quality, debugMotionVectors)
|
||||
graphics.tevDecode(blockDataPtr, CURRENT_RGB_ADDR, PREV_RGB_ADDR, width, height, quality, debugMotionVectors, rateControlFactor)
|
||||
|
||||
// Upload RGB buffer to display framebuffer with dithering
|
||||
graphics.uploadRGBToFramebuffer(CURRENT_RGB_ADDR, DISPLAY_RG_ADDR, DISPLAY_BA_ADDR,
|
||||
|
||||
@@ -678,6 +678,12 @@ Created by Claude on 2025-08-17
|
||||
TEV is a modern video codec optimized for TSVM's 4096-color hardware, featuring
|
||||
DCT-based compression, motion compensation, and efficient temporal coding.
|
||||
|
||||
## Version History
|
||||
- Version 2.0: YCoCg-R 4:2:0 with 16x16/8x8 DCT blocks
|
||||
- Version 2.1: Added Rate Control Factor to all video packets (breaking change)
|
||||
* Enables bitrate-constrained encoding alongside quality modes
|
||||
* All video frames now include 4-byte rate control factor after payload size
|
||||
|
||||
# File Structure
|
||||
\x1F T S V M T E V
|
||||
[HEADER]
|
||||
@@ -694,7 +700,7 @@ DCT-based compression, motion compensation, and efficient temporal coding.
|
||||
uint16 Height: video height in pixels
|
||||
uint16 FPS: frames per second
|
||||
uint32 Total Frames: number of video frames
|
||||
uint8 Quality: quantization quality (0-7, higher = better)
|
||||
uint8 Quality: quantization quality (0-4, higher = better)
|
||||
byte[5] Reserved
|
||||
|
||||
## Packet Types
|
||||
@@ -705,7 +711,8 @@ DCT-based compression, motion compensation, and efficient temporal coding.
|
||||
|
||||
## Video Packet Structure
|
||||
uint8 Packet Type
|
||||
uint32 Compressed Size
|
||||
uint32 Compressed Size (includes rate control factor size)
|
||||
float Rate Control Factor (4 bytes, little-endian)
|
||||
* Gzip-compressed Block Data
|
||||
|
||||
## Block Data (per 16x16 block)
|
||||
@@ -722,11 +729,19 @@ DCT-based compression, motion compensation, and efficient temporal coding.
|
||||
int16[64] DCT Coefficients Cg (subsampled by two, aggressively quantised)
|
||||
For SKIP and MOTION mode, DCT coefficients are filled with zero
|
||||
|
||||
## DCT Quantization
|
||||
## DCT Quantization and Rate Control
|
||||
TEV uses 8 quality levels (0=lowest, 7=highest) with progressive quantization
|
||||
tables optimized for perceptual quality. DC coefficients use fixed quantizer
|
||||
of 8, while AC coefficients are quantized according to quality tables.
|
||||
|
||||
### Rate Control Factor
|
||||
Each video frame includes a Rate Control Factor that modifies quantization:
|
||||
- Quality mode: Factor = 1.0 (fixed quantization based on quality level)
|
||||
- Bitrate mode: Factor varies per frame based on content complexity and target bitrate
|
||||
- Encoder: quantized_coeff = dct_coeff / (base_quant * rate_factor)
|
||||
- Decoder: dequantized_coeff = quantized_coeff * (base_quant / rate_factor)
|
||||
- Optimization: When factor ≈ 1.0 (0.999-1.001), decoder uses original tables
|
||||
|
||||
## Motion Compensation
|
||||
- Search range: ±8 pixels
|
||||
- Sub-pixel precision: 1/4 pixel (again, integer precision for now)
|
||||
|
||||
@@ -1567,7 +1567,8 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
||||
* @param frameCounter Frame counter for temporal patterns
|
||||
*/
|
||||
fun tevDecode(blockDataPtr: Long, currentRGBAddr: Long, prevRGBAddr: Long,
|
||||
width: Int, height: Int, quality: Int, debugMotionVectors: Boolean = false) {
|
||||
width: Int, height: Int, quality: Int, debugMotionVectors: Boolean = false,
|
||||
rateControlFactor: Float = 1.0f) {
|
||||
|
||||
val blocksX = (width + 15) / 16 // 16x16 blocks now
|
||||
val blocksY = (height + 15) / 16
|
||||
@@ -1576,9 +1577,22 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
||||
val quantCOmult = QUANT_MULT_CO[quality]
|
||||
val quantCGmult = QUANT_MULT_CG[quality]
|
||||
|
||||
val quantTableY = QUANT_TABLE_Y.map { it * quantYmult }.toIntArray()
|
||||
val quantTableCo = QUANT_TABLE_C.map { it * quantCOmult }.toIntArray()
|
||||
val quantTableCg = QUANT_TABLE_C.map { it * quantCGmult }.toIntArray()
|
||||
// Apply rate control factor to quantization tables (if not ~1.0, skip optimization)
|
||||
val quantTableY = if (rateControlFactor in 0.999f..1.001f) {
|
||||
QUANT_TABLE_Y.map { it * quantYmult }.toIntArray()
|
||||
} else {
|
||||
QUANT_TABLE_Y.map { (it * quantYmult * rateControlFactor).toInt() }.toIntArray()
|
||||
}
|
||||
val quantTableCo = if (rateControlFactor in 0.999f..1.001f) {
|
||||
QUANT_TABLE_C.map { it * quantCOmult }.toIntArray()
|
||||
} else {
|
||||
QUANT_TABLE_C.map { (it * quantCOmult * rateControlFactor).toInt() }.toIntArray()
|
||||
}
|
||||
val quantTableCg = if (rateControlFactor in 0.999f..1.001f) {
|
||||
QUANT_TABLE_C.map { it * quantCGmult }.toIntArray()
|
||||
} else {
|
||||
QUANT_TABLE_C.map { (it * quantCGmult * rateControlFactor).toInt() }.toIntArray()
|
||||
}
|
||||
|
||||
var readPtr = blockDataPtr
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user