summaryrefslogtreecommitdiff
path: root/libavcodec/vc2enc.c
diff options
context:
space:
mode:
authorRostislav Pehlivanov <atomnuker@gmail.com>2016-02-27 18:24:28 +0000
committerRostislav Pehlivanov <atomnuker@gmail.com>2016-02-28 19:06:29 +0000
commit5cc53c2e530d128d80c94320a7263521e43257d2 (patch)
tree3e060ca70941b630cdba38d91921bdd04b55dc03 /libavcodec/vc2enc.c
parent2ad1c87bb260fc921878b04fa7729ab6cc7130e3 (diff)
vc2enc: cache bits per quantizer, calculate wasted bits
Needed for following commits, also a speed increase. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Diffstat (limited to 'libavcodec/vc2enc.c')
-rw-r--r--libavcodec/vc2enc.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c
index fd2abd5456..1d74cd5605 100644
--- a/libavcodec/vc2enc.c
+++ b/libavcodec/vc2enc.c
@@ -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;
}