Changed video format; added TEV version 3 (XYB colour space)

This commit is contained in:
minjaesong
2025-08-26 22:17:45 +09:00
parent 6d982a9786
commit 33e77e378e
7 changed files with 2485 additions and 141 deletions

View File

@@ -95,6 +95,7 @@ int KEYFRAME_INTERVAL = 60;
typedef struct __attribute__((packed)) {
uint8_t mode; // Block encoding mode
int16_t mv_x, mv_y; // Motion vector (1/4 pixel precision)
float rate_control_factor; // Rate control factor (4 bytes, little-endian)
uint16_t cbp; // Coded block pattern (which channels have non-zero coeffs)
int16_t y_coeffs[256]; // quantised Y DCT coefficients (16x16)
int16_t co_coeffs[64]; // quantised Co DCT coefficients (8x8)
@@ -666,6 +667,7 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
// Intra coding for keyframes
block->mode = TEV_MODE_INTRA;
block->mv_x = block->mv_y = 0;
block->rate_control_factor = enc->rate_control_factor;
enc->blocks_intra++;
} else {
// Implement proper mode decision for P-frames
@@ -749,6 +751,7 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
block->mode = TEV_MODE_SKIP;
block->mv_x = 0;
block->mv_y = 0;
block->rate_control_factor = enc->rate_control_factor;
block->cbp = 0x00; // No coefficients present
// Zero out DCT coefficients for consistent format
memset(block->y_coeffs, 0, sizeof(block->y_coeffs));
@@ -760,6 +763,7 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
(abs(block->mv_x) > 0 || abs(block->mv_y) > 0)) {
// Good motion prediction - use motion-only mode
block->mode = TEV_MODE_MOTION;
block->rate_control_factor = enc->rate_control_factor;
block->cbp = 0x00; // No coefficients present
// Zero out DCT coefficients for consistent format
memset(block->y_coeffs, 0, sizeof(block->y_coeffs));
@@ -772,6 +776,7 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
// Motion compensation with threshold
if (motion_sad <= 1024) {
block->mode = TEV_MODE_MOTION;
block->rate_control_factor = enc->rate_control_factor;
block->cbp = 0x00; // No coefficients present
memset(block->y_coeffs, 0, sizeof(block->y_coeffs));
memset(block->co_coeffs, 0, sizeof(block->co_coeffs));
@@ -783,10 +788,12 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
// Use INTER mode with motion vector and residuals
if (abs(block->mv_x) <= 24 && abs(block->mv_y) <= 24) {
block->mode = TEV_MODE_INTER;
block->rate_control_factor = enc->rate_control_factor;
enc->blocks_inter++;
} else {
// Motion vector too large, fall back to INTRA
block->mode = TEV_MODE_INTRA;
block->rate_control_factor = enc->rate_control_factor;
block->mv_x = 0;
block->mv_y = 0;
enc->blocks_intra++;
@@ -795,6 +802,7 @@ static void encode_block(tev_encoder_t *enc, int block_x, int block_y, int is_ke
} else {
// No good motion prediction - use intra mode
block->mode = TEV_MODE_INTRA;
block->rate_control_factor = enc->rate_control_factor;
block->mv_x = 0;
block->mv_y = 0;
enc->blocks_intra++;
@@ -1293,20 +1301,19 @@ static int encode_frame(tev_encoder_t *enc, FILE *output, int frame_num) {
// Clean up frame stream
deflateEnd(&frame_stream);
// Write frame packet header (always include rate control factor)
// Write frame packet header (rate control factor now per-block)
uint8_t packet_type = is_keyframe ? TEV_PACKET_IFRAME : TEV_PACKET_PFRAME;
uint32_t payload_size = compressed_size + 4; // +4 bytes for rate control factor (always)
uint32_t payload_size = compressed_size; // Rate control factor now per-block, not per-packet
fwrite(&packet_type, 1, 1, output);
fwrite(&payload_size, 4, 1, output);
fwrite(&enc->rate_control_factor, 4, 1, output); // Always store rate control factor
fwrite(enc->compressed_buffer, 1, compressed_size, output);
if (enc->verbose) {
printf("rateControlFactor=%.6f\n", enc->rate_control_factor);
}
enc->total_output_bytes += 5 + 4 + compressed_size; // packet + size + rate_factor + data
enc->total_output_bytes += 5 + compressed_size; // packet + size + data (rate_factor now per-block)
// Update rate control for next frame
if (enc->bitrate_mode > 0) {