Commit 20be5450 authored by Andrey Norkin's avatar Andrey Norkin

[NORMATIVE] Monochrome support in film grain

BUG=aomedia:1346

Change-Id: I4247f1387022cfd3b69116f6f259eebbf61db791
parent 9a74bb68
......@@ -246,7 +246,8 @@ static void init_arrays(aom_film_grain_t *params, int luma_stride,
memset(scaling_lut_cr, 0, sizeof(*scaling_lut_cr) * 256);
int num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
int num_pos_chroma = num_pos_luma + 1;
int num_pos_chroma = num_pos_luma;
if (params->num_y_points > 0) ++num_pos_chroma;
int **pred_pos_luma;
int **pred_pos_chroma;
......@@ -292,9 +293,11 @@ static void init_arrays(aom_film_grain_t *params, int luma_stride,
++pos_ar_index;
}
pred_pos_chroma[pos_ar_index][0] = 0;
pred_pos_chroma[pos_ar_index][1] = 0;
pred_pos_chroma[pos_ar_index][2] = 1;
if (params->num_y_points > 0) {
pred_pos_chroma[pos_ar_index][0] = 0;
pred_pos_chroma[pos_ar_index][1] = 0;
pred_pos_chroma[pos_ar_index][2] = 1;
}
*pred_pos_luma_p = pred_pos_luma;
*pred_pos_chroma_p = pred_pos_chroma;
......@@ -385,6 +388,8 @@ static void generate_luma_grain_block(
aom_film_grain_t *params, int **pred_pos_luma, int *luma_grain_block,
int luma_block_size_y, int luma_block_size_x, int luma_grain_stride,
int left_pad, int top_pad, int right_pad, int bottom_pad) {
if (params->num_y_points == 0) return;
int bit_depth = params->bit_depth;
int gauss_sec_shift = 12 - bit_depth + params->grain_scale_shift;
......@@ -424,20 +429,22 @@ static void generate_chroma_grain_blocks(
int bit_depth = params->bit_depth;
int gauss_sec_shift = 12 - bit_depth + params->grain_scale_shift;
int num_pos_chroma =
2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1) + 1;
int num_pos_chroma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
if (params->num_y_points > 0) ++num_pos_chroma;
int rounding_offset = (1 << (params->ar_coeff_shift - 1));
for (int i = 0; i < chroma_block_size_y; i++)
for (int j = 0; j < chroma_block_size_x; j++) {
cb_grain_block[i * chroma_grain_stride + j] =
(gaussian_sequence[get_random_number(gauss_bits)] +
((1 << gauss_sec_shift) >> 1)) >>
gauss_sec_shift;
cr_grain_block[i * chroma_grain_stride + j] =
(gaussian_sequence[get_random_number(gauss_bits)] +
((1 << gauss_sec_shift) >> 1)) >>
gauss_sec_shift;
if (params->num_cb_points)
cb_grain_block[i * chroma_grain_stride + j] =
(gaussian_sequence[get_random_number(gauss_bits)] +
((1 << gauss_sec_shift) >> 1)) >>
gauss_sec_shift;
if (params->num_cr_points)
cr_grain_block[i * chroma_grain_stride + j] =
(gaussian_sequence[get_random_number(gauss_bits)] +
((1 << gauss_sec_shift) >> 1)) >>
gauss_sec_shift;
}
for (int i = top_pad; i < chroma_block_size_y - bottom_pad; i++)
......@@ -480,14 +487,16 @@ static void generate_chroma_grain_blocks(
exit(1);
}
}
cb_grain_block[i * chroma_grain_stride + j] =
clamp(cb_grain_block[i * chroma_grain_stride + j] +
((wsum_cb + rounding_offset) >> params->ar_coeff_shift),
grain_min, grain_max);
cr_grain_block[i * chroma_grain_stride + j] =
clamp(cr_grain_block[i * chroma_grain_stride + j] +
((wsum_cr + rounding_offset) >> params->ar_coeff_shift),
grain_min, grain_max);
if (params->num_cb_points)
cb_grain_block[i * chroma_grain_stride + j] =
clamp(cb_grain_block[i * chroma_grain_stride + j] +
((wsum_cb + rounding_offset) >> params->ar_coeff_shift),
grain_min, grain_max);
if (params->num_cr_points)
cr_grain_block[i * chroma_grain_stride + j] =
clamp(cr_grain_block[i * chroma_grain_stride + j] +
((wsum_cr + rounding_offset) >> params->ar_coeff_shift),
grain_min, grain_max);
}
}
......@@ -545,6 +554,10 @@ static void add_noise_to_block(aom_film_grain_t *params, uint8_t *luma,
int rounding_offset = (1 << (params->scaling_shift - 1));
int apply_y = params->num_y_points > 0 ? 1 : 0;
int apply_cb = params->num_cb_points > 0 ? 1 : 0;
int apply_cr = params->num_cr_points > 0 ? 1 : 0;
if (params->chroma_scaling_from_luma) {
cb_mult = 0; // fixed scale
cb_luma_mult = 64; // fixed scale
......@@ -573,71 +586,78 @@ static void add_noise_to_block(aom_film_grain_t *params, uint8_t *luma,
int average_luma = (luma[(i << 1) * luma_stride + (j << 1)] +
luma[((i << 1)) * luma_stride + (j << 1) + 1] + 1) >>
1;
if (apply_y) {
luma[((i) << 1) * luma_stride + ((j) << 1)] = clamp(
luma[((i) << 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[((i) << 1) * luma_stride + ((j) << 1)], 8) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)],
8) *
luma_grain[((i << 1) + 1) * luma_grain_stride +
(j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1],
8) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1) + 1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(
scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1],
8) *
luma_grain[((i << 1) + 1) * luma_grain_stride + (j << 1) +
1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
}
luma[((i) << 1) * luma_stride + ((j) << 1)] = clamp(
luma[((i) << 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[((i) << 1) * luma_stride + ((j) << 1)], 8) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)],
8) *
luma_grain[((i << 1) + 1) * luma_grain_stride + (j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1],
8) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1) + 1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1],
8) *
luma_grain[((i << 1) + 1) * luma_grain_stride + (j << 1) +
1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
cb[i * chroma_stride + j] =
clamp(cb[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cb,
clamp(((average_luma * cb_luma_mult +
cb_mult * cb[i * chroma_stride + j]) >>
6) +
cb_offset,
0, (256 << (bit_depth - 8)) - 1),
8) *
cb_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
cr[i * chroma_stride + j] =
clamp(cr[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cr,
clamp(((average_luma * cr_luma_mult +
cr_mult * cr[i * chroma_stride + j]) >>
6) +
cr_offset,
0, (256 << (bit_depth - 8)) - 1),
8) *
cr_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
if (apply_cb) {
cb[i * chroma_stride + j] = clamp(
cb[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cb,
clamp(((average_luma * cb_luma_mult +
cb_mult * cb[i * chroma_stride + j]) >>
6) +
cb_offset,
0, (256 << (bit_depth - 8)) - 1),
8) *
cb_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
}
if (apply_cr) {
cr[i * chroma_stride + j] = clamp(
cr[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cr,
clamp(((average_luma * cr_luma_mult +
cr_mult * cr[i * chroma_stride + j]) >>
6) +
cr_offset,
0, (256 << (bit_depth - 8)) - 1),
8) *
cr_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
}
}
}
}
......@@ -661,6 +681,10 @@ static void add_noise_to_block_hbd(aom_film_grain_t *params, uint16_t *luma,
int rounding_offset = (1 << (params->scaling_shift - 1));
int apply_y = params->num_y_points > 0 ? 1 : 0;
int apply_cb = params->num_cb_points > 0 ? 1 : 0;
int apply_cr = params->num_cr_points > 0 ? 1 : 0;
if (params->chroma_scaling_from_luma) {
cb_mult = 0; // fixed scale
cb_luma_mult = 64; // fixed scale
......@@ -689,72 +713,77 @@ static void add_noise_to_block_hbd(aom_film_grain_t *params, uint16_t *luma,
int average_luma = (luma[(i << 1) * luma_stride + (j << 1)] +
luma[((i << 1)) * luma_stride + (j << 1) + 1] + 1) >>
1;
luma[((i) << 1) * luma_stride + ((j) << 1)] =
clamp(luma[((i) << 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[((i) << 1) * luma_stride + ((j) << 1)],
bit_depth) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)],
bit_depth) *
luma_grain[((i << 1) + 1) * luma_grain_stride + (j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1],
bit_depth) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1) + 1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1],
bit_depth) *
luma_grain[((i << 1) + 1) * luma_grain_stride + (j << 1) +
1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
cb[i * chroma_stride + j] =
clamp(cb[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cb,
clamp(((average_luma * cb_luma_mult +
cb_mult * cb[i * chroma_stride + j]) >>
6) +
cb_offset,
0, (256 << (bit_depth - 8)) - 1),
bit_depth) *
cb_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
cr[i * chroma_stride + j] =
clamp(cr[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cr,
clamp(((average_luma * cr_luma_mult +
cr_mult * cr[i * chroma_stride + j]) >>
6) +
cr_offset,
0, (256 << (bit_depth - 8)) - 1),
bit_depth) *
cr_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
if (apply_y) {
luma[((i) << 1) * luma_stride + ((j) << 1)] = clamp(
luma[((i) << 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[((i) << 1) * luma_stride + ((j) << 1)],
bit_depth) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1)],
bit_depth) *
luma_grain[((i << 1) + 1) * luma_grain_stride +
(j << 1)] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(scaling_lut_y,
luma[(((i) << 1)) * luma_stride + ((j) << 1) + 1],
bit_depth) *
luma_grain[(i << 1) * luma_grain_stride + (j << 1) + 1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] = clamp(
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1] +
((scale_LUT(
scaling_lut_y,
luma[(((i) << 1) + 1) * luma_stride + ((j) << 1) + 1],
bit_depth) *
luma_grain[((i << 1) + 1) * luma_grain_stride + (j << 1) +
1] +
rounding_offset) >>
params->scaling_shift),
min_luma, max_luma);
}
if (apply_cb) {
cb[i * chroma_stride + j] = clamp(
cb[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cb,
clamp(((average_luma * cb_luma_mult +
cb_mult * cb[i * chroma_stride + j]) >>
6) +
cb_offset,
0, (256 << (bit_depth - 8)) - 1),
bit_depth) *
cb_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
}
if (apply_cr) {
cr[i * chroma_stride + j] = clamp(
cr[i * chroma_stride + j] +
((scale_LUT(scaling_lut_cr,
clamp(((average_luma * cr_luma_mult +
cr_mult * cr[i * chroma_stride + j]) >>
6) +
cr_offset,
0, (256 << (bit_depth - 8)) - 1),
bit_depth) *
cr_grain[i * chroma_grain_stride + j] +
rounding_offset) >>
params->scaling_shift),
min_chroma, max_chroma);
}
}
}
}
......
......@@ -2207,9 +2207,10 @@ void av1_read_film_grain_params(AV1_COMMON *cm,
pars->scaling_points_y[i][1] = aom_rb_read_literal(rb, 8);
}
pars->chroma_scaling_from_luma = aom_rb_read_bit(rb);
if (!cm->seq_params.monochrome)
pars->chroma_scaling_from_luma = aom_rb_read_bit(rb);
if (pars->chroma_scaling_from_luma) {
if (cm->seq_params.monochrome || pars->chroma_scaling_from_luma) {
pars->num_cb_points = 0;
pars->num_cr_points = 0;
} else {
......@@ -2253,7 +2254,8 @@ void av1_read_film_grain_params(AV1_COMMON *cm,
pars->ar_coeff_lag = aom_rb_read_literal(rb, 2);
int num_pos_luma = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
int num_pos_chroma = num_pos_luma + 1;
int num_pos_chroma = num_pos_luma;
if (pars->num_y_points > 0) ++num_pos_chroma;
if (pars->num_y_points)
for (int i = 0; i < num_pos_luma; i++)
......
......@@ -3223,11 +3223,12 @@ static void write_film_grain_params(AV1_COMMON *const cm,
aom_wb_write_literal(wb, pars->scaling_points_y[i][1], 8);
}
aom_wb_write_bit(wb, pars->chroma_scaling_from_luma);
if (!cm->seq_params.monochrome)
aom_wb_write_bit(wb, pars->chroma_scaling_from_luma);
if (pars->chroma_scaling_from_luma) {
assert(pars->num_cb_points == 0);
assert(pars->num_cr_points == 0);
if (cm->seq_params.monochrome || pars->chroma_scaling_from_luma) {
pars->num_cb_points = 0;
pars->num_cr_points = 0;
} else {
aom_wb_write_literal(wb, pars->num_cb_points, 4); // max 10
for (int i = 0; i < pars->num_cb_points; i++) {
......@@ -3251,7 +3252,8 @@ static void write_film_grain_params(AV1_COMMON *const cm,
aom_wb_write_literal(wb, pars->ar_coeff_lag, 2);
int num_pos_luma = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
int num_pos_chroma = num_pos_luma + 1;
int num_pos_chroma = num_pos_luma;
if (pars->num_y_points > 0) ++num_pos_chroma;
if (pars->num_y_points)
for (int i = 0; i < num_pos_luma; i++)
......
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