rate control not quite working but committing anyway due to format change

This commit is contained in:
minjaesong
2025-08-24 13:35:08 +09:00
parent b1857e355a
commit cb07ab1f3b
4 changed files with 409 additions and 219 deletions

View File

@@ -201,8 +201,20 @@ try {
sys.memcpy(CURRENT_RGB_ADDR, PREV_RGB_ADDR, FRAME_PIXELS * 3) sys.memcpy(CURRENT_RGB_ADDR, PREV_RGB_ADDR, FRAME_PIXELS * 3)
} else if (packetType == TEV_PACKET_IFRAME || packetType == TEV_PACKET_PFRAME) { } 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() 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) let compressedPtr = seqread.readBytes(payloadLen)
updateDataRateBin(payloadLen) updateDataRateBin(payloadLen)
@@ -232,9 +244,9 @@ try {
continue continue
} }
// Hardware-accelerated TEV YCoCg-R decoding to RGB buffers // Hardware-accelerated TEV YCoCg-R decoding to RGB buffers (with rate control factor)
try { 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 // Upload RGB buffer to display framebuffer with dithering
graphics.uploadRGBToFramebuffer(CURRENT_RGB_ADDR, DISPLAY_RG_ADDR, DISPLAY_BA_ADDR, graphics.uploadRGBToFramebuffer(CURRENT_RGB_ADDR, DISPLAY_RG_ADDR, DISPLAY_BA_ADDR,

View File

@@ -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 TEV is a modern video codec optimized for TSVM's 4096-color hardware, featuring
DCT-based compression, motion compensation, and efficient temporal coding. 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 # File Structure
\x1F T S V M T E V \x1F T S V M T E V
[HEADER] [HEADER]
@@ -694,7 +700,7 @@ DCT-based compression, motion compensation, and efficient temporal coding.
uint16 Height: video height in pixels uint16 Height: video height in pixels
uint16 FPS: frames per second uint16 FPS: frames per second
uint32 Total Frames: number of video frames 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 byte[5] Reserved
## Packet Types ## Packet Types
@@ -705,7 +711,8 @@ DCT-based compression, motion compensation, and efficient temporal coding.
## Video Packet Structure ## Video Packet Structure
uint8 Packet Type 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 * Gzip-compressed Block Data
## Block Data (per 16x16 block) ## 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) int16[64] DCT Coefficients Cg (subsampled by two, aggressively quantised)
For SKIP and MOTION mode, DCT coefficients are filled with zero 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 TEV uses 8 quality levels (0=lowest, 7=highest) with progressive quantization
tables optimized for perceptual quality. DC coefficients use fixed quantizer tables optimized for perceptual quality. DC coefficients use fixed quantizer
of 8, while AC coefficients are quantized according to quality tables. 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 ## Motion Compensation
- Search range: ±8 pixels - Search range: ±8 pixels
- Sub-pixel precision: 1/4 pixel (again, integer precision for now) - Sub-pixel precision: 1/4 pixel (again, integer precision for now)

View File

@@ -1567,7 +1567,8 @@ class GraphicsJSR223Delegate(private val vm: VM) {
* @param frameCounter Frame counter for temporal patterns * @param frameCounter Frame counter for temporal patterns
*/ */
fun tevDecode(blockDataPtr: Long, currentRGBAddr: Long, prevRGBAddr: Long, 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 blocksX = (width + 15) / 16 // 16x16 blocks now
val blocksY = (height + 15) / 16 val blocksY = (height + 15) / 16
@@ -1576,9 +1577,22 @@ class GraphicsJSR223Delegate(private val vm: VM) {
val quantCOmult = QUANT_MULT_CO[quality] val quantCOmult = QUANT_MULT_CO[quality]
val quantCGmult = QUANT_MULT_CG[quality] val quantCGmult = QUANT_MULT_CG[quality]
val quantTableY = QUANT_TABLE_Y.map { it * quantYmult }.toIntArray() // Apply rate control factor to quantization tables (if not ~1.0, skip optimization)
val quantTableCo = QUANT_TABLE_C.map { it * quantCOmult }.toIntArray() val quantTableY = if (rateControlFactor in 0.999f..1.001f) {
val quantTableCg = QUANT_TABLE_C.map { it * quantCGmult }.toIntArray() 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 var readPtr = blockDataPtr

File diff suppressed because it is too large Load Diff