YUV_420_888 interpretation on Samsung Galaxy S7 (Camera2)

Look at

floor((float) uvPixelStride*(x)/2)

which calculates your U,V row offset (uv_row_offset) from the Y x-coordinate.

if uvPixelStride = 2, then as x increases:

x = 0, uv_row_offset = 0
x = 1, uv_row_offset = 1
x = 2, uv_row_offset = 2
x = 3, uv_row_offset = 3

and this is incorrect. There’s no valid U/V pixel value at uv_row_offset = 1 or 3, since uvPixelStride = 2.

You want

uvPixelStride * floor(x/2)

(assuming you don’t trust yourself to remember the critical round-down behavior of integer divide, if you do then):

uvPixelStride * (x/2)

should be enough

With that, your mapping becomes:

x = 0, uv_row_offset = 0
x = 1, uv_row_offset = 0
x = 2, uv_row_offset = 2
x = 3, uv_row_offset = 2

See if that fixes the color errors. In practice, the incorrect addressing here would mean every other color sample would be from the wrong color plane, since it’s likely that the underlying YUV data is semiplanar (so the U plane starts at V plane + 1 byte, with the two planes interleaved)

Leave a Comment