mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 02:24:07 +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)
|
||||
{
|
||||
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_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);
|
||||
|
||||
// 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.
|
||||
picture_blit_pixels(&pic->y_recdata[(bottom - 1) * size.x + 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);
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
//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 * 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->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;
|
||||
}
|
||||
|
||||
void dealloc_yuv_t(yuv_t * yuv)
|
||||
{
|
||||
free(yuv->y);
|
||||
free(yuv->u);
|
||||
free(yuv->v);
|
||||
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],
|
||||
1, y_max_c, pic_width_c, 1);
|
||||
|
||||
assert(!memcmp(ver_buf->y, &lcu->left_ref.y[1], y_max));
|
||||
assert(!memcmp(ver_buf->u, &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->y[1], &lcu->left_ref.y[1], y_max));
|
||||
assert(!memcmp(&ver_buf->u[1], &lcu->left_ref.u[1], y_max_c));
|
||||
assert(!memcmp(&ver_buf->v[1], &lcu->left_ref.v[1], y_max_c));
|
||||
}
|
||||
// Copy top-left reference pixel.
|
||||
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->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