tavenc: tiling

This commit is contained in:
minjaesong
2025-12-07 15:27:32 +09:00
parent 3828bd7fbc
commit 0907e22f53
3 changed files with 88 additions and 3 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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]);