7

I have been working for some time with NV21 images in Android and I have been tracking a bug that might be caused by incorrect indexing bytes in an NV21 image.

The image in the answer of this question has a nice overview of how the Y, U and V bytes are positioned in the image buffer. Not sure it is allowed, but I am embedding it below:

YUV420SP NV21 format

  1. What happens when the image has odd dimensions (as in parity)? Is that even possible in this format?
  2. Do we have an official specification of this format somewhere?
Rotem
  • 30,366
  • 4
  • 32
  • 65
silvaren
  • 730
  • 6
  • 14
  • 1
    The graphics was wrong, showing NV12 format. I have updated the graphics (I also commented the problem in the referred answer). – rics Feb 23 '17 at 10:14

1 Answers1

7

In the case of an image with odd dimensions (i.e one of W or H, in a WxH image is odd), you'd expect the Y plane to be fully sampled as always, with WxH samples, followed by 2(⌈W/2⌉ x ⌈H/2⌉) chroma samples, where we divide each image dimension by 2 but round up rather than round down.

So some of the pixels at the very edge of the image have chroma samples that correspond to only 1 or 2 original pixels, rather than 4. I hope that makes sense. You can see in this link that a couple of other libraries have had issues handling odd dimensions in YUV images previously.

For your second question, I haven't seen an official specification, but I have seen some code in the android framework that handles this format, I will see if I can dig up a link to it, and append it to this answer.

jpowell
  • 365
  • 3
  • 5
  • I accepted the answer already, but if you can come up with that link it would be really nice to illustrate the "official" format. – silvaren Nov 21 '15 at 03:13
  • 1
    @silvaren [`Yuv420SpToJpegEncoder::deinterleave`](http://code.metager.de/source/xref/android/4.4/frameworks/base/core/jni/android/graphics/YuvToJpegEncoder.cpp#deinterleave) may be what you're looking for, for full stack trace see http://stackoverflow.com/a/36560663/253468 – TWiStErRob Apr 14 '16 at 15:27
  • 1
    @silvaren notice that they just `width >> 1` in the C++ code, because Android's `YuvImage` does not support odd-sized images, see [`YuvImage.adjustRectangle`](https://github.com/android/platform_frameworks_base/blob/kitkat-mr2.2-release/graphics/java/android/graphics/YuvImage.java#L214). – TWiStErRob Apr 14 '16 at 17:01