mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
tavenc: tiling
This commit is contained in:
@@ -75,7 +75,7 @@ typedef struct {
|
|||||||
|
|
||||||
// === Advanced Options ===
|
// === Advanced Options ===
|
||||||
int verbose; // 1=enable debug output, 0=quiet (default)
|
int verbose; // 1=enable debug output, 0=quiet (default)
|
||||||
int monoblock; // 1=single tile encoding (always 1 for current implementation)
|
int monoblock; // -1=auto (based on dimensions), 0=force tiled, 1=force monoblock
|
||||||
|
|
||||||
} tav_encoder_params_t;
|
} tav_encoder_params_t;
|
||||||
|
|
||||||
@@ -296,6 +296,23 @@ void tav_encoder_get_stats(tav_encoder_context_t *ctx, tav_encoder_stats_t *stat
|
|||||||
#define TAV_PACKET_GOP_SYNC 0xFC // GOP sync (frame count marker)
|
#define TAV_PACKET_GOP_SYNC 0xFC // GOP sync (frame count marker)
|
||||||
#define TAV_PACKET_TIMECODE 0xFD // Timecode metadata
|
#define TAV_PACKET_TIMECODE 0xFD // Timecode metadata
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Tile Settings (for multi-tile mode)
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
#define TAV_TILE_SIZE_X 640 // Base tile width
|
||||||
|
#define TAV_TILE_SIZE_Y 540 // Base tile height
|
||||||
|
#define TAV_DWT_FILTER_HALF_SUPPORT 4 // For 9/7 filter (filter lengths 9,7 → L=4)
|
||||||
|
#define TAV_TILE_MARGIN_LEVELS 3 // Use margin for 3 levels: 4 * (2^3) = 32px
|
||||||
|
#define TAV_TILE_MARGIN (TAV_DWT_FILTER_HALF_SUPPORT * (1 << TAV_TILE_MARGIN_LEVELS)) // 32px
|
||||||
|
#define TAV_PADDED_TILE_SIZE_X (TAV_TILE_SIZE_X + 2 * TAV_TILE_MARGIN) // 704
|
||||||
|
#define TAV_PADDED_TILE_SIZE_Y (TAV_TILE_SIZE_Y + 2 * TAV_TILE_MARGIN) // 604
|
||||||
|
|
||||||
|
// Monoblock threshold: D1 PAL resolution (720x576)
|
||||||
|
// If width > 720 OR height > 576, automatically switch to tiled mode
|
||||||
|
#define TAV_MONOBLOCK_MAX_WIDTH 720
|
||||||
|
#define TAV_MONOBLOCK_MAX_HEIGHT 576
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -206,6 +206,9 @@ struct tav_encoder_context {
|
|||||||
int verbose;
|
int verbose;
|
||||||
int monoblock;
|
int monoblock;
|
||||||
|
|
||||||
|
// Tile configuration (derived from monoblock and dimensions)
|
||||||
|
int tiles_x, tiles_y; // Number of tiles in x/y directions
|
||||||
|
|
||||||
// Derived quantizer values (QLUT indices)
|
// Derived quantizer values (QLUT indices)
|
||||||
int quantiser_y, quantiser_co, quantiser_cg;
|
int quantiser_y, quantiser_co, quantiser_cg;
|
||||||
|
|
||||||
@@ -304,7 +307,7 @@ void tav_encoder_params_init(tav_encoder_params_t *params, int width, int height
|
|||||||
|
|
||||||
// Advanced
|
// Advanced
|
||||||
params->verbose = 0;
|
params->verbose = 0;
|
||||||
params->monoblock = 1; // Single tile (always 1 for current implementation)
|
params->monoblock = -1; // -1=auto (based on dimensions), 0=force tiled, 1=force monoblock
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -381,10 +384,60 @@ tav_encoder_context_t *tav_encoder_create(const tav_encoder_params_t *params) {
|
|||||||
// Force temporal level 2
|
// Force temporal level 2
|
||||||
ctx->temporal_levels = 2;
|
ctx->temporal_levels = 2;
|
||||||
|
|
||||||
|
// Handle monoblock mode:
|
||||||
|
// -1 = auto (select based on dimensions), 0 = force tiled, 1 = force monoblock
|
||||||
|
if (ctx->monoblock == -1) {
|
||||||
|
// Auto mode: use monoblock for <= D1 PAL, tiled for larger
|
||||||
|
if (ctx->width > TAV_MONOBLOCK_MAX_WIDTH || ctx->height > TAV_MONOBLOCK_MAX_HEIGHT) {
|
||||||
|
ctx->monoblock = 0;
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("Auto-selected Padded Tiling mode: %dx%d exceeds D1 PAL threshold (%dx%d)\n",
|
||||||
|
ctx->width, ctx->height, TAV_MONOBLOCK_MAX_WIDTH, TAV_MONOBLOCK_MAX_HEIGHT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx->monoblock = 1;
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("Auto-selected Monoblock mode: %dx%d within D1 PAL threshold\n",
|
||||||
|
ctx->width, ctx->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ctx->monoblock == 0) {
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("Forced Padded Tiling mode (--tiled)\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// monoblock == 1: force monoblock even for large dimensions
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("Forced Monoblock mode (--monoblock)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate tile dimensions based on monoblock setting
|
||||||
|
if (ctx->monoblock) {
|
||||||
|
// Monoblock mode: single tile covering entire frame
|
||||||
|
ctx->tiles_x = 1;
|
||||||
|
ctx->tiles_y = 1;
|
||||||
|
} else {
|
||||||
|
// Padded Tiling mode: multiple tiles of TILE_SIZE_X × TILE_SIZE_Y
|
||||||
|
ctx->tiles_x = (ctx->width + TAV_TILE_SIZE_X - 1) / TAV_TILE_SIZE_X;
|
||||||
|
ctx->tiles_y = (ctx->height + TAV_TILE_SIZE_Y - 1) / TAV_TILE_SIZE_Y;
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("Padded Tiling mode: %dx%d tiles (%d total)\n",
|
||||||
|
ctx->tiles_x, ctx->tiles_y, ctx->tiles_x * ctx->tiles_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate decomp levels if auto (0)
|
// Calculate decomp levels if auto (0)
|
||||||
|
// For multi-tile mode, use tile size as the basis; for monoblock, use frame size
|
||||||
if (ctx->decomp_levels == 0) {
|
if (ctx->decomp_levels == 0) {
|
||||||
int levels = 0;
|
int levels = 0;
|
||||||
int min_dim = (ctx->width < ctx->height) ? ctx->width : ctx->height;
|
int min_dim;
|
||||||
|
if (ctx->monoblock) {
|
||||||
|
min_dim = (ctx->width < ctx->height) ? ctx->width : ctx->height;
|
||||||
|
} else {
|
||||||
|
// For tiled mode, calculate based on tile size
|
||||||
|
min_dim = (TAV_TILE_SIZE_X < TAV_TILE_SIZE_Y) ? TAV_TILE_SIZE_X : TAV_TILE_SIZE_Y;
|
||||||
|
}
|
||||||
// Keep halving until we reach minimum size
|
// Keep halving until we reach minimum size
|
||||||
while (min_dim >= 32) {
|
while (min_dim >= 32) {
|
||||||
min_dim /= 2;
|
min_dim /= 2;
|
||||||
@@ -483,6 +536,9 @@ tav_encoder_context_t *tav_encoder_create(const tav_encoder_params_t *params) {
|
|||||||
printf("%s created:\n", ENCODER_VERSION);
|
printf("%s created:\n", ENCODER_VERSION);
|
||||||
printf(" Resolution: %dx%d @ %d/%d fps\n",
|
printf(" Resolution: %dx%d @ %d/%d fps\n",
|
||||||
ctx->width, ctx->height, ctx->fps_num, ctx->fps_den);
|
ctx->width, ctx->height, ctx->fps_num, ctx->fps_den);
|
||||||
|
printf(" Tiling: %s (%dx%d tiles)\n",
|
||||||
|
ctx->monoblock ? "Monoblock" : "Padded Tiling",
|
||||||
|
ctx->tiles_x, ctx->tiles_y);
|
||||||
printf(" GOP size: %d frames\n", ctx->gop_size);
|
printf(" GOP size: %d frames\n", ctx->gop_size);
|
||||||
printf(" Wavelet: %d (spatial), %d (temporal)\n",
|
printf(" Wavelet: %d (spatial), %d (temporal)\n",
|
||||||
ctx->wavelet_type, ctx->temporal_wavelet);
|
ctx->wavelet_type, ctx->temporal_wavelet);
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ static void print_usage(const char *program) {
|
|||||||
printf(" --intra-only Disable temporal compression (I-frames only)\n");
|
printf(" --intra-only Disable temporal compression (I-frames only)\n");
|
||||||
printf(" --gop-size N GOP size 8/16/24 (default: 24)\n");
|
printf(" --gop-size N GOP size 8/16/24 (default: 24)\n");
|
||||||
printf(" --single-pass Disable scene change detection\n");
|
printf(" --single-pass Disable scene change detection\n");
|
||||||
|
printf("\nTiling:\n");
|
||||||
|
printf(" --monoblock Force single-tile mode (auto-disabled for > %dx%d)\n",
|
||||||
|
TAV_MONOBLOCK_MAX_WIDTH, TAV_MONOBLOCK_MAX_HEIGHT);
|
||||||
|
printf(" --tiled Force multi-tile mode (Padded Tiling)\n");
|
||||||
printf("\nCompression:\n");
|
printf("\nCompression:\n");
|
||||||
printf(" --zstd-level N Zstd level 3-22 (default: 7)\n");
|
printf(" --zstd-level N Zstd level 3-22 (default: 7)\n");
|
||||||
printf(" --no-perceptual-tuning Disable HVS perceptual quantization\n");
|
printf(" --no-perceptual-tuning Disable HVS perceptual quantization\n");
|
||||||
@@ -1212,6 +1216,8 @@ int main(int argc, char *argv[]) {
|
|||||||
{"no-audio", no_argument, 0, 1017},
|
{"no-audio", no_argument, 0, 1017},
|
||||||
{"preset-sports", no_argument, 0, 1026},
|
{"preset-sports", no_argument, 0, 1026},
|
||||||
{"preset-anime", no_argument, 0, 1027},
|
{"preset-anime", no_argument, 0, 1027},
|
||||||
|
{"monoblock", no_argument, 0, 1028},
|
||||||
|
{"tiled", no_argument, 0, 1029},
|
||||||
{"help", no_argument, 0, '?'},
|
{"help", no_argument, 0, '?'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@@ -1359,6 +1365,12 @@ int main(int argc, char *argv[]) {
|
|||||||
case 1027: // --preset-anime
|
case 1027: // --preset-anime
|
||||||
cli.enc_params.encoder_preset |= 0x02;
|
cli.enc_params.encoder_preset |= 0x02;
|
||||||
break;
|
break;
|
||||||
|
case 1028: // --monoblock
|
||||||
|
cli.enc_params.monoblock = 1;
|
||||||
|
break;
|
||||||
|
case 1029: // --tiled
|
||||||
|
cli.enc_params.monoblock = 0;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user