more aggressive and asymmetrical Chroma compression

This commit is contained in:
minjaesong
2025-08-22 23:12:56 +09:00
parent b720e786a9
commit 3c135e48e0
3 changed files with 331 additions and 162 deletions

View File

@@ -688,7 +688,7 @@ DCT-based compression, motion compensation, and efficient temporal coding.
## Header (24 bytes)
uint8 Magic[8]: "\x1FTSVM TEV"
uint8 Version: 1
uint8 Version: 2
uint8 Flags: bit 0 = has audio
uint16 Width: video width in pixels
uint16 Height: video height in pixels
@@ -708,16 +708,19 @@ DCT-based compression, motion compensation, and efficient temporal coding.
uint32 Compressed Size
* Gzip-compressed Block Data
## Block Data (per 8x8/16x16 block)
## Block Data (per 16x16 block)
uint8 Mode: encoding mode
0x00 = SKIP (copy from previous frame)
0x01 = INTRA (DCT-coded, no prediction)
0x02 = INTER (DCT-coded with motion compensation)
0x02 = INTER (DCT-coded with motion compensation) -- currently unused due to bugs
0x03 = MOTION (motion vector only)
int16 Motion Vector X (1/4 pixel precision)
int16 Motion Vector Y (1/4 pixel precision)
int16 Motion Vector X ("capable of" 1/4 pixel precision, integer precision for now)
int16 Motion Vector Y ("capable of" 1/4 pixel precision, integer precision for now)
uint16 Coded Block Pattern (which 8x8 have non-zero coeffs)
int16 DCT Coefficients[3][64]: quantized R,G,B transform coefficients
int16[256] DCT Coefficients Y
int16[64] DCT Coefficients Co (subsampled by two)
int16[64] DCT Coefficients Cg (subsampled by two, aggressively quantised)
For SKIP and MOTION mode, DCT coefficients are filled with zero
## DCT Quantization
TEV uses 8 quality levels (0=lowest, 7=highest) with progressive quantization
@@ -725,9 +728,9 @@ tables optimized for perceptual quality. DC coefficients use fixed quantizer
of 8, while AC coefficients are quantized according to quality tables.
## Motion Compensation
- Search range: ±16 pixels
- Sub-pixel precision: 1/4 pixel
- Block size: 8x8 pixels
- Search range: ±8 pixels
- Sub-pixel precision: 1/4 pixel (again, integer precision for now)
- Block size: 16x16 pixels
- Uses Sum of Absolute Differences (SAD) for motion estimation
- Bilinear interpolation for sub-pixel motion vectors

View File

@@ -1419,87 +1419,173 @@ class GraphicsJSR223Delegate(private val vm: VM) {
)
)
// Quality settings for quantization (Chroma channels - 8x8)
var QUANT_TABLES_C: Array<IntArray> = arrayOf( // Quality 0 (lowest)
// Quality settings for quantization (Co channel - orange-blue, 8x8)
var QUANT_TABLES_CO: Array<IntArray> = arrayOf( // Quality 0 (lowest) - 2x more aggressive than Co
intArrayOf(
120, 90, 75, 120, 180, 255, 255, 255,
83, 90, 105, 143, 195, 255, 255, 255,
105, 98, 120, 180, 255, 255, 255, 255,
105, 128, 165, 218, 255, 255, 255, 255,
135, 165, 255, 255, 255, 255, 255, 255,
180, 255, 255, 255, 255, 255, 255, 255,
240, 180, 150, 240, 255, 255, 255, 255,
166, 180, 210, 255, 255, 255, 255, 255,
210, 196, 240, 255, 255, 255, 255, 255,
210, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 1
), // Quality 1 - 1.8x more aggressive
intArrayOf(
60, 45, 38, 60, 90, 150, 192, 225,
42, 45, 53, 72, 98, 192, 225, 255,
53, 49, 60, 90, 150, 192, 225, 255,
53, 64, 83, 109, 192, 225, 255, 255,
68, 83, 139, 192, 225, 255, 255, 255,
90, 132, 192, 225, 255, 255, 255, 255,
185, 192, 225, 255, 255, 255, 255, 255,
192, 225, 255, 255, 255, 255, 255, 255
), // Quality 2
108, 81, 68, 108, 162, 255, 255, 255,
76, 81, 95, 130, 176, 255, 255, 255,
95, 88, 108, 162, 255, 255, 255, 255,
95, 115, 149, 196, 255, 255, 255, 255,
122, 149, 250, 255, 255, 255, 255, 255,
162, 238, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 2 - 1.7x more aggressive
intArrayOf(
30, 23, 19, 30, 45, 75, 96, 113,
21, 23, 27, 36, 49, 96, 113, 135,
27, 25, 30, 45, 75, 96, 113, 135,
27, 32, 42, 55, 96, 113, 135, 150,
34, 42, 70, 96, 113, 135, 150, 165,
45, 66, 96, 113, 135, 150, 165, 180,
93, 96, 113, 135, 150, 165, 180, 188,
96, 113, 135, 150, 165, 180, 188, 192
), // Quality 3
51, 39, 32, 51, 77, 128, 163, 192,
36, 39, 46, 61, 83, 163, 192, 230,
46, 43, 51, 77, 128, 163, 192, 230,
46, 54, 71, 94, 163, 192, 230, 255,
58, 71, 119, 163, 192, 230, 255, 255,
77, 112, 163, 192, 230, 255, 255, 255,
158, 163, 192, 230, 255, 255, 255, 255,
163, 192, 230, 255, 255, 255, 255, 255
), // Quality 3 - 1.6x more aggressive
intArrayOf(
24, 18, 15, 24, 36, 60, 77, 90,
17, 18, 21, 29, 39, 77, 90, 108,
21, 20, 24, 36, 60, 77, 90, 108,
21, 26, 33, 44, 77, 90, 108, 120,
27, 33, 56, 77, 90, 108, 120, 132,
36, 53, 77, 90, 108, 120, 132, 144,
74, 77, 90, 108, 120, 132, 144, 150,
77, 90, 108, 120, 132, 144, 150, 154
), // Quality 4
38, 29, 24, 38, 58, 96, 123, 144,
27, 29, 34, 46, 62, 123, 144, 173,
34, 32, 38, 58, 96, 123, 144, 173,
34, 42, 53, 70, 123, 144, 173, 192,
43, 53, 90, 123, 144, 173, 192, 211,
58, 85, 123, 144, 173, 192, 211, 230,
118, 123, 144, 173, 192, 211, 230, 240,
123, 144, 173, 192, 211, 230, 240, 246
), // Quality 4 - 1.5x more aggressive
intArrayOf(
18, 14, 12, 18, 27, 45, 57, 68,
13, 14, 16, 22, 30, 57, 68, 81,
16, 15, 18, 27, 45, 57, 68, 81,
16, 20, 25, 33, 57, 68, 81, 90,
20, 25, 42, 57, 68, 81, 90, 99,
27, 39, 57, 68, 81, 90, 99, 108,
56, 57, 68, 81, 90, 99, 108, 113,
57, 68, 81, 90, 99, 108, 113, 116
), // Quality 5
27, 21, 18, 27, 41, 68, 86, 102,
20, 21, 24, 33, 45, 86, 102, 122,
24, 23, 27, 41, 68, 86, 102, 122,
24, 30, 38, 50, 86, 102, 122, 135,
30, 38, 63, 86, 102, 122, 135, 149,
41, 59, 86, 102, 122, 135, 149, 162,
84, 86, 102, 122, 135, 149, 162, 170,
86, 102, 122, 135, 149, 162, 170, 174
), // Quality 5 - 1.4x more aggressive
intArrayOf(
15, 11, 9, 15, 23, 38, 48, 57,
11, 11, 13, 18, 24, 48, 57, 68,
13, 12, 15, 23, 38, 48, 57, 68,
13, 16, 21, 28, 48, 57, 68, 75,
17, 21, 35, 48, 57, 68, 75, 83,
23, 33, 48, 57, 68, 75, 83, 90,
46, 48, 57, 68, 75, 83, 90, 94,
48, 57, 68, 75, 83, 90, 94, 96
), // Quality 6
21, 15, 13, 21, 32, 53, 67, 80,
15, 15, 18, 25, 34, 67, 80, 95,
18, 17, 21, 32, 53, 67, 80, 95,
18, 22, 29, 39, 67, 80, 95, 105,
24, 29, 49, 67, 80, 95, 105, 116,
32, 46, 67, 80, 95, 105, 116, 126,
64, 67, 80, 95, 105, 116, 126, 132,
67, 80, 95, 105, 116, 126, 132, 134
), // Quality 6 - 1.3x more aggressive
intArrayOf(
12, 9, 8, 12, 18, 30, 39, 45,
9, 9, 11, 14, 20, 39, 45, 54,
11, 10, 12, 18, 30, 39, 45, 54,
11, 13, 17, 22, 39, 45, 54, 60,
14, 17, 28, 39, 45, 54, 60, 66,
18, 26, 39, 45, 54, 60, 66, 72,
38, 39, 45, 54, 60, 66, 72, 75,
39, 45, 54, 60, 66, 72, 75, 77
), // Quality 7 (highest)
16, 12, 10, 16, 23, 39, 51, 59,
12, 12, 14, 18, 26, 51, 59, 70,
14, 13, 16, 23, 39, 51, 59, 70,
14, 17, 22, 29, 51, 59, 70, 78,
18, 22, 36, 51, 59, 70, 78, 86,
23, 34, 51, 59, 70, 78, 86, 94,
49, 51, 59, 70, 78, 86, 94, 98,
51, 59, 70, 78, 86, 94, 98, 100
), // Quality 7 (highest) - 1.2x more aggressive for subtle improvement
intArrayOf(
1, 1, 1, 1, 1, 2, 2, 3,
1, 1, 1, 1, 2, 2, 3, 4,
1, 1, 1, 2, 2, 3, 4, 5,
1, 1, 2, 2, 3, 4, 5, 6,
1, 2, 2, 3, 4, 5, 6, 7,
2, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9, 10
1, 1, 1, 1, 1, 2, 2, 4,
1, 1, 1, 1, 2, 3, 4, 5,
1, 1, 1, 2, 3, 4, 5, 6,
1, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 10,
3, 4, 5, 6, 7, 8, 10, 11,
4, 5, 6, 7, 8, 10, 11, 12
)
)
// Quality settings for quantization (Cg channel - green-magenta, much more aggressive than Co)
// Similar to NTSC Q channel reduction - exploit reduced human sensitivity to green-magenta
// Now using 3x-5x more aggressive quantization, similar to actual NTSC Q bandwidth reduction
var QUANT_TABLES_CG: Array<IntArray> = arrayOf( // Quality 0 (lowest) - 5x more aggressive than Co, maximum compression
intArrayOf(
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 1 - 4.5x more aggressive, very low bandwidth
intArrayOf(
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 2 - 4x more aggressive, preserve only DC and very low frequencies
intArrayOf(
120, 180, 240, 255, 255, 255, 255, 255,
180, 240, 255, 255, 255, 255, 255, 255,
240, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 3 - 3.5x more aggressive, basic low frequency preservation
intArrayOf(
84, 108, 144, 192, 255, 255, 255, 255,
108, 144, 192, 255, 255, 255, 255, 255,
144, 192, 255, 255, 255, 255, 255, 255,
192, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 4 - 3x more aggressive, moderate compression
intArrayOf(
54, 72, 96, 128, 180, 255, 255, 255,
72, 96, 128, 180, 255, 255, 255, 255,
96, 128, 180, 255, 255, 255, 255, 255,
128, 180, 255, 255, 255, 255, 255, 255,
180, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 5 - 2.8x more aggressive, balanced compression
intArrayOf(
42, 56, 75, 100, 140, 200, 255, 255,
56, 75, 100, 140, 200, 255, 255, 255,
75, 100, 140, 200, 255, 255, 255, 255,
100, 140, 200, 255, 255, 255, 255, 255,
140, 200, 255, 255, 255, 255, 255, 255,
200, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 6 - 2.5x more aggressive, good quality but still compressed
intArrayOf(
30, 40, 54, 72, 100, 144, 200, 255,
40, 54, 72, 100, 144, 200, 255, 255,
54, 72, 100, 144, 200, 255, 255, 255,
72, 100, 144, 200, 255, 255, 255, 255,
100, 144, 200, 255, 255, 255, 255, 255,
144, 200, 255, 255, 255, 255, 255, 255,
200, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
), // Quality 7 (highest) - 2x more aggressive, preserve more detail
intArrayOf(
2, 3, 4, 6, 8, 12, 16, 20,
3, 4, 6, 8, 12, 16, 20, 24,
4, 6, 8, 12, 16, 20, 24, 28,
6, 8, 12, 16, 20, 24, 28, 32,
8, 12, 16, 20, 24, 28, 32, 36,
12, 16, 20, 24, 28, 32, 36, 40,
16, 20, 24, 28, 32, 36, 40, 44,
20, 24, 28, 32, 36, 40, 44, 48
)
)
@@ -1772,7 +1858,8 @@ class GraphicsJSR223Delegate(private val vm: VM) {
val blocksY = (height + 15) / 16
val quantTableY = QUANT_TABLES_Y[quality]
val quantTableC = QUANT_TABLES_C[quality]
val quantTableCo = QUANT_TABLES_CO[quality]
val quantTableCg = QUANT_TABLES_CG[quality]
var readPtr = blockDataPtr
@@ -1909,8 +1996,8 @@ class GraphicsJSR223Delegate(private val vm: VM) {
// Perform hardware IDCT for each channel using fast algorithm
val yBlock = tevIdct16x16_fast(yCoeffs, quantTableY)
val coBlock = tevIdct8x8_fast(coCoeffs, quantTableC, true)
val cgBlock = tevIdct8x8_fast(cgCoeffs, quantTableC, true)
val coBlock = tevIdct8x8_fast(coCoeffs, quantTableCo, true)
val cgBlock = tevIdct8x8_fast(cgCoeffs, quantTableCg, true)
// Convert YCoCg-R to RGB
val rgbData = tevYcocgToRGB(yBlock, coBlock, cgBlock)
@@ -1965,8 +2052,8 @@ class GraphicsJSR223Delegate(private val vm: VM) {
// Step 2: Decode residual DCT
val yResidual = tevIdct16x16_fast(yCoeffs, quantTableY)
val coResidual = tevIdct8x8_fast(coCoeffs, quantTableC, true)
val cgResidual = tevIdct8x8_fast(cgCoeffs, quantTableC, true)
val coResidual = tevIdct8x8_fast(coCoeffs, quantTableCo, true)
val cgResidual = tevIdct8x8_fast(cgCoeffs, quantTableCg, true)
// Step 3: Build motion-compensated YCoCg-R block and add residuals
val finalY = IntArray(256)

View File

@@ -173,80 +173,158 @@ static const uint8_t QUANT_TABLES_Y[8][256] = {
14, 15, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 26, 27}
};
// Quality settings for quantization (Chroma channels - 8x8)
static const uint8_t QUANT_TABLES_C[8][64] = {
// Quality 0 (lowest)
{120, 90, 75, 120, 180, 255, 255, 255,
83, 90, 105, 143, 195, 255, 255, 255,
105, 98, 120, 180, 255, 255, 255, 255,
105, 128, 165, 218, 255, 255, 255, 255,
135, 165, 255, 255, 255, 255, 255, 255,
180, 255, 255, 255, 255, 255, 255, 255,
// Quality settings for quantization (Co channel - 8x8)
static const uint8_t QUANT_TABLES_CO[8][64] = {
// Quality 0 (lowest) - 2x more aggressive than before
{240, 180, 150, 240, 255, 255, 255, 255,
166, 180, 210, 255, 255, 255, 255, 255,
210, 196, 240, 255, 255, 255, 255, 255,
210, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 1
{60, 45, 38, 60, 90, 150, 192, 225,
42, 45, 53, 72, 98, 192, 225, 255,
53, 49, 60, 90, 150, 192, 225, 255,
53, 64, 83, 109, 192, 225, 255, 255,
68, 83, 139, 192, 225, 255, 255, 255,
90, 132, 192, 225, 255, 255, 255, 255,
185, 192, 225, 255, 255, 255, 255, 255,
192, 225, 255, 255, 255, 255, 255, 255},
// Quality 2
{30, 23, 19, 30, 45, 75, 96, 113,
21, 23, 27, 36, 49, 96, 113, 135,
27, 25, 30, 45, 75, 96, 113, 135,
27, 32, 42, 55, 96, 113, 135, 150,
34, 42, 70, 96, 113, 135, 150, 165,
45, 66, 96, 113, 135, 150, 165, 180,
93, 96, 113, 135, 150, 165, 180, 188,
96, 113, 135, 150, 165, 180, 188, 192},
// Quality 3
{24, 18, 15, 24, 36, 60, 77, 90,
17, 18, 21, 29, 39, 77, 90, 108,
21, 20, 24, 36, 60, 77, 90, 108,
21, 26, 33, 44, 77, 90, 108, 120,
27, 33, 56, 77, 90, 108, 120, 132,
36, 53, 77, 90, 108, 120, 132, 144,
74, 77, 90, 108, 120, 132, 144, 150,
77, 90, 108, 120, 132, 144, 150, 154},
// Quality 4
{18, 14, 12, 18, 27, 45, 57, 68,
13, 14, 16, 22, 30, 57, 68, 81,
16, 15, 18, 27, 45, 57, 68, 81,
16, 20, 25, 33, 57, 68, 81, 90,
20, 25, 42, 57, 68, 81, 90, 99,
27, 39, 57, 68, 81, 90, 99, 108,
56, 57, 68, 81, 90, 99, 108, 113,
57, 68, 81, 90, 99, 108, 113, 116},
// Quality 5
{15, 11, 9, 15, 23, 38, 48, 57,
11, 11, 13, 18, 24, 48, 57, 68,
13, 12, 15, 23, 38, 48, 57, 68,
13, 16, 21, 28, 48, 57, 68, 75,
17, 21, 35, 48, 57, 68, 75, 83,
23, 33, 48, 57, 68, 75, 83, 90,
46, 48, 57, 68, 75, 83, 90, 94,
48, 57, 68, 75, 83, 90, 94, 96},
// Quality 6
{12, 9, 8, 12, 18, 30, 39, 45,
9, 9, 11, 14, 20, 39, 45, 54,
11, 10, 12, 18, 30, 39, 45, 54,
11, 13, 17, 22, 39, 45, 54, 60,
14, 17, 28, 39, 45, 54, 60, 66,
18, 26, 39, 45, 54, 60, 66, 72,
38, 39, 45, 54, 60, 66, 72, 75,
39, 45, 54, 60, 66, 72, 75, 77},
// Quality 7 (highest) - much finer quantization for better quality
{1, 1, 1, 1, 1, 2, 2, 3,
1, 1, 1, 1, 2, 2, 3, 4,
1, 1, 1, 2, 2, 3, 4, 5,
1, 1, 2, 2, 3, 4, 5, 6,
1, 2, 2, 3, 4, 5, 6, 7,
2, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9, 10}
// Quality 1 - 1.8x more aggressive
{108, 81, 68, 108, 162, 255, 255, 255,
76, 81, 95, 130, 176, 255, 255, 255,
95, 88, 108, 162, 255, 255, 255, 255,
95, 115, 149, 196, 255, 255, 255, 255,
122, 149, 250, 255, 255, 255, 255, 255,
162, 238, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 2 - 1.7x more aggressive
{51, 39, 32, 51, 77, 128, 163, 192,
36, 39, 46, 61, 83, 163, 192, 230,
46, 43, 51, 77, 128, 163, 192, 230,
46, 54, 71, 94, 163, 192, 230, 255,
58, 71, 119, 163, 192, 230, 255, 255,
77, 112, 163, 192, 230, 255, 255, 255,
158, 163, 192, 230, 255, 255, 255, 255,
163, 192, 230, 255, 255, 255, 255, 255},
// Quality 3 - 1.6x more aggressive
{38, 29, 24, 38, 58, 96, 123, 144,
27, 29, 34, 46, 62, 123, 144, 173,
34, 32, 38, 58, 96, 123, 144, 173,
34, 42, 53, 70, 123, 144, 173, 192,
43, 53, 90, 123, 144, 173, 192, 211,
58, 85, 123, 144, 173, 192, 211, 230,
118, 123, 144, 173, 192, 211, 230, 240,
123, 144, 173, 192, 211, 230, 240, 246},
// Quality 4 - 1.5x more aggressive
{27, 21, 18, 27, 41, 68, 86, 102,
20, 21, 24, 33, 45, 86, 102, 122,
24, 23, 27, 41, 68, 86, 102, 122,
24, 30, 38, 50, 86, 102, 122, 135,
30, 38, 63, 86, 102, 122, 135, 149,
41, 59, 86, 102, 122, 135, 149, 162,
84, 86, 102, 122, 135, 149, 162, 170,
86, 102, 122, 135, 149, 162, 170, 174},
// Quality 5 - 1.4x more aggressive
{21, 15, 13, 21, 32, 53, 67, 80,
15, 15, 18, 25, 34, 67, 80, 95,
18, 17, 21, 32, 53, 67, 80, 95,
18, 22, 29, 39, 67, 80, 95, 105,
24, 29, 49, 67, 80, 95, 105, 116,
32, 46, 67, 80, 95, 105, 116, 126,
64, 67, 80, 95, 105, 116, 126, 132,
67, 80, 95, 105, 116, 126, 132, 134},
// Quality 6 - 1.3x more aggressive
{16, 12, 10, 16, 23, 39, 51, 59,
12, 12, 14, 18, 26, 51, 59, 70,
14, 13, 16, 23, 39, 51, 59, 70,
14, 17, 22, 29, 51, 59, 70, 78,
18, 22, 36, 51, 59, 70, 78, 86,
23, 34, 51, 59, 70, 78, 86, 94,
49, 51, 59, 70, 78, 86, 94, 98,
51, 59, 70, 78, 86, 94, 98, 100},
// Quality 7 (highest) - 1.2x more aggressive for subtle improvement
{1, 1, 1, 1, 1, 2, 2, 4,
1, 1, 1, 1, 2, 3, 4, 5,
1, 1, 1, 2, 3, 4, 5, 6,
1, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 10,
3, 4, 5, 6, 7, 8, 10, 11,
4, 5, 6, 7, 8, 10, 11, 12}
};
// Quality settings for quantization (Cg channel - 8x8, much more aggressive than Co)
// Similar to NTSC Q channel reduction - exploit reduced human sensitivity to green-magenta
// Now using 3x-5x more aggressive quantization, similar to actual NTSC Q bandwidth reduction
static const uint8_t QUANT_TABLES_CG[8][64] = {
// Quality 0 (lowest) - 5x more aggressive than Co, maximum compression
{255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 1 - 4.5x more aggressive, very low bandwidth
{255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 2 - 4x more aggressive, preserve only DC and very low frequencies
{120, 180, 240, 255, 255, 255, 255, 255,
180, 240, 255, 255, 255, 255, 255, 255,
240, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 3 - 3.5x more aggressive, basic low frequency preservation
{84, 108, 144, 192, 255, 255, 255, 255,
108, 144, 192, 255, 255, 255, 255, 255,
144, 192, 255, 255, 255, 255, 255, 255,
192, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 4 - 3x more aggressive, moderate compression
{54, 72, 96, 128, 180, 255, 255, 255,
72, 96, 128, 180, 255, 255, 255, 255,
96, 128, 180, 255, 255, 255, 255, 255,
128, 180, 255, 255, 255, 255, 255, 255,
180, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 5 - 2.8x more aggressive, balanced compression
{42, 56, 75, 100, 140, 200, 255, 255,
56, 75, 100, 140, 200, 255, 255, 255,
75, 100, 140, 200, 255, 255, 255, 255,
100, 140, 200, 255, 255, 255, 255, 255,
140, 200, 255, 255, 255, 255, 255, 255,
200, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 6 - 2.5x more aggressive, good quality but still compressed
{30, 40, 54, 72, 100, 144, 200, 255,
40, 54, 72, 100, 144, 200, 255, 255,
54, 72, 100, 144, 200, 255, 255, 255,
72, 100, 144, 200, 255, 255, 255, 255,
100, 144, 200, 255, 255, 255, 255, 255,
144, 200, 255, 255, 255, 255, 255, 255,
200, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255},
// Quality 7 (highest) - 2x more aggressive, preserve more detail
{2, 3, 4, 6, 8, 12, 16, 20,
3, 4, 6, 8, 12, 16, 20, 24,
4, 6, 8, 12, 16, 20, 24, 28,
6, 8, 12, 16, 20, 24, 28, 32,
8, 12, 16, 20, 24, 28, 32, 36,
12, 16, 20, 24, 28, 32, 36, 40,
16, 20, 24, 28, 32, 36, 40, 44,
20, 24, 28, 32, 36, 40, 44, 48}
};
// Audio constants (reuse MP2 from existing system)
@@ -890,18 +968,19 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
// Apply fast DCT transform to chroma - 4x performance improvement
dct_8x8_fast(enc->co_workspace, enc->dct_workspace);
// Quantize Co coefficients (chroma)
const uint8_t *c_quant = QUANT_TABLES_C[enc->quality];
// Quantize Co coefficients (chroma - orange-blue)
const uint8_t *co_quant = QUANT_TABLES_CO[enc->quality];
for (int i = 0; i < 64; i++) {
block->co_coeffs[i] = quantize_coeff(enc->dct_workspace[i], c_quant[i], i == 0, 1);
block->co_coeffs[i] = quantize_coeff(enc->dct_workspace[i], co_quant[i], i == 0, 1);
}
// Apply fast DCT transform to Cg - 4x performance improvement
dct_8x8_fast(enc->cg_workspace, enc->dct_workspace);
// Quantize Cg coefficients (chroma)
// Quantize Cg coefficients (chroma - green-magenta, more aggressive like NTSC Q)
const uint8_t *cg_quant = QUANT_TABLES_CG[enc->quality];
for (int i = 0; i < 64; i++) {
block->cg_coeffs[i] = quantize_coeff(enc->dct_workspace[i], c_quant[i], i == 0, 1);
block->cg_coeffs[i] = quantize_coeff(enc->dct_workspace[i], cg_quant[i], i == 0, 1);
}
// Set CBP (simplified - always encode all channels)