staticvoid generate_grain_y_c(entry buf[][GRAIN_WIDTH], const Dav1dFilmGrainData *const data
HIGHBD_DECL_SUFFIX)
{ const int bitdepth_min_8 = bitdepth_from_max(bitdepth_max) - 8; unsigned seed = data->seed; const int shift = 4 - bitdepth_min_8 + data->grain_scale_shift; const int grain_ctr = 128 << bitdepth_min_8; const int grain_min = -grain_ctr, grain_max = grain_ctr - 1;
for (int y = 0; y < GRAIN_HEIGHT; y++) {
for (int x = 0; x < GRAIN_WIDTH; x++) { const int value = get_random_number(11, &seed);
buf[y][x] = round2(dav1d_gaussian_sequence[ value ], shift);
}
}
const int ar_pad = 3; const int ar_lag = data->ar_coeff_lag;
for (int y = ar_pad; y < GRAIN_HEIGHT; y++) {
for (int x = ar_pad; x < GRAIN_WIDTH - ar_pad; x++) { const int8_t *coeff = data->ar_coeffs_y;
int sum = 0;
for (int dy = -ar_lag; dy <= 0; dy++) {
for (int dx = -ar_lag; dx <= ar_lag; dx++) {
if (!dx && !dy) break;
sum += *(coeff++) * buf[y + dy][x + dx];
}
}
const int chromaW = subx ? SUB_GRAIN_WIDTH : GRAIN_WIDTH; const int chromaH = suby ? SUB_GRAIN_HEIGHT : GRAIN_HEIGHT;
for (int y = 0; y < chromaH; y++) {
for (int x = 0; x < chromaW; x++) { const int value = get_random_number(11, &seed);
buf[y][x] = round2(dav1d_gaussian_sequence[ value ], shift);
}
}
const int ar_pad = 3; const int ar_lag = data->ar_coeff_lag;
for (int y = ar_pad; y < chromaH; y++) {
for (int x = ar_pad; x < chromaW - ar_pad; x++) { const int8_t *coeff = data->ar_coeffs_uv[uv];
int sum = 0;
for (int dy = -ar_lag; dy <= 0; dy++) {
for (int dx = -ar_lag; dx <= ar_lag; dx++) { // For the final (current) pixel, we need to add in the // contribution from the luma grain texture
if (!dx && !dy) {
if (!data->num_y_points) break;
int luma = 0; const int lumaX = ((x - ar_pad) << subx) + ar_pad; const int lumaY = ((y - ar_pad) << suby) + ar_pad;
for (int i = 0; i <= suby; i++) {
for (int j = 0; j <= subx; j++) {
luma += buf_y[lumaY + i][lumaX + j];
}
}
luma = round2(luma, subx + suby);
sum += luma * (*coeff); break;
}
// samples from the correct block of a grain LUT, while taking into account the // offsets provided by the offsets cache static inline entry sample_lut(const entry grain_lut[][GRAIN_WIDTH], const int offsets[2][2], const int subx, const int suby, const int bx, const int by, const int x, const int y)
{ const int randval = offsets[bx][by]; const int offx = 3 + (2 >> subx) * (3 + (randval >> 4)); const int offy = 3 + (2 >> suby) * (3 + (randval & 0xF)); return grain_lut[offy + y + (FG_BLOCK_SIZE >> suby) * by]
[offx + x + (FG_BLOCK_SIZE >> subx) * bx];
}
for (int y = ystart; y < bh; y++) { // Non-overlapped image region (straightforward)
for (int x = xstart; x < bw; x++) {
int grain = sample_lut(grain_lut, offsets, 0, 0, 0, 0, x, y);
add_noise_y(x, y, grain);
}
// Special case for overlapped column
for (int x = 0; x < xstart; x++) {
int grain = sample_lut(grain_lut, offsets, 0, 0, 0, 0, x, y);
int old = sample_lut(grain_lut, offsets, 0, 0, 1, 0, x, y);
grain = round2(old * w[x][0] + grain * w[x][1], 5);
grain = iclip(grain, grain_min, grain_max);
add_noise_y(x, y, grain);
}
}
for (int y = 0; y < ystart; y++) { // Special case for overlapped row (sans corner)
for (int x = xstart; x < bw; x++) {
int grain = sample_lut(grain_lut, offsets, 0, 0, 0, 0, x, y);
int old = sample_lut(grain_lut, offsets, 0, 0, 0, 1, x, y);
grain = round2(old * w[y][0] + grain * w[y][1], 5);
grain = iclip(grain, grain_min, grain_max);
add_noise_y(x, y, grain);
}
// Special case for doubly-overlapped corner
for (int x = 0; x < xstart; x++) { // Blend the top pixel with the top left block
int top = sample_lut(grain_lut, offsets, 0, 0, 0, 1, x, y);
int old = sample_lut(grain_lut, offsets, 0, 0, 1, 1, x, y);
top = round2(old * w[x][0] + top * w[x][1], 5);
top = iclip(top, grain_min, grain_max);
// Blend the current pixel with the left block
int grain = sample_lut(grain_lut, offsets, 0, 0, 0, 0, x, y);
old = sample_lut(grain_lut, offsets, 0, 0, 1, 0, x, y);
grain = round2(old * w[x][0] + grain * w[x][1], 5);
grain = iclip(grain, grain_min, grain_max);
// Mix the row rows together and apply grain
grain = round2(top * w[y][0] + grain * w[y][1], 5);
grain = iclip(grain, grain_min, grain_max);
add_noise_y(x, y, grain);
}
}
}
}
static NOINLINE void
fguv_32x32xn_c(pixel *const dst_row, const pixel *const src_row, const ptrdiff_t stride, const Dav1dFilmGrainData *const data, const size_t pw, const uint8_t scaling[SCALING_SIZE], const entry grain_lut[][GRAIN_WIDTH], const int bh, const int row_num, const pixel *const luma_row, const ptrdiff_t luma_stride, const int uv, const int is_id, const int sx, const int sy HIGHBD_DECL_SUFFIX)
{ const int rows = 1 + (data->overlap_flag && row_num > 0); const int bitdepth_min_8 = bitdepth_from_max(bitdepth_max) - 8; const int grain_ctr = 128 << bitdepth_min_8; const int grain_min = -grain_ctr, grain_max = grain_ctr - 1;
for (int y = ystart; y < bh; y++) { // Non-overlapped image region (straightforward)
for (int x = xstart; x < bw; x++) {
int grain = sample_lut(grain_lut, offsets, sx, sy, 0, 0, x, y);
add_noise_uv(x, y, grain);
}
// Special case for overlapped column
for (int x = 0; x < xstart; x++) {
int grain = sample_lut(grain_lut, offsets, sx, sy, 0, 0, x, y);
int old = sample_lut(grain_lut, offsets, sx, sy, 1, 0, x, y);
grain = round2(old * w[sx][x][0] + grain * w[sx][x][1], 5);
grain = iclip(grain, grain_min, grain_max);
add_noise_uv(x, y, grain);
}
}
for (int y = 0; y < ystart; y++) { // Special case for overlapped row (sans corner)
for (int x = xstart; x < bw; x++) {
int grain = sample_lut(grain_lut, offsets, sx, sy, 0, 0, x, y);
int old = sample_lut(grain_lut, offsets, sx, sy, 0, 1, x, y);
grain = round2(old * w[sy][y][0] + grain * w[sy][y][1], 5);
grain = iclip(grain, grain_min, grain_max);
add_noise_uv(x, y, grain);
}
// Special case for doubly-overlapped corner
for (int x = 0; x < xstart; x++) { // Blend the top pixel with the top left block
int top = sample_lut(grain_lut, offsets, sx, sy, 0, 1, x, y);
int old = sample_lut(grain_lut, offsets, sx, sy, 1, 1, x, y);
top = round2(old * w[sx][x][0] + top * w[sx][x][1], 5);
top = iclip(top, grain_min, grain_max);
// Blend the current pixel with the left block
int grain = sample_lut(grain_lut, offsets, sx, sy, 0, 0, x, y);
old = sample_lut(grain_lut, offsets, sx, sy, 1, 0, x, y);
grain = round2(old * w[sx][x][0] + grain * w[sx][x][1], 5);
grain = iclip(grain, grain_min, grain_max);
// Mix the row rows together and apply to image
grain = round2(top * w[sy][y][0] + grain * w[sy][y][1], 5);
grain = iclip(grain, grain_min, grain_max);
add_noise_uv(x, y, grain);
}
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.