mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
Changed video format; added TEV version 3 (XYB colour space)
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user