mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-28 03:34:06 +00:00
Add special handling for bottom right LCU pixel.
I didn't take into account that the reference pixel on the top-left of the LCU gets over written if we just replace the top reference pixels for current LCU with the bottom reference pixels after doing the search. To handle this I copy the pixel that gets overwritten to the vertical reference pixels.
This commit is contained in:
parent
57ce7e990b
commit
7328fc2897
|
@ -384,7 +384,9 @@ static void write_aud(encoder_control* encoder)
|
||||||
void encode_one_frame(encoder_control* encoder)
|
void encode_one_frame(encoder_control* encoder)
|
||||||
{
|
{
|
||||||
yuv_t *hor_buf = alloc_yuv_t(encoder->in.width);
|
yuv_t *hor_buf = alloc_yuv_t(encoder->in.width);
|
||||||
yuv_t *ver_buf = alloc_yuv_t(LCU_WIDTH);
|
// Allocate 2 extra luma pixels so we get 1 extra chroma pixel for the
|
||||||
|
// for the extra pixel on the top right.
|
||||||
|
yuv_t *ver_buf = alloc_yuv_t(LCU_WIDTH + 2);
|
||||||
|
|
||||||
const int is_first_frame = (encoder->frame == 0);
|
const int is_first_frame = (encoder->frame == 0);
|
||||||
const int is_i_radl = (encoder->cfg->intra_period == 1 && encoder->frame % 2 == 0);
|
const int is_i_radl = (encoder->cfg->intra_period == 1 && encoder->frame % 2 == 0);
|
||||||
|
@ -483,6 +485,14 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
|
|
||||||
search_lcu(encoder, px.x, px.y, hor_buf, ver_buf);
|
search_lcu(encoder, px.x, px.y, hor_buf, ver_buf);
|
||||||
|
|
||||||
|
// Take the bottom right pixel from the LCU above and put it as the
|
||||||
|
// first pixel in this LCUs rightmost pixels.
|
||||||
|
if (lcu.y > 0) {
|
||||||
|
ver_buf->y[0] = hor_buf->y[right - 1];
|
||||||
|
ver_buf->u[0] = hor_buf->u[right / 2 - 1];
|
||||||
|
ver_buf->v[0] = hor_buf->v[right / 2 - 1];
|
||||||
|
}
|
||||||
|
|
||||||
// Take bottom and right pixels from this LCU to be used on the search of next LCU.
|
// Take bottom and right pixels from this LCU to be used on the search of next LCU.
|
||||||
picture_blit_pixels(&pic->y_recdata[(bottom - 1) * size.x + px.x],
|
picture_blit_pixels(&pic->y_recdata[(bottom - 1) * size.x + px.x],
|
||||||
&hor_buf->y[px.x],
|
&hor_buf->y[px.x],
|
||||||
|
@ -495,13 +505,13 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
lcu_dim.x / 2, 1, size.x / 2, size.x / 2);
|
lcu_dim.x / 2, 1, size.x / 2, size.x / 2);
|
||||||
|
|
||||||
picture_blit_pixels(&pic->y_recdata[px.y * size.x + right - 1],
|
picture_blit_pixels(&pic->y_recdata[px.y * size.x + right - 1],
|
||||||
ver_buf->y,
|
&ver_buf->y[1],
|
||||||
1, lcu_dim.y, size.x, 1);
|
1, lcu_dim.y, size.x, 1);
|
||||||
picture_blit_pixels(&pic->u_recdata[px.y * size.x / 4 + (right / 2) - 1],
|
picture_blit_pixels(&pic->u_recdata[px.y * size.x / 4 + (right / 2) - 1],
|
||||||
ver_buf->u,
|
&ver_buf->u[1],
|
||||||
1, lcu_dim.y / 2, size.x / 2, 1);
|
1, lcu_dim.y / 2, size.x / 2, 1);
|
||||||
picture_blit_pixels(&pic->v_recdata[px.y * size.x / 4 + (right / 2) - 1],
|
picture_blit_pixels(&pic->v_recdata[px.y * size.x / 4 + (right / 2) - 1],
|
||||||
ver_buf->v,
|
&ver_buf->v[1],
|
||||||
1, lcu_dim.y / 2, size.x / 2, 1);
|
1, lcu_dim.y / 2, size.x / 2, 1);
|
||||||
|
|
||||||
//encode_lcu(encoder, x.px, y.px, hor_buf, ver_buf);
|
//encode_lcu(encoder, x.px, y.px, hor_buf, ver_buf);
|
||||||
|
|
|
@ -36,16 +36,22 @@
|
||||||
|
|
||||||
yuv_t * alloc_yuv_t(int luma_size)
|
yuv_t * alloc_yuv_t(int luma_size)
|
||||||
{
|
{
|
||||||
yuv_t * yuv = (yuv_t *)malloc(sizeof(yuv_t) + luma_size * sizeof(pixel) * 2);
|
// Get buffers with separate mallocs in order to take advantage of
|
||||||
|
// automatic buffer overrun checks.
|
||||||
|
yuv_t *yuv = (yuv_t *)malloc(sizeof(*yuv));
|
||||||
|
yuv->y = (pixel *)malloc(luma_size * sizeof(*yuv->y));
|
||||||
|
yuv->u = (pixel *)malloc(luma_size / 2 * sizeof(*yuv->u));
|
||||||
|
yuv->v = (pixel *)malloc(luma_size / 2 * sizeof(*yuv->v));
|
||||||
yuv->size = luma_size;
|
yuv->size = luma_size;
|
||||||
yuv->y = (pixel *)yuv + sizeof(yuv_t);
|
|
||||||
yuv->u = yuv->y + luma_size * sizeof(pixel);
|
|
||||||
yuv->v = yuv->u + luma_size / 2 * sizeof(pixel);
|
|
||||||
return yuv;
|
return yuv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dealloc_yuv_t(yuv_t * yuv)
|
void dealloc_yuv_t(yuv_t * yuv)
|
||||||
{
|
{
|
||||||
|
free(yuv->y);
|
||||||
|
free(yuv->u);
|
||||||
|
free(yuv->v);
|
||||||
free(yuv);
|
free(yuv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/search.c
10
src/search.c
|
@ -977,9 +977,9 @@ static void init_lcu_t(encoder_control *encoder, const int x, const int y, lcu_t
|
||||||
&lcu->left_ref.v[1],
|
&lcu->left_ref.v[1],
|
||||||
1, y_max_c, pic_width_c, 1);
|
1, y_max_c, pic_width_c, 1);
|
||||||
|
|
||||||
assert(!memcmp(ver_buf->y, &lcu->left_ref.y[1], y_max));
|
assert(!memcmp(&ver_buf->y[1], &lcu->left_ref.y[1], y_max));
|
||||||
assert(!memcmp(ver_buf->u, &lcu->left_ref.u[1], y_max_c));
|
assert(!memcmp(&ver_buf->u[1], &lcu->left_ref.u[1], y_max_c));
|
||||||
assert(!memcmp(ver_buf->v, &lcu->left_ref.v[1], y_max_c));
|
assert(!memcmp(&ver_buf->v[1], &lcu->left_ref.v[1], y_max_c));
|
||||||
}
|
}
|
||||||
// Copy top-left reference pixel.
|
// Copy top-left reference pixel.
|
||||||
if (x > 0 && y > 0) {
|
if (x > 0 && y > 0) {
|
||||||
|
@ -991,6 +991,10 @@ static void init_lcu_t(encoder_control *encoder, const int x, const int y, lcu_t
|
||||||
|
|
||||||
lcu->top_ref.v[0] = pic->v_recdata[(x_c - 1) + (y_c - 1) * pic_width_c];
|
lcu->top_ref.v[0] = pic->v_recdata[(x_c - 1) + (y_c - 1) * pic_width_c];
|
||||||
lcu->left_ref.v[0] = pic->v_recdata[(x_c - 1) + (y_c - 1) * pic_width_c];
|
lcu->left_ref.v[0] = pic->v_recdata[(x_c - 1) + (y_c - 1) * pic_width_c];
|
||||||
|
|
||||||
|
assert(ver_buf->y[0] == lcu->top_ref.y[0]);
|
||||||
|
assert(ver_buf->u[0] == lcu->top_ref.u[0]);
|
||||||
|
assert(ver_buf->v[0] == lcu->top_ref.v[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue