Commit b91a1586 authored by Jingning Han's avatar Jingning Han
Browse files

Calculate rd cost per transformed block

Compute the rate-distortion cost per transformed block, and cumulate
the cost through all blocks inside a partition. This allows encoder
to detect if the cumulative rd cost is already above the best rd cost,
thereby enabling early termination in the rate-distortion optimization
search.

Change-Id: I0a856367a9a7b6dd0b466e7b767f54d5018d09ac
parent 9df24b41
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "vp9/encoder/vp9_onyx_int.h" #include "vp9/encoder/vp9_onyx_int.h"
int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred); int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred);
void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg);
void vp9_encode_intra_block_y(VP9_COMMON *const cm, MACROBLOCK *mb, void vp9_encode_intra_block_y(VP9_COMMON *const cm, MACROBLOCK *mb,
BLOCK_SIZE_TYPE bs); BLOCK_SIZE_TYPE bs);
void vp9_encode_intra_block_uv(VP9_COMMON *const cm, MACROBLOCK *mb, void vp9_encode_intra_block_uv(VP9_COMMON *const cm, MACROBLOCK *mb,
......
...@@ -431,13 +431,7 @@ void vp9_optimize_sbuv(VP9_COMMON *const cm, MACROBLOCK *x, ...@@ -431,13 +431,7 @@ void vp9_optimize_sbuv(VP9_COMMON *const cm, MACROBLOCK *x,
foreach_transformed_block_uv(&x->e_mbd, bsize, optimize_block, &arg); foreach_transformed_block_uv(&x->e_mbd, bsize, optimize_block, &arg);
} }
struct encode_b_args { void xform_quant(int plane, int block, BLOCK_SIZE_TYPE bsize,
VP9_COMMON *cm;
MACROBLOCK *x;
struct optimize_ctx *ctx;
};
static void xform_quant(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) { int ss_txfrm_size, void *arg) {
struct encode_b_args* const args = arg; struct encode_b_args* const args = arg;
MACROBLOCK* const x = args->x; MACROBLOCK* const x = args->x;
...@@ -588,7 +582,7 @@ void vp9_encode_sb(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) { ...@@ -588,7 +582,7 @@ void vp9_encode_sb(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
foreach_transformed_block(xd, bsize, encode_block, &arg); foreach_transformed_block(xd, bsize, encode_block, &arg);
} }
static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) { int ss_txfrm_size, void *arg) {
struct encode_b_args* const args = arg; struct encode_b_args* const args = arg;
MACROBLOCK *const x = args->x; MACROBLOCK *const x = args->x;
......
...@@ -27,6 +27,12 @@ struct optimize_ctx { ...@@ -27,6 +27,12 @@ struct optimize_ctx {
ENTROPY_CONTEXT tl[MAX_MB_PLANE][16]; ENTROPY_CONTEXT tl[MAX_MB_PLANE][16];
}; };
struct encode_b_args {
VP9_COMMON *cm;
MACROBLOCK *x;
struct optimize_ctx *ctx;
};
void vp9_optimize_init(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, void vp9_optimize_init(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize,
struct optimize_ctx *ctx); struct optimize_ctx *ctx);
void vp9_optimize_b(int plane, int block, BLOCK_SIZE_TYPE bsize, void vp9_optimize_b(int plane, int block, BLOCK_SIZE_TYPE bsize,
...@@ -39,6 +45,8 @@ void vp9_encode_sb(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize); ...@@ -39,6 +45,8 @@ void vp9_encode_sb(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
void vp9_encode_sby(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize); void vp9_encode_sby(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
void vp9_encode_sbuv(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize); void vp9_encode_sbuv(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
void xform_quant(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg);
void vp9_xform_quant_sby(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize); void vp9_xform_quant_sby(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
void vp9_xform_quant_sbuv(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize); void vp9_xform_quant_sbuv(VP9_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
......
...@@ -505,17 +505,6 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x, ...@@ -505,17 +505,6 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
rd[TX_4X4][1] : rd[TX_8X8][1]; rd[TX_4X4][1] : rd[TX_8X8][1];
} }
static int64_t block_error_sby(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
int shift, int64_t *sse) {
struct macroblockd_plane *p = &x->e_mbd.plane[0];
const int bw = plane_block_width(bsize, p);
const int bh = plane_block_height(bsize, p);
int64_t e = vp9_block_error(x->plane[0].coeff, x->e_mbd.plane[0].dqcoeff,
bw * bh, sse) >> shift;
*sse >>= shift;
return e;
}
static int64_t block_error_sbuv(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize, static int64_t block_error_sbuv(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
int shift, int64_t *sse) { int shift, int64_t *sse) {
int64_t sum = 0, this_sse; int64_t sum = 0, this_sse;
...@@ -542,10 +531,30 @@ struct rdcost_block_args { ...@@ -542,10 +531,30 @@ struct rdcost_block_args {
TX_SIZE tx_size; TX_SIZE tx_size;
int bw; int bw;
int bh; int bh;
int cost; int rate;
int64_t dist;
int64_t sse;
int64_t best_rd;
int skip;
}; };
static void rdcost_block(int plane, int block, BLOCK_SIZE_TYPE bsize, static void dist_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
struct rdcost_block_args* args = arg;
MACROBLOCK* const x = args->x;
MACROBLOCKD* const xd = &x->e_mbd;
struct macroblock_plane *const p = &x->plane[0];
struct macroblockd_plane *const pd = &xd->plane[0];
int64_t this_sse;
int shift = args->tx_size == TX_32X32 ? 0 : 2;
int16_t *const coeff = BLOCK_OFFSET(p->coeff, block, 16);
int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block, 16);
args->dist += vp9_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
&this_sse) >> shift;
args->sse += this_sse >> shift;
}
static void rate_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) { int ss_txfrm_size, void *arg) {
struct rdcost_block_args* args = arg; struct rdcost_block_args* args = arg;
int x_idx, y_idx; int x_idx, y_idx;
...@@ -554,7 +563,7 @@ static void rdcost_block(int plane, int block, BLOCK_SIZE_TYPE bsize, ...@@ -554,7 +563,7 @@ static void rdcost_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
txfrm_block_to_raster_xy(xd, bsize, plane, block, args->tx_size * 2, &x_idx, txfrm_block_to_raster_xy(xd, bsize, plane, block, args->tx_size * 2, &x_idx,
&y_idx); &y_idx);
args->cost += cost_coeffs(args->cm, args->x, plane, block, args->rate += cost_coeffs(args->cm, args->x, plane, block,
xd->plane[plane].plane_type, args->t_above + x_idx, xd->plane[plane].plane_type, args->t_above + x_idx,
args->t_left + y_idx, args->tx_size, args->t_left + y_idx, args->tx_size,
args->bw * args->bh); args->bw * args->bh);
...@@ -566,16 +575,17 @@ static int rdcost_plane(VP9_COMMON * const cm, MACROBLOCK *x, int plane, ...@@ -566,16 +575,17 @@ static int rdcost_plane(VP9_COMMON * const cm, MACROBLOCK *x, int plane,
const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x;
const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y; const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y;
const int bw = 1 << bwl, bh = 1 << bhl; const int bw = 1 << bwl, bh = 1 << bhl;
struct rdcost_block_args args = { cm, x, { 0 }, { 0 }, tx_size, bw, bh, 0 }; struct rdcost_block_args args = { cm, x, { 0 }, { 0 }, tx_size, bw, bh,
0, 0, 0, 0, 0 };
vpx_memcpy(&args.t_above, xd->plane[plane].above_context, vpx_memcpy(&args.t_above, xd->plane[plane].above_context,
sizeof(ENTROPY_CONTEXT) * bw); sizeof(ENTROPY_CONTEXT) * bw);
vpx_memcpy(&args.t_left, xd->plane[plane].left_context, vpx_memcpy(&args.t_left, xd->plane[plane].left_context,
sizeof(ENTROPY_CONTEXT) * bh); sizeof(ENTROPY_CONTEXT) * bh);
foreach_transformed_block_in_plane(xd, bsize, plane, rdcost_block, &args); foreach_transformed_block_in_plane(xd, bsize, plane, rate_block, &args);
return args.cost; return args.rate;
} }
static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x, static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x,
...@@ -588,20 +598,41 @@ static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x, ...@@ -588,20 +598,41 @@ static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x,
return cost; return cost;
} }
static void block_yrd_txfm(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
struct rdcost_block_args *args = arg;
MACROBLOCK *const x = args->x;
MACROBLOCKD *const xd = &x->e_mbd;
struct encode_b_args encode_args = {args->cm, x, NULL};
if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
encode_block_intra(plane, block, bsize, ss_txfrm_size, &encode_args);
else
xform_quant(plane, block, bsize, ss_txfrm_size, &encode_args);
dist_block(plane, block, bsize, ss_txfrm_size, args);
rate_block(plane, block, bsize, ss_txfrm_size, args);
}
static void super_block_yrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x, static void super_block_yrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x,
int *rate, int64_t *distortion, int *rate, int64_t *distortion,
int *skippable, int64_t *sse, int *skippable, int64_t *sse,
BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) { BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) {
MACROBLOCKD *const xd = &x->e_mbd; MACROBLOCKD *const xd = &x->e_mbd;
struct macroblockd_plane *const pd = &xd->plane[0];
const int bwl = b_width_log2(bsize) - xd->plane[0].subsampling_x;
const int bhl = b_height_log2(bsize) - xd->plane[0].subsampling_y;
const int bw = 1 << bwl, bh = 1 << bhl;
struct rdcost_block_args args = { cm, x, { 0 }, { 0 }, tx_size, bw, bh,
0, 0, 0, 0, 0 };
xd->mode_info_context->mbmi.txfm_size = tx_size; xd->mode_info_context->mbmi.txfm_size = tx_size;
vpx_memcpy(&args.t_above, pd->above_context, sizeof(ENTROPY_CONTEXT) * bw);
vpx_memcpy(&args.t_left, pd->left_context, sizeof(ENTROPY_CONTEXT) * bh);
if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) foreach_transformed_block_in_plane(xd, bsize, 0, block_yrd_txfm, &args);
vp9_encode_intra_block_y(cm, x, bsize); *distortion = args.dist;
else *rate = args.rate;
vp9_xform_quant_sby(cm, x, bsize); *sse = args.sse;
*distortion = block_error_sby(x, bsize, tx_size == TX_32X32 ? 0 : 2, sse);
*rate = rdcost_plane(cm, x, 0, bsize, tx_size);
*skippable = vp9_sby_is_skippable(xd, bsize); *skippable = vp9_sby_is_skippable(xd, bsize);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment