mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-28 03:34:06 +00:00
Fix sao offsets. Reconstruction kind of works.
This commit is contained in:
parent
66fe302520
commit
31af7e3929
|
@ -792,6 +792,12 @@ typedef struct {
|
||||||
int offsets[NUM_SAO_EDGE_CATEGORIES];
|
int offsets[NUM_SAO_EDGE_CATEGORIES];
|
||||||
} sao_info;
|
} sao_info;
|
||||||
|
|
||||||
|
void init_sao_info(sao_info *sao) {
|
||||||
|
sao->type = SAO_TYPE_NONE;
|
||||||
|
sao->merge_left_flag = 0;
|
||||||
|
sao->merge_up_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//#define SIGN3(x) ((x) > 0) ? +1 : ((x) == 0 ? 0 : -1)
|
//#define SIGN3(x) ((x) > 0) ? +1 : ((x) == 0 ? 0 : -1)
|
||||||
#define SIGN3(x) (((x) > 0) - ((x) < 0))
|
#define SIGN3(x) (((x) > 0) - ((x) < 0))
|
||||||
#define NUM_SAO_EDGE_DIRS 4;
|
#define NUM_SAO_EDGE_DIRS 4;
|
||||||
|
@ -807,10 +813,10 @@ typedef struct {
|
||||||
// | a c b | c | c | c |
|
// | a c b | c | c | c |
|
||||||
// | | b | b | b |
|
// | | b | b | b |
|
||||||
static const vector2d g_sao_edge_offsets[4][2] = {
|
static const vector2d g_sao_edge_offsets[4][2] = {
|
||||||
{ { 0, -1 }, { 0, 1 } },
|
|
||||||
{ { -1, 0 }, { 1, 0 } },
|
{ { -1, 0 }, { 1, 0 } },
|
||||||
|
{ { 0, -1 }, { 0, 1 } },
|
||||||
{ { -1, -1 }, { 1, 1 } },
|
{ { -1, -1 }, { 1, 1 } },
|
||||||
{ { -1, 1 }, { 1, -1 } }
|
{ { 1, -1 }, { -1, 1 } }
|
||||||
};
|
};
|
||||||
// Mapping of edge_idx values to eo-classes.
|
// Mapping of edge_idx values to eo-classes.
|
||||||
static const unsigned g_sao_eo_idx_to_eo_category[] = { 1, 2, 0, 3, 4 };
|
static const unsigned g_sao_eo_idx_to_eo_category[] = { 1, 2, 0, 3, 4 };
|
||||||
|
@ -850,7 +856,7 @@ void calc_sao_edge_dir(const pixel *orig_data, const pixel *rec_data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sao_reconstruct_color(pixel *rec_data, const sao_info *sao, int block_width)
|
void sao_reconstruct_color(const pixel *rec_data, pixel *new_rec_data, const sao_info *sao, int block_width)
|
||||||
{
|
{
|
||||||
int y, x;
|
int y, x;
|
||||||
vector2d a_ofs = g_sao_edge_offsets[sao->eo_class][0];
|
vector2d a_ofs = g_sao_edge_offsets[sao->eo_class][0];
|
||||||
|
@ -861,7 +867,8 @@ void sao_reconstruct_color(pixel *rec_data, const sao_info *sao, int block_width
|
||||||
// their neighbours.
|
// their neighbours.
|
||||||
for (y = 1; y < block_width - 1; ++y) {
|
for (y = 1; y < block_width - 1; ++y) {
|
||||||
for (x = 1; x < block_width - 1; ++x) {
|
for (x = 1; x < block_width - 1; ++x) {
|
||||||
pixel *c_data = &rec_data[y * block_width + x];
|
const pixel *c_data = &rec_data[y * block_width + x];
|
||||||
|
pixel *new_data = &new_rec_data[y * block_width + x];
|
||||||
pixel a = c_data[a_ofs.y * block_width + a_ofs.x];
|
pixel a = c_data[a_ofs.y * block_width + a_ofs.x];
|
||||||
pixel c = c_data[0];
|
pixel c = c_data[0];
|
||||||
pixel b = c_data[b_ofs.y * block_width + b_ofs.x];
|
pixel b = c_data[b_ofs.y * block_width + b_ofs.x];
|
||||||
|
@ -869,7 +876,7 @@ void sao_reconstruct_color(pixel *rec_data, const sao_info *sao, int block_width
|
||||||
int eo_idx = EO_IDX(a, b, c);
|
int eo_idx = EO_IDX(a, b, c);
|
||||||
int eo_cat = g_sao_eo_idx_to_eo_category[eo_idx];
|
int eo_cat = g_sao_eo_idx_to_eo_category[eo_idx];
|
||||||
|
|
||||||
c_data[0] += sao->offsets[eo_cat];
|
new_data[0] = CLIP(0, (1 << BIT_DEPTH) - 1, c_data[0] + sao->offsets[eo_cat]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -878,18 +885,19 @@ void sao_reconstruct(picture *pic, unsigned x_ctb, unsigned y_ctb,
|
||||||
const sao_info *sao_luma, const sao_info *sao_chroma)
|
const sao_info *sao_luma, const sao_info *sao_chroma)
|
||||||
{
|
{
|
||||||
pixel rec_y[LCU_LUMA_SIZE];
|
pixel rec_y[LCU_LUMA_SIZE];
|
||||||
|
pixel new_rec_y[LCU_LUMA_SIZE];
|
||||||
pixel *y_recdata = &pic->y_recdata[CU_TO_PIXEL(x_ctb, y_ctb, 0, pic->width)];
|
pixel *y_recdata = &pic->y_recdata[CU_TO_PIXEL(x_ctb, y_ctb, 0, pic->width)];
|
||||||
// TODO: sao chroma reconstruct
|
// TODO: sao chroma reconstruct
|
||||||
|
|
||||||
// Data to tmp buffer.
|
// Data to tmp buffer.
|
||||||
picture_blit_pixels(y_recdata, rec_y, LCU_WIDTH, LCU_WIDTH, pic->width, LCU_WIDTH);
|
picture_blit_pixels(y_recdata, rec_y, LCU_WIDTH, LCU_WIDTH, pic->width, LCU_WIDTH);
|
||||||
|
|
||||||
sao_reconstruct_color(rec_y, sao_luma, LCU_WIDTH);
|
sao_reconstruct_color(rec_y, new_rec_y, sao_luma, LCU_WIDTH);
|
||||||
//sao_reconstruct_color(rec_u, sao_chroma, COLOR_U);
|
//sao_reconstruct_color(rec_u, sao_chroma, COLOR_U);
|
||||||
//sao_reconstruct_color(rec_v, sao_chroma, COLOR_V);
|
//sao_reconstruct_color(rec_v, sao_chroma, COLOR_V);
|
||||||
|
|
||||||
// Copy reconstructed block from tmp buffer to rec image.
|
// Copy reconstructed block from tmp buffer to rec image.
|
||||||
picture_blit_pixels(rec_y, y_recdata, LCU_WIDTH, LCU_WIDTH, LCU_WIDTH, pic->width);
|
picture_blit_pixels(new_rec_y, y_recdata, LCU_WIDTH, LCU_WIDTH, LCU_WIDTH, pic->width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sao_search_best_mode(const pixel *data, const pixel *recdata,
|
void sao_search_best_mode(const pixel *data, const pixel *recdata,
|
||||||
|
@ -948,16 +956,12 @@ void sao_search_best_mode(const pixel *data, const pixel *recdata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sao_info sao_search_chroma(const picture *pic, unsigned x_ctb, unsigned y_ctb)
|
void sao_search_chroma(const picture *pic, unsigned x_ctb, unsigned y_ctb, sao_info *sao)
|
||||||
{
|
{
|
||||||
sao_info sao;
|
|
||||||
sao.merge_left_flag = 0;
|
|
||||||
sao.merge_up_flag = 0;
|
|
||||||
sao.type = SAO_TYPE_NONE;
|
|
||||||
return sao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sao_info sao_search_luma(const picture *pic, unsigned x_ctb, unsigned y_ctb)
|
void sao_search_luma(const picture *pic, unsigned x_ctb, unsigned y_ctb, sao_info *sao)
|
||||||
{
|
{
|
||||||
// These buffers are needed only until we switch to a LCU based data
|
// These buffers are needed only until we switch to a LCU based data
|
||||||
// structure for pixels. Then we can give pointers directly to that structure
|
// structure for pixels. Then we can give pointers directly to that structure
|
||||||
|
@ -968,18 +972,20 @@ sao_info sao_search_luma(const picture *pic, unsigned x_ctb, unsigned y_ctb)
|
||||||
pixel *y_data = &pic->y_data[CU_TO_PIXEL(x_ctb, y_ctb, 0, pic->width)];
|
pixel *y_data = &pic->y_data[CU_TO_PIXEL(x_ctb, y_ctb, 0, pic->width)];
|
||||||
pixel *y_recdata = &pic->y_recdata[CU_TO_PIXEL(x_ctb, y_ctb, 0, pic->width)];
|
pixel *y_recdata = &pic->y_recdata[CU_TO_PIXEL(x_ctb, y_ctb, 0, pic->width)];
|
||||||
|
|
||||||
sao_info sao;
|
sao->offsets[SAO_EO_CAT0] = 0;
|
||||||
sao.merge_left_flag = 0;
|
sao->offsets[SAO_EO_CAT1] = 7;
|
||||||
sao.merge_up_flag = 0;
|
sao->offsets[SAO_EO_CAT2] = 7;
|
||||||
sao.type = SAO_TYPE_EDGE;
|
sao->offsets[SAO_EO_CAT3] = -7;
|
||||||
|
sao->offsets[SAO_EO_CAT4] = -7;
|
||||||
|
sao->eo_class = SAO_EO0;
|
||||||
|
sao->type = SAO_TYPE_EDGE;
|
||||||
|
return;
|
||||||
|
|
||||||
// Fill temporary buffers with picture data.
|
// Fill temporary buffers with picture data.
|
||||||
picture_blit_pixels(y_data, orig_y, LCU_WIDTH, LCU_WIDTH, pic->width, LCU_WIDTH);
|
picture_blit_pixels(y_data, orig_y, LCU_WIDTH, LCU_WIDTH, pic->width, LCU_WIDTH);
|
||||||
picture_blit_pixels(y_recdata, rec_y, LCU_WIDTH, LCU_WIDTH, pic->width, LCU_WIDTH);
|
picture_blit_pixels(y_recdata, rec_y, LCU_WIDTH, LCU_WIDTH, pic->width, LCU_WIDTH);
|
||||||
|
|
||||||
sao_search_best_mode(orig_y, rec_y, LCU_WIDTH, LCU_LUMA_SIZE, 1, &sao);
|
sao_search_best_mode(orig_y, rec_y, LCU_WIDTH, LCU_LUMA_SIZE, 1, sao);
|
||||||
|
|
||||||
return sao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void encode_sao_color(encoder_control *encoder, sao_info *sao, color_index color_i)
|
void encode_sao_color(encoder_control *encoder, sao_info *sao, color_index color_i)
|
||||||
|
@ -1087,13 +1093,25 @@ void encode_slice_data(encoder_control* encoder)
|
||||||
uint8_t depth = 0;
|
uint8_t depth = 0;
|
||||||
|
|
||||||
if (encoder->sao_enable) {
|
if (encoder->sao_enable) {
|
||||||
sao_info sao_luma = sao_search_luma(encoder->in.cur_pic, x_ctb, y_ctb);
|
sao_info sao_luma;
|
||||||
sao_info sao_chroma = sao_search_chroma(encoder->in.cur_pic, x_ctb, y_ctb);
|
sao_info sao_chroma;
|
||||||
|
init_sao_info(&sao_luma);
|
||||||
|
init_sao_info(&sao_chroma);
|
||||||
|
|
||||||
// sao_do_merge(encoder, x_ctb, y_ctb, sao_luma, sao_chroma);
|
// Temporary guards against non-LCU size coding units at the edges,
|
||||||
// sao_do_rdo(encoder, x_ctb, y_ctb, sao_luma, sao_chroma);
|
// because they aren't handled yet.
|
||||||
|
if (encoder->in.width_in_lcu * LCU_WIDTH != encoder->in.cur_pic->width
|
||||||
|
&& x_ctb == encoder->in.width_in_lcu - 1) {
|
||||||
|
|
||||||
sao_reconstruct(encoder->in.cur_pic, x_ctb, y_ctb, &sao_luma, &sao_chroma);
|
} else if (encoder->in.height_in_lcu * LCU_WIDTH != encoder->in.cur_pic->height
|
||||||
|
&& y_ctb == encoder->in.height_in_lcu - 1) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sao_search_luma(encoder->in.cur_pic, x_ctb, y_ctb, &sao_luma);
|
||||||
|
// sao_do_merge(encoder, x_ctb, y_ctb, sao_luma, sao_chroma);
|
||||||
|
// sao_do_rdo(encoder, x_ctb, y_ctb, sao_luma, sao_chroma);
|
||||||
|
sao_reconstruct(encoder->in.cur_pic, x_ctb, y_ctb, &sao_luma, &sao_chroma);
|
||||||
|
}
|
||||||
|
|
||||||
encode_sao(encoder, x_ctb, y_ctb, &sao_luma, &sao_chroma);
|
encode_sao(encoder, x_ctb, y_ctb, &sao_luma, &sao_chroma);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue