From 951516358e2841d2425f610bcd0175d9960135d2 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 2 May 2012 16:21:18 -0700 Subject: [PATCH] Update docs for YV12 format and camera preview callbacks. - Define stride for YV12 when using it for preview callbacks - Include equations for calculating stride and start indexes of Y, U, and V planes for YV12. - Add more cross-references so that equations are easier to find. Bug: 6330501 Change-Id: I85a78757ec767d08173b9fe714adb715835244b4 --- core/java/android/hardware/Camera.java | 70 +++++++++++++++---- .../java/android/graphics/ImageFormat.java | 16 ++++- 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index eb0a0c6f4732a..77f826eff62f3 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -469,6 +469,11 @@ public class Camera { * Called as preview frames are displayed. This callback is invoked * on the event thread {@link #open(int)} was called from. * + *

If using the {@link android.graphics.ImageFormat#YV12} format, + * refer to the equations in {@link Camera.Parameters#setPreviewFormat} + * for the arrangement of the pixel data in the preview callback + * buffers. + * * @param data the contents of the preview frame in the format defined * by {@link android.graphics.ImageFormat}, which can be queried * with {@link android.hardware.Camera.Parameters#getPreviewFormat()}. @@ -609,12 +614,17 @@ public class Camera { * the frame is discarded. Applications should add buffers back when they * finish processing the data in them. * - *

The size of the buffer is determined by multiplying the preview - * image width, height, and bytes per pixel. The width and height can be - * read from {@link Camera.Parameters#getPreviewSize()}. Bytes per pixel - * can be computed from - * {@link android.graphics.ImageFormat#getBitsPerPixel(int)} / 8, - * using the image format from {@link Camera.Parameters#getPreviewFormat()}. + *

For formats besides YV12, the size of the buffer is determined by + * multiplying the preview image width, height, and bytes per pixel. The + * width and height can be read from + * {@link Camera.Parameters#getPreviewSize()}. Bytes per pixel can be + * computed from {@link android.graphics.ImageFormat#getBitsPerPixel(int)} / + * 8, using the image format from + * {@link Camera.Parameters#getPreviewFormat()}. + * + *

If using the {@link android.graphics.ImageFormat#YV12} format, the + * size can be calculated using the equations listed in + * {@link Camera.Parameters#setPreviewFormat}. * *

This method is only necessary when * {@link #setPreviewCallbackWithBuffer(PreviewCallback)} is used. When @@ -624,8 +634,8 @@ public class Camera { * hold the preview frame data, preview callback will return null and * the buffer will be removed from the buffer queue. * - * @param callbackBuffer the buffer to add to the queue. - * The size should be width * height * bits_per_pixel / 8. + * @param callbackBuffer the buffer to add to the queue. The size of the + * buffer must match the values described above. * @see #setPreviewCallbackWithBuffer(PreviewCallback) */ public final void addCallbackBuffer(byte[] callbackBuffer) @@ -2270,12 +2280,44 @@ public class Camera { * {@link android.graphics.ImageFormat#NV21}, which * uses the NV21 encoding format.

* - * @param pixel_format the desired preview picture format, defined - * by one of the {@link android.graphics.ImageFormat} constants. - * (E.g., ImageFormat.NV21 (default), - * ImageFormat.RGB_565, or - * ImageFormat.JPEG) + *

Use {@link Parameters#getSupportedPreviewFormats} to get a list of + * the available preview formats. + * + *

It is strongly recommended that either + * {@link android.graphics.ImageFormat#NV21} or + * {@link android.graphics.ImageFormat#YV12} is used, since + * they are supported by all camera devices.

+ * + *

For YV12, the image buffer that is received is not necessarily + * tightly packed, as there may be padding at the end of each row of + * pixel data, as described in + * {@link android.graphics.ImageFormat#YV12}. For camera callback data, + * it can be assumed that the stride of the Y and UV data is the + * smallest possible that meets the alignment requirements. That is, if + * the preview size is width x height, then the following + * equations describe the buffer index for the beginning of row + * y for the Y plane and row c for the U and V + * planes: + * + * {@code + *

+         * yStride   = (int) ceil(width / 16.0) * 16;
+         * uvStride  = (int) ceil( (yStride / 2) / 16.0) * 16;
+         * ySize     = yStride * height;
+         * uvSize    = uvStride * height / 2;
+         * yRowIndex = yStride * y;
+         * uRowIndex = ySize + uvSize + uvStride * c;
+         * vRowIndex = ySize + uvStride * c;
+         * size      = ySize + uvSize * 2;
+ * } + * + * @param pixel_format the desired preview picture format, defined by + * one of the {@link android.graphics.ImageFormat} constants. (E.g., + * ImageFormat.NV21 (default), or + * ImageFormat.YV12) + * * @see android.graphics.ImageFormat + * @see android.hardware.Camera.Parameters#getSupportedPreviewFormats */ public void setPreviewFormat(int pixel_format) { String s = cameraFormatForPixelFormat(pixel_format); @@ -2293,6 +2335,7 @@ public class Camera { * * @return the preview format. * @see android.graphics.ImageFormat + * @see #setPreviewFormat */ public int getPreviewFormat() { return pixelFormatForCameraFormat(get(KEY_PREVIEW_FORMAT)); @@ -2306,6 +2349,7 @@ public class Camera { * @return a list of supported preview formats. This method will always * return a list with at least one element. * @see android.graphics.ImageFormat + * @see #setPreviewFormat */ public List getSupportedPreviewFormats() { String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX); diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java index b3a8fd7ba87cc..f6b747a0af83c 100644 --- a/graphics/java/android/graphics/ImageFormat.java +++ b/graphics/java/android/graphics/ImageFormat.java @@ -48,14 +48,26 @@ public class ImageFormat { *

* *
 y_size = stride * height
-     * c_size = ALIGN(stride/2, 16) * height/2
+     * c_stride = ALIGN(stride/2, 16)
+     * c_size = c_stride * height/2
      * size = y_size + c_size * 2
      * cr_offset = y_size
      * cb_offset = y_size + c_size
* - * This format is guaranteed to be supported for camera preview images since + *

This format is guaranteed to be supported for camera preview images since * API level 12; for earlier API versions, check * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}. + * + *

Note that for camera preview callback use (see + * {@link android.hardware.Camera#setPreviewCallback}), the + * stride value is the smallest possible; that is, it is equal + * to: + * + *

stride = ALIGN(width, 16)
+ * + * @see android.hardware.Camera.Parameters#setPreviewCallback + * @see android.hardware.Camera.Parameters#setPreviewFormat + * @see android.hardware.Camera.Parameters#getSupportedPreviewFormats *

*/ public static final int YV12 = 0x32315659;