mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 10:34:05 +00:00
Fix bugs
This commit is contained in:
parent
50e9acd3f4
commit
13e605153a
92
src/filter.c
92
src/filter.c
|
@ -360,8 +360,8 @@ static INLINE int kvz_filter_deblock_large_block(kvz_pixel *line, kvz_pixel *lin
|
||||||
const int coeffs5[5] = { 58, 45, 32, 19, 6 };
|
const int coeffs5[5] = { 58, 45, 32, 19, 6 };
|
||||||
const int coeffs3[3] = { 53, 32, 11 };
|
const int coeffs3[3] = { 53, 32, 11 };
|
||||||
|
|
||||||
int *coeffs_P;
|
const int *coeffs_P = NULL;
|
||||||
int *coeffs_Q;
|
const int *coeffs_Q = NULL;
|
||||||
|
|
||||||
//Form P/Q arrays that contain all of the samples to make things simpler later
|
//Form P/Q arrays that contain all of the samples to make things simpler later
|
||||||
const kvz_pixel* lineP[8] = { line + 3, line + 2, line + 1, line + 0,
|
const kvz_pixel* lineP[8] = { line + 3, line + 2, line + 1, line + 0,
|
||||||
|
@ -462,7 +462,7 @@ static INLINE int kvz_filter_deblock_large_block(kvz_pixel *line, kvz_pixel *lin
|
||||||
|
|
||||||
for (size_t i = 0; i < filter_length_Q; i++)
|
for (size_t i = 0; i < filter_length_Q; i++)
|
||||||
{
|
{
|
||||||
int range = (tc * tc_coeff_P[i]) >> 1;
|
int range = (tc * tc_coeff_Q[i]) >> 1;
|
||||||
*dstQ[i] = CLIP(*lineQ[i] - range, *lineQ[i] + range, (ref_middle * coeffs_Q[i] + ref_Q * (64 - coeffs_Q[i]) + 32) >> 6);
|
*dstQ[i] = CLIP(*lineQ[i] - range, *lineQ[i] + range, (ref_middle * coeffs_Q[i] + ref_Q * (64 - coeffs_Q[i]) + 32) >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,14 +472,14 @@ static INLINE int kvz_filter_deblock_large_block(kvz_pixel *line, kvz_pixel *lin
|
||||||
/**
|
/**
|
||||||
* \brief Determine if strong or weak filtering should be used
|
* \brief Determine if strong or weak filtering should be used
|
||||||
*/
|
*/
|
||||||
static INLINE bool use_strong_filtering(const kvz_pixel const* b0, const kvz_pixel const* b3,
|
static INLINE bool use_strong_filtering(const kvz_pixel * const b0, const kvz_pixel * const b3,
|
||||||
const kvz_pixel const* b0L, const kvz_pixel const* b3L,
|
const kvz_pixel * const b0L, const kvz_pixel * const b3L,
|
||||||
const int_fast32_t dp0, const int_fast32_t dq0,
|
const int_fast32_t dp0, const int_fast32_t dq0,
|
||||||
const int_fast32_t dp3, const int_fast32_t dq3,
|
const int_fast32_t dp3, const int_fast32_t dq3,
|
||||||
const int32_t tc, const int32_t beta,
|
const int32_t tc, const int32_t beta,
|
||||||
const bool is_side_P_large, const bool is_side_Q_large,
|
const bool is_side_P_large, const bool is_side_Q_large,
|
||||||
const uint8_t max_filter_length_P, const uint8_t max_filter_length_Q,
|
const uint8_t max_filter_length_P, const uint8_t max_filter_length_Q,
|
||||||
const is_chroma_CTB_boundary)
|
const bool is_chroma_CTB_boundary)
|
||||||
{
|
{
|
||||||
int_fast32_t sp0 = is_chroma_CTB_boundary ? abs(b0[2] - b0[3]) : abs(b0[0] - b0[3]);
|
int_fast32_t sp0 = is_chroma_CTB_boundary ? abs(b0[2] - b0[3]) : abs(b0[0] - b0[3]);
|
||||||
int_fast32_t sp3 = is_chroma_CTB_boundary ? abs(b3[2] - b3[3]) : abs(b3[0] - b3[3]);
|
int_fast32_t sp3 = is_chroma_CTB_boundary ? abs(b3[2] - b3[3]) : abs(b3[0] - b3[3]);
|
||||||
|
@ -533,46 +533,47 @@ static INLINE bool use_strong_filtering(const kvz_pixel const* b0, const kvz_pix
|
||||||
static INLINE void get_max_filter_length(uint8_t *filt_len_P, uint8_t *filt_len_Q,
|
static INLINE void get_max_filter_length(uint8_t *filt_len_P, uint8_t *filt_len_Q,
|
||||||
const encoder_state_t * const state, const uint32_t x, const uint32_t y,
|
const encoder_state_t * const state, const uint32_t x, const uint32_t y,
|
||||||
const edge_dir dir, const bool transform_edge,
|
const edge_dir dir, const bool transform_edge,
|
||||||
const int block_size, const int size_P_side, const int size_Q_side,
|
const int tu_size_P_side, const int tu_size_Q_side,
|
||||||
|
const int pu_pos, const int pu_size,
|
||||||
color_t comp)
|
color_t comp)
|
||||||
{
|
{
|
||||||
//const int size_P_side = 0;
|
//const int tu_size_P_side = 0;
|
||||||
//const int size_Q_side = 0;
|
//const int tu_size_Q_side = 0;
|
||||||
//const int size = 0;
|
//const int size = 0;
|
||||||
const int x_mul = dir == EDGE_HOR ? 0 : 1;
|
const int x_mul = dir == EDGE_HOR ? 0 : 1;
|
||||||
const int y_mul = dir == EDGE_HOR ? 1 : 0;
|
const int y_mul = dir == EDGE_HOR ? 1 : 0;
|
||||||
const int pos = (dir == EDGE_HOR ? y : x) % LCU_WIDTH;
|
const int pos = dir == EDGE_HOR ? y : x;
|
||||||
|
const int len = EDGE_HOR ? state->tile->frame->height : state->tile->frame->width;
|
||||||
//const bool transform_edge = is_tu_boundary(state, x, y, dir);
|
//const bool transform_edge = is_tu_boundary(state, x, y, dir);
|
||||||
bool transform_edge_4x4[2] = { false, false };
|
bool transform_edge_4x4[2] = { false, false };
|
||||||
bool transform_edge_8x8[2] = { false, false };
|
bool transform_edge_8x8[2] = { false, false };
|
||||||
if (pos > 0) {
|
|
||||||
transform_edge_4x4[0] = is_tu_boundary(state, x + x_mul * 4, y + y_mul * 4, dir);
|
if (pos >= 4) transform_edge_4x4[0] = is_tu_boundary(state, x - x_mul * 4, y - y_mul * 4, dir);
|
||||||
transform_edge_4x4[1] = is_tu_boundary(state, x - x_mul * 4, y - y_mul * 4, dir);
|
if (pos >= 8) transform_edge_8x8[0] = is_tu_boundary(state, x - x_mul * 8, y - y_mul * 8, dir);
|
||||||
transform_edge_8x8[0] = is_tu_boundary(state, x + x_mul * 8, y + y_mul * 8, dir);
|
if (pos + 4 < len) transform_edge_4x4[1] = is_tu_boundary(state, x + x_mul * 4, y + y_mul * 4, dir);
|
||||||
transform_edge_8x8[1] = is_tu_boundary(state, x - x_mul * 8, y - y_mul * 8, dir);
|
if (pos + 8 < len) transform_edge_8x8[1] = is_tu_boundary(state, x + x_mul * 8, y + y_mul * 8, dir);
|
||||||
}
|
|
||||||
|
|
||||||
if (comp == COLOR_Y) {
|
if (comp == COLOR_Y) {
|
||||||
if (size_P_side <= 4 && size_Q_side <= 4){
|
if (tu_size_P_side <= 4 && tu_size_Q_side <= 4){
|
||||||
*filt_len_P = 1;
|
*filt_len_P = 1;
|
||||||
*filt_len_Q = 1;
|
*filt_len_Q = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*filt_len_P = size_P_side >= 32 ? 7 : 3;
|
*filt_len_P = tu_size_P_side >= 32 ? 7 : 3;
|
||||||
*filt_len_Q = size_Q_side >= 32 ? 7 : 3;
|
*filt_len_Q = tu_size_Q_side >= 32 ? 7 : 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform_edge) {
|
if (transform_edge) {
|
||||||
*filt_len_Q = MIN(*filt_len_Q, 5);
|
*filt_len_Q = MIN(*filt_len_Q, 5);
|
||||||
if (pos > 0) {
|
if (pu_pos > 0) {
|
||||||
*filt_len_P = MIN(*filt_len_P, 5);
|
*filt_len_P = MIN(*filt_len_P, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pos > 0 && (transform_edge_4x4[0] || (pos + 4) >= block_size || transform_edge_4x4[1])) { //adjacent to transform edge (4x4 grid)
|
else if (pu_pos > 0 && (transform_edge_4x4[0] || (pu_pos + 4) >= pu_size || transform_edge_4x4[1])) { //adjacent to transform edge (4x4 grid)
|
||||||
*filt_len_P = 1;
|
*filt_len_P = 1;
|
||||||
*filt_len_Q = 1;
|
*filt_len_Q = 1;
|
||||||
}
|
}
|
||||||
else if (pos > 0 && (transform_edge_8x8[0] || (pos + 8) >= block_size || transform_edge_8x8[1])) { //adjacent to transform edge (8x8 grid)
|
else if (pu_pos > 0 && (pu_pos == 8 || transform_edge_8x8[0] || (pu_pos + 8) >= pu_size || transform_edge_8x8[1])) { //adjacent to transform edge (8x8 grid)
|
||||||
*filt_len_P = 2;
|
*filt_len_P = 2;
|
||||||
*filt_len_Q = 2;
|
*filt_len_Q = 2;
|
||||||
}
|
}
|
||||||
|
@ -582,8 +583,8 @@ static INLINE void get_max_filter_length(uint8_t *filt_len_P, uint8_t *filt_len_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*filt_len_P = (size_P_side >= 8 && size_Q_side >= 8) ? 3 : 1;
|
*filt_len_P = (tu_size_P_side >= 8 && tu_size_Q_side >= 8) ? 3 : 1;
|
||||||
*filt_len_Q = (size_P_side >= 8 && size_Q_side >= 8) ? 3 : 1;
|
*filt_len_Q = (tu_size_P_side >= 8 && tu_size_Q_side >= 8) ? 3 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,14 +662,16 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
|
||||||
// CUs on both sides of the edge
|
// CUs on both sides of the edge
|
||||||
cu_info_t *cu_p;
|
cu_info_t *cu_p;
|
||||||
cu_info_t *cu_q;
|
cu_info_t *cu_q;
|
||||||
|
int32_t y_coord = y;
|
||||||
|
int32_t x_coord = x;
|
||||||
{
|
{
|
||||||
if (dir == EDGE_VER) {
|
if (dir == EDGE_VER) {
|
||||||
int32_t y_coord = y + 4 * block_idx;
|
y_coord = y + 4 * block_idx;
|
||||||
cu_p = kvz_cu_array_at(frame->cu_array, x - 1, y_coord);
|
cu_p = kvz_cu_array_at(frame->cu_array, x - 1, y_coord);
|
||||||
cu_q = kvz_cu_array_at(frame->cu_array, x, y_coord);
|
cu_q = kvz_cu_array_at(frame->cu_array, x, y_coord);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int32_t x_coord = x + 4 * block_idx;
|
x_coord = x + 4 * block_idx;
|
||||||
cu_p = kvz_cu_array_at(frame->cu_array, x_coord, y - 1);
|
cu_p = kvz_cu_array_at(frame->cu_array, x_coord, y - 1);
|
||||||
cu_q = kvz_cu_array_at(frame->cu_array, x_coord, y );
|
cu_q = kvz_cu_array_at(frame->cu_array, x_coord, y );
|
||||||
}
|
}
|
||||||
|
@ -767,8 +770,20 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
|
||||||
bool is_side_Q_large = false;
|
bool is_side_Q_large = false;
|
||||||
uint8_t max_filter_length_P = 0;
|
uint8_t max_filter_length_P = 0;
|
||||||
uint8_t max_filter_length_Q = 0;
|
uint8_t max_filter_length_Q = 0;
|
||||||
get_max_filter_length(&max_filter_length_P, &max_filter_length_Q, state, x, y, dir, tu_boundary,
|
const int cu_size = LCU_WIDTH >> cu_q->depth;
|
||||||
LCU_WIDTH >> cu_p->tr_depth, LCU_WIDTH >> cu_q->tr_depth, length, COLOR_Y);
|
const int pu_part_idx = (y + PU_GET_H(cu_q->part_size, cu_size, 0) <= y_coord ?
|
||||||
|
1 + (kvz_part_mode_num_parts[cu_q->part_size] >> 2) : 0)
|
||||||
|
+ (x + PU_GET_W(cu_q->part_size, cu_size, 0) <= x_coord ? 1 : 0);
|
||||||
|
const int pu_size = dir == EDGE_HOR ? PU_GET_H(cu_q->part_size, cu_size, pu_part_idx)
|
||||||
|
: PU_GET_W(cu_q->part_size, cu_size, pu_part_idx);
|
||||||
|
const int pu_pos = dir == EDGE_HOR ? y_coord - PU_GET_Y(cu_q->part_size, cu_size, 0, pu_part_idx)
|
||||||
|
: x_coord - PU_GET_X(cu_q->part_size, cu_size, 0, pu_part_idx);
|
||||||
|
get_max_filter_length(&max_filter_length_P, &max_filter_length_Q, state,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
dir, tu_boundary,
|
||||||
|
LCU_WIDTH >> cu_p->tr_depth, LCU_WIDTH >> cu_q->tr_depth,
|
||||||
|
pu_pos, pu_size, COLOR_Y);
|
||||||
|
|
||||||
if (max_filter_length_P > 3) {
|
if (max_filter_length_P > 3) {
|
||||||
is_side_P_large = dir == EDGE_HOR && y % LCU_WIDTH == 0 ? false : true;
|
is_side_P_large = dir == EDGE_HOR && y % LCU_WIDTH == 0 ? false : true;
|
||||||
|
@ -860,10 +875,6 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
|
||||||
scatter_deblock_pixels(&bL[i][0] + diff_reach, x_stride, i * y_stride, diff_reach, edge_src + filter_reach + diff_reach);
|
scatter_deblock_pixels(&bL[i][0] + diff_reach, x_stride, i * y_stride, diff_reach, edge_src + filter_reach + diff_reach);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
is_side_P_large = false;
|
|
||||||
is_side_Q_large = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,8 +886,7 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
|
||||||
// Strong filtering flag checking.
|
// Strong filtering flag checking.
|
||||||
sw = use_strong_filtering(b[0], b[3], NULL, NULL,
|
sw = use_strong_filtering(b[0], b[3], NULL, NULL,
|
||||||
dp0, dq0, dp3, dq3, tc, beta,
|
dp0, dq0, dp3, dq3, tc, beta,
|
||||||
is_side_P_large, is_side_Q_large,
|
false, false, 7, 7, false);
|
||||||
max_filter_length_P, max_filter_length_Q, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read lines 1 and 2. Weak filtering doesn't use the outermost pixels
|
// Read lines 1 and 2. Weak filtering doesn't use the outermost pixels
|
||||||
|
@ -1015,7 +1025,7 @@ static void filter_deblock_edge_chroma(encoder_state_t * const state,
|
||||||
// +-- edge_src
|
// +-- edge_src
|
||||||
// v
|
// v
|
||||||
// line0 p3 p2 p1 p0 q0 q1 q2 q3
|
// line0 p3 p2 p1 p0 q0 q1 q2 q3
|
||||||
kvz_pixel *edge_src = &src[blk_idx * 4 * step];
|
kvz_pixel *edge_src = &src[component][blk_idx * 4 * step];
|
||||||
const uint8_t sub_sampling_shift = 0; //TODO: figure out the correct value
|
const uint8_t sub_sampling_shift = 0; //TODO: figure out the correct value
|
||||||
const uint8_t sss = sub_sampling_shift == 1 ? 1 : 3;
|
const uint8_t sss = sub_sampling_shift == 1 ? 1 : 3;
|
||||||
// Gather the lines of pixels required for the filter on/off decision.
|
// Gather the lines of pixels required for the filter on/off decision.
|
||||||
|
@ -1215,12 +1225,10 @@ static void filter_deblock_lcu_rightmost(encoder_state_t * const state,
|
||||||
*/
|
*/
|
||||||
//TODO: Things to check/fix for VVC:
|
//TODO: Things to check/fix for VVC:
|
||||||
// - Strength calculation to include average Luma level (Luma Adaptive Deblocing Filter LADF) (optional)
|
// - Strength calculation to include average Luma level (Luma Adaptive Deblocing Filter LADF) (optional)
|
||||||
// - Stronger Luma and chroma filters (i.e. large block filtering)
|
|
||||||
// - Deblocking strength for CIIP and IBC modes (CIIP/IBC not currently used)
|
// - Deblocking strength for CIIP and IBC modes (CIIP/IBC not currently used)
|
||||||
// - Handle new prediction modes (i.e. PLT) (PLT not currently used)
|
// - Handle new prediction modes (i.e. PLT) (PLT not currently used)
|
||||||
// - Luma deblocking on a 4x4 grid
|
// - Luma deblocking on a 4x4 grid
|
||||||
// - Deblocking filter for subblock boundaries
|
// - Deblocking filter for subblock boundaries
|
||||||
// - Account for small blocks (in chroma) and max filter lengths
|
|
||||||
// - Allow loop filtering across slice/tile boundaries?
|
// - Allow loop filtering across slice/tile boundaries?
|
||||||
void kvz_filter_deblock_lcu(encoder_state_t * const state, int x_px, int y_px)
|
void kvz_filter_deblock_lcu(encoder_state_t * const state, int x_px, int y_px)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue