|
|
|
@ -36,6 +36,9 @@ |
|
|
|
|
* (COEF_LUT_TAB*MAX_QUANT_INDEX) since the sign is appended during encoding */ |
|
|
|
|
#define COEF_LUT_TAB 2048 |
|
|
|
|
|
|
|
|
|
/* Per slice quantization bit cost cache */ |
|
|
|
|
#define SLICE_CACHED_QUANTIZERS 30 |
|
|
|
|
|
|
|
|
|
enum VC2_QM { |
|
|
|
|
VC2_QM_DEF = 0, |
|
|
|
|
VC2_QM_COL, |
|
|
|
@ -61,14 +64,22 @@ typedef struct Plane { |
|
|
|
|
ptrdiff_t coef_stride; |
|
|
|
|
} Plane; |
|
|
|
|
|
|
|
|
|
typedef struct BitCostCache { |
|
|
|
|
int bits; |
|
|
|
|
int quantizer; |
|
|
|
|
} BitCostCache; |
|
|
|
|
|
|
|
|
|
typedef struct SliceArgs { |
|
|
|
|
PutBitContext pb; |
|
|
|
|
BitCostCache cache[SLICE_CACHED_QUANTIZERS]; |
|
|
|
|
int cached_results; |
|
|
|
|
void *ctx; |
|
|
|
|
int x; |
|
|
|
|
int y; |
|
|
|
|
int quant_idx; |
|
|
|
|
int bits_ceil; |
|
|
|
|
int bits_floor; |
|
|
|
|
int bytes_left; |
|
|
|
|
int bytes; |
|
|
|
|
} SliceArgs; |
|
|
|
|
|
|
|
|
@ -583,13 +594,19 @@ static void encode_subband(VC2EncContext *s, PutBitContext *pb, int sx, int sy, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int count_hq_slice(VC2EncContext *s, int slice_x, |
|
|
|
|
int slice_y, int quant_idx) |
|
|
|
|
static int count_hq_slice(VC2EncContext *s, BitCostCache *cache, |
|
|
|
|
int *cached_results, int slice_x, int slice_y, |
|
|
|
|
int quant_idx) |
|
|
|
|
{ |
|
|
|
|
int x, y; |
|
|
|
|
int i, x, y; |
|
|
|
|
uint8_t quants[MAX_DWT_LEVELS][4]; |
|
|
|
|
int bits = 0, p, level, orientation; |
|
|
|
|
|
|
|
|
|
if (cache && *cached_results) |
|
|
|
|
for (i = 0; i < *cached_results; i++) |
|
|
|
|
if (cache[i].quantizer == quant_idx) |
|
|
|
|
return cache[i].bits; |
|
|
|
|
|
|
|
|
|
bits += 8*s->prefix_bytes; |
|
|
|
|
bits += 8; /* quant_idx */ |
|
|
|
|
|
|
|
|
@ -639,6 +656,12 @@ static int count_hq_slice(VC2EncContext *s, int slice_x, |
|
|
|
|
bits += pad_c*8; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cache) { |
|
|
|
|
cache[*cached_results].quantizer = quant_idx; |
|
|
|
|
cache[*cached_results].bits = bits; |
|
|
|
|
*cached_results = FFMIN(*cached_results + 1, SLICE_CACHED_QUANTIZERS); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return bits; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -655,12 +678,14 @@ static int rate_control(AVCodecContext *avctx, void *arg) |
|
|
|
|
int quant = s->q_start, range = s->q_start/3; |
|
|
|
|
const int top = slice_dat->bits_ceil; |
|
|
|
|
const int bottom = slice_dat->bits_floor; |
|
|
|
|
int bits = count_hq_slice(s, sx, sy, quant); |
|
|
|
|
int bits = count_hq_slice(s, slice_dat->cache, &slice_dat->cached_results, |
|
|
|
|
sx, sy, quant); |
|
|
|
|
range -= range & 1; /* Make it an even number */ |
|
|
|
|
while ((bits > top) || (bits < bottom)) { |
|
|
|
|
range *= bits > top ? +1 : -1; |
|
|
|
|
quant = av_clip(quant + range, 0, s->q_ceil); |
|
|
|
|
bits = count_hq_slice(s, sx, sy, quant); |
|
|
|
|
bits = count_hq_slice(s, slice_dat->cache, &slice_dat->cached_results, |
|
|
|
|
sx, sy, quant); |
|
|
|
|
range = av_clip(range/2, 1, s->q_ceil); |
|
|
|
|
if (quant_buf[1] == quant) { |
|
|
|
|
quant = bits_last < bits ? quant_buf[0] : quant; |
|
|
|
@ -673,6 +698,7 @@ static int rate_control(AVCodecContext *avctx, void *arg) |
|
|
|
|
} |
|
|
|
|
slice_dat->quant_idx = av_clip(quant, 0, s->q_ceil); |
|
|
|
|
slice_dat->bytes = FFALIGN((bits >> 3), s->size_scaler) + 4 + s->prefix_bytes; |
|
|
|
|
slice_dat->bytes_left = s->slice_max_bytes - slice_dat->bytes; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -688,6 +714,7 @@ static void calc_slice_sizes(VC2EncContext *s) |
|
|
|
|
args->ctx = s; |
|
|
|
|
args->x = slice_x; |
|
|
|
|
args->y = slice_y; |
|
|
|
|
args->cached_results = 0; |
|
|
|
|
args->bits_ceil = s->slice_max_bytes << 3; |
|
|
|
|
args->bits_floor = s->slice_min_bytes << 3; |
|
|
|
|
} |
|
|
|
|