Add macros for indexing cu array in lcu_t.

- Adds macros LCU_GET_CU and LCU_GET_CU_AT_PX to cu.h.
- Replaces accesses to the cu array of lcu_t by calls to these macros.
This commit is contained in:
Arttu Ylä-Outinen 2015-07-23 09:40:41 +03:00
parent 39302b0328
commit 9532d79adb
7 changed files with 59 additions and 42 deletions

View file

@ -175,6 +175,27 @@ typedef struct {
cu_info_t cu[9*9+1];
} lcu_t;
/**
* \brief Return pointer to a given CU.
*
* \param lcu pointer to the containing LCU
* \param x_cu x-index of the CU
* \param y_cu y-index of the CU
* \return pointer to the CU
*/
#define LCU_GET_CU(lcu, x_cu, y_cu) \
(&(lcu)->cu[LCU_CU_OFFSET + (x_cu) + (y_cu) * LCU_T_CU_WIDTH])
/**
* \brief Return pointer to the CU containing a given pixel.
*
* \param lcu pointer to the containing LCU
* \param x_px x-coordinate relative to the upper left corner of the LCU
* \param y_px y-coordinate relative to the upper left corner of the LCU
* \return pointer to the CU at coordinates (x_px, y_px)
*/
#define LCU_GET_CU_AT_PX(lcu, x_px, y_px) LCU_GET_CU(lcu, (x_px) >> 3, (y_px) >> 3)
#define CHECKPOINT_LCU(prefix_str, lcu) do { \
CHECKPOINT_CU(prefix_str " cu[0]", (lcu).cu[0]); \
CHECKPOINT_CU(prefix_str " cu[1]", (lcu).cu[1]); \

View file

@ -432,7 +432,7 @@ void kvz_inter_get_spatial_merge_candidates(int32_t x, int32_t y, int8_t depth,
*/
int32_t x_cu = (x & (LCU_WIDTH - 1)) >> MAX_DEPTH; //!< coordinates from top-left of this LCU
int32_t y_cu = (y & (LCU_WIDTH - 1)) >> MAX_DEPTH;
cu_info_t* cu = &lcu->cu[LCU_CU_OFFSET];
cu_info_t* cu = LCU_GET_CU(lcu, 0, 0);
// A0 and A1 availability testing
if (x != 0) {
*a1 = &cu[x_cu - 1 + (y_cu + cur_block_in_scu - 1) * LCU_T_CU_WIDTH];

View file

@ -487,7 +487,7 @@ void kvz_intra_recon_lcu_luma(
{
const vector2d_t lcu_px = { x & 0x3f, y & 0x3f };
if (cur_cu == NULL) {
cur_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + (lcu_px.y >> 3)*LCU_T_CU_WIDTH];
cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
}
const int8_t width = LCU_WIDTH >> depth;
@ -500,9 +500,9 @@ void kvz_intra_recon_lcu_luma(
kvz_intra_recon_lcu_luma(state, x + offset, y + offset, depth+1, intra_mode, NULL, lcu);
if (depth < MAX_DEPTH) {
cu_info_t *cu_a = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + (lcu_px.y >> 3) *LCU_T_CU_WIDTH];
cu_info_t *cu_b = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_c = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_a = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y);
cu_info_t *cu_b = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y + offset);
cu_info_t *cu_c = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y + offset);
if (cbf_is_set(cu_a->cbf.y, depth+1) || cbf_is_set(cu_b->cbf.y, depth+1) || cbf_is_set(cu_c->cbf.y, depth+1)) {
cbf_set(&cur_cu->cbf.y, depth);
}
@ -542,7 +542,7 @@ void kvz_intra_recon_lcu_chroma(
const int8_t width_c = (depth == MAX_PU_DEPTH ? width : width / 2);
if (cur_cu == NULL) {
cur_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + (lcu_px.y >> 3)*LCU_T_CU_WIDTH];
cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
}
if (depth == 0 || cur_cu->tr_depth > depth) {
@ -554,9 +554,9 @@ void kvz_intra_recon_lcu_chroma(
kvz_intra_recon_lcu_chroma(state, x + offset, y + offset, depth+1, intra_mode, NULL, lcu);
if (depth < MAX_DEPTH) {
cu_info_t *cu_a = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + (lcu_px.y >> 3) *LCU_T_CU_WIDTH];
cu_info_t *cu_b = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_c = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_a = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y);
cu_info_t *cu_b = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y + offset);
cu_info_t *cu_c = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y + offset);
if (cbf_is_set(cu_a->cbf.u, depth+1) || cbf_is_set(cu_b->cbf.u, depth+1) || cbf_is_set(cu_c->cbf.u, depth+1)) {
cbf_set(&cur_cu->cbf.u, depth);
}

View file

@ -82,8 +82,8 @@ static void work_tree_copy_up(int x_px, int y_px, int depth, lcu_t work_tree[MAX
int x, y;
for (y = y_cu; y < y_cu + width_cu; ++y) {
for (x = x_cu; x < x_cu + width_cu; ++x) {
const cu_info_t *from_cu = &work_tree[depth + 1].cu[LCU_CU_OFFSET + x + y * LCU_T_CU_WIDTH];
cu_info_t *to_cu = &work_tree[depth].cu[LCU_CU_OFFSET + x + y * LCU_T_CU_WIDTH];
const cu_info_t *from_cu = LCU_GET_CU(&work_tree[depth + 1], x, y);
cu_info_t *to_cu = LCU_GET_CU(&work_tree[depth], x, y);
memcpy(to_cu, from_cu, sizeof(*to_cu));
}
}
@ -142,8 +142,8 @@ static void work_tree_copy_down(int x_px, int y_px, int depth, lcu_t work_tree[M
int x, y;
for (y = y_cu; y < y_cu + width_cu; ++y) {
for (x = x_cu; x < x_cu + width_cu; ++x) {
const cu_info_t *from_cu = &work_tree[depth].cu[LCU_CU_OFFSET + x + y * LCU_T_CU_WIDTH];
cu_info_t *to_cu = &work_tree[d].cu[LCU_CU_OFFSET + x + y * LCU_T_CU_WIDTH];
const cu_info_t *from_cu = LCU_GET_CU(&work_tree[depth], x, y);
cu_info_t *to_cu = LCU_GET_CU(&work_tree[d], x, y);
memcpy(to_cu, from_cu, sizeof(*to_cu));
}
}
@ -174,7 +174,7 @@ void kvz_lcu_set_trdepth(lcu_t *lcu, int x_px, int y_px, int depth, int tr_depth
{
const int width_cu = LCU_CU_WIDTH >> depth;
const vector2d_t lcu_cu = { (x_px & (LCU_WIDTH - 1)) / 8, (y_px & (LCU_WIDTH - 1)) / 8 };
cu_info_t *const cur_cu = &lcu->cu[lcu_cu.x + lcu_cu.y * LCU_T_CU_WIDTH + LCU_CU_OFFSET];
cu_info_t *const cur_cu = LCU_GET_CU(lcu, lcu_cu.x, lcu_cu.y);
int x, y;
// Depth 4 doesn't go inside the loop. Set the top-left CU.
@ -194,7 +194,7 @@ static void lcu_set_intra_mode(lcu_t *lcu, int x_px, int y_px, int depth, int pr
const int width_cu = LCU_CU_WIDTH >> depth;
const int x_cu = SUB_SCU(x_px) >> MAX_DEPTH;
const int y_cu = SUB_SCU(y_px) >> MAX_DEPTH;
cu_info_t *const lcu_cu = &lcu->cu[LCU_CU_OFFSET];
cu_info_t *const lcu_cu = LCU_GET_CU(lcu, 0, 0);
int x, y;
// NxN can only be applied to a single CU at a time.
@ -231,7 +231,7 @@ static void lcu_set_inter(lcu_t *lcu, int x_px, int y_px, int depth, cu_info_t *
const int width_cu = LCU_CU_WIDTH >> depth;
const int x_cu = SUB_SCU(x_px) >> MAX_DEPTH;
const int y_cu = SUB_SCU(y_px) >> MAX_DEPTH;
cu_info_t *const lcu_cu = &lcu->cu[LCU_CU_OFFSET];
cu_info_t *const lcu_cu = LCU_GET_CU(lcu, 0, 0);
int x, y;
// Set mode in every CU covered by part_mode in this depth.
for (y = y_cu; y < y_cu + width_cu; ++y) {
@ -295,7 +295,7 @@ double kvz_cu_rd_cost_luma(const encoder_state_t *const state,
const uint8_t pu_index = PU_INDEX(x_px / 4, y_px / 4);
// cur_cu is used for TU parameters.
cu_info_t *const tr_cu = &lcu->cu[LCU_CU_OFFSET + (x_px / 8) + (y_px / 8) * LCU_T_CU_WIDTH];
cu_info_t *const tr_cu = LCU_GET_CU_AT_PX(lcu, x_px, y_px);
double coeff_bits = 0;
double tr_tree_bits = 0;
@ -368,7 +368,7 @@ double kvz_cu_rd_cost_chroma(const encoder_state_t *const state,
{
const vector2d_t lcu_px = { x_px / 2, y_px / 2 };
const int width = (depth <= MAX_DEPTH) ? LCU_WIDTH >> (depth + 1) : LCU_WIDTH >> depth;
cu_info_t *const tr_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x / 4) + (lcu_px.y / 4)*LCU_T_CU_WIDTH];
cu_info_t *const tr_cu = LCU_GET_CU(lcu, lcu_px.x / 4, lcu_px.y / 4);
double tr_tree_bits = 0;
double coeff_bits = 0;
@ -468,7 +468,7 @@ static double calc_mode_bits(const encoder_state_t *state,
static uint8_t get_ctx_cu_split_model(const lcu_t *lcu, int x, int y, int depth)
{
vector2d_t lcu_cu = { (x & 0x3f) / 8, (y & 0x3f) / 8 };
const cu_info_t *cu_array = &(lcu)->cu[LCU_CU_OFFSET];
const cu_info_t *cu_array = LCU_GET_CU(lcu, 0, 0);
bool condA = x >= 8 && cu_array[(lcu_cu.x - 1) + lcu_cu.y * LCU_T_CU_WIDTH].depth > depth;
bool condL = y >= 8 && cu_array[lcu_cu.x + (lcu_cu.y - 1) * LCU_T_CU_WIDTH].depth > depth;
return condA + condL;
@ -506,7 +506,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
return 0;
}
cur_cu = &(&work_tree[depth])->cu[LCU_CU_OFFSET+(x_local>>3) + (y_local>>3)*LCU_T_CU_WIDTH];
cur_cu = LCU_GET_CU_AT_PX(&work_tree[depth], x_local, y_local);
// Assign correct depth
cur_cu->depth = depth > MAX_DEPTH ? MAX_DEPTH : depth;
cur_cu->tr_depth = depth > 0 ? depth : 1;
@ -647,7 +647,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
&& x + cu_width <= frame->width && y + cu_width <= frame->height)
{
vector2d_t lcu_cu = { x_local / 8, y_local / 8 };
cu_info_t *cu_array_d1 = &(&work_tree[depth + 1])->cu[LCU_CU_OFFSET];
cu_info_t *cu_array_d1 = LCU_GET_CU(&work_tree[depth + 1], 0, 0);
cu_info_t *cu_d1 = &cu_array_d1[(lcu_cu.x + lcu_cu.y * LCU_T_CU_WIDTH)];
// If the best CU in depth+1 is intra and the biggest it can be, try it.
@ -717,7 +717,7 @@ static void init_lcu_t(const encoder_state_t * const state, const int x, const i
// Use top-left sub-cu of LCU as pointer to lcu->cu array to make things
// simpler.
cu_info_t *lcu_cu = &lcu->cu[LCU_CU_OFFSET];
cu_info_t *lcu_cu = LCU_GET_CU(lcu, 0, 0);
// Copy top CU row.
if (y_cu > 0) {
@ -808,7 +808,7 @@ static void copy_lcu_to_cu_data(const encoder_state_t * const state, int x_px, i
// Use top-left sub-cu of LCU as pointer to lcu->cu array to make things
// simpler.
const cu_info_t *const lcu_cu = &lcu->cu[LCU_CU_OFFSET];
const cu_info_t *const lcu_cu = LCU_GET_CU(lcu, 0, 0);
int x, y;
for (y = 0; y < LCU_CU_WIDTH; ++y) {

View file

@ -962,9 +962,7 @@ int kvz_search_cu_inter(const encoder_state_t * const state, int x, int y, int d
int x_local = (x&0x3f), y_local = (y&0x3f);
int x_cu = x>>3;
int y_cu = y>>3;
int cu_pos = LCU_CU_OFFSET+(x_local>>3) + (y_local>>3)*LCU_T_CU_WIDTH;
cu_info_t *cur_cu = &lcu->cu[cu_pos];
cu_info_t *cur_cu = LCU_GET_CU(lcu, x_local >> 3, y_local >> 3);
int16_t mv_cand[2][2];
// Search for merge mode candidate

View file

@ -146,7 +146,7 @@ static double search_intra_trdepth(encoder_state_t * const state,
const int offset = width / 2;
const vector2d_t lcu_px = { x_px & 0x3f, y_px & 0x3f };
cu_info_t *const tr_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + (lcu_px.y >> 3)*LCU_T_CU_WIDTH];
cu_info_t *const tr_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
const bool reconstruct_chroma = !(x_px & 4 || y_px & 4);
@ -610,7 +610,7 @@ int8_t kvz_search_intra_chroma_rdo(encoder_state_t * const state,
if (reconstruct_chroma) {
const vector2d_t lcu_px = { x_px & 0x3f, y_px & 0x3f };
cu_info_t *const tr_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + (lcu_px.y >> 3)*LCU_T_CU_WIDTH];
cu_info_t *const tr_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
struct {
double cost;
@ -647,9 +647,8 @@ int8_t kvz_search_cu_intra_chroma(encoder_state_t * const state,
{
const vector2d_t lcu_px = { x_px & 0x3f, y_px & 0x3f };
const vector2d_t lcu_cu = { lcu_px.x >> 3, lcu_px.y >> 3 };
const int cu_index = LCU_CU_OFFSET + lcu_cu.x + lcu_cu.y * LCU_T_CU_WIDTH;
cu_info_t *cur_cu = &lcu->cu[cu_index];
cu_info_t *cur_cu = LCU_GET_CU(lcu, lcu_cu.x, lcu_cu.y);
int8_t intra_mode = cur_cu->intra[PU_INDEX(x_px >> 2, y_px >> 2)].mode;
double costs[5];
@ -713,10 +712,9 @@ double kvz_search_cu_intra(encoder_state_t * const state,
const vector2d_t lcu_px = { x_px & 0x3f, y_px & 0x3f };
const vector2d_t lcu_cu = { lcu_px.x >> 3, lcu_px.y >> 3 };
const int8_t cu_width = (LCU_WIDTH >> (depth));
const int cu_index = LCU_CU_OFFSET + lcu_cu.x + lcu_cu.y * LCU_T_CU_WIDTH;
const int_fast8_t log2_width = LOG2_LCU_WIDTH - depth;
cu_info_t *cur_cu = &lcu->cu[cu_index];
cu_info_t *cur_cu = LCU_GET_CU(lcu, lcu_cu.x, lcu_cu.y);
kvz_intra_references refs;
@ -728,10 +726,10 @@ double kvz_search_cu_intra(encoder_state_t * const state,
// Select left and top CUs if they are available.
// Top CU is not available across LCU boundary.
if ((x_px >> 3) > 0) {
left_cu = &lcu->cu[cu_index - 1];
left_cu = LCU_GET_CU(lcu, lcu_cu.x - 1, lcu_cu.y);
}
if ((y_px >> 3) > 0 && lcu_cu.y != 0) {
above_cu = &lcu->cu[cu_index - LCU_T_CU_WIDTH];
above_cu = LCU_GET_CU(lcu, lcu_cu.x, lcu_cu.y - 1);
}
kvz_intra_get_dir_luma_predictor(x_px, y_px, candidate_modes, cur_cu, left_cu, above_cu);

View file

@ -223,7 +223,7 @@ void kvz_quantize_lcu_luma_residual(encoder_state_t * const state, int32_t x, in
const vector2d_t lcu_px = {x & 0x3f, y & 0x3f};
const int pu_index = PU_INDEX(lcu_px.x / 4, lcu_px.y / 4);
if (cur_cu == NULL) {
cur_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + (lcu_px.y >> 3)*LCU_T_CU_WIDTH];
cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
}
const int8_t width = LCU_WIDTH>>depth;
@ -241,9 +241,9 @@ void kvz_quantize_lcu_luma_residual(encoder_state_t * const state, int32_t x, in
// Propagate coded block flags from child CUs to parent CU.
if (depth < MAX_DEPTH) {
cu_info_t *cu_a = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + (lcu_px.y >> 3) *LCU_T_CU_WIDTH];
cu_info_t *cu_b = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_c = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_a = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y);
cu_info_t *cu_b = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y + offset);
cu_info_t *cu_c = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y + offset);
if (cbf_is_set(cu_a->cbf.y, depth+1) || cbf_is_set(cu_b->cbf.y, depth+1) || cbf_is_set(cu_c->cbf.y, depth+1)) {
cbf_set(&cur_cu->cbf.y, depth);
}
@ -308,7 +308,7 @@ void kvz_quantize_lcu_chroma_residual(encoder_state_t * const state, int32_t x,
const int pu_index = PU_INDEX(lcu_px.x / 4, lcu_px.y / 4);
const int8_t width = LCU_WIDTH>>depth;
if (cur_cu == NULL) {
cur_cu = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + (lcu_px.y >> 3)*LCU_T_CU_WIDTH];
cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
}
// Tell clang-analyzer what is up. For some reason it can't figure out from
@ -325,9 +325,9 @@ void kvz_quantize_lcu_chroma_residual(encoder_state_t * const state, int32_t x,
// Propagate coded block flags from child CUs to parent CU.
if (depth < MAX_DEPTH) {
cu_info_t *cu_a = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + (lcu_px.y >> 3) *LCU_T_CU_WIDTH];
cu_info_t *cu_b = &lcu->cu[LCU_CU_OFFSET + (lcu_px.x >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_c = &lcu->cu[LCU_CU_OFFSET + ((lcu_px.x + offset) >> 3) + ((lcu_px.y + offset) >> 3)*LCU_T_CU_WIDTH];
cu_info_t *cu_a = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y);
cu_info_t *cu_b = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y + offset);
cu_info_t *cu_c = LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y + offset);
if (cbf_is_set(cu_a->cbf.u, depth+1) || cbf_is_set(cu_b->cbf.u, depth+1) || cbf_is_set(cu_c->cbf.u, depth+1)) {
cbf_set(&cur_cu->cbf.u, depth);
}