OSDN Git Service

Camera2/3: Optimize a few YCbCr_420_888 copy paths
authorEino-Ville Talvala <etalvala@google.com>
Thu, 9 May 2013 19:10:35 +0000 (12:10 -0700)
committerEino-Ville Talvala <etalvala@google.com>
Thu, 9 May 2013 19:13:07 +0000 (12:13 -0700)
Covers cases where the HAL format and the API format have the same
chroma layout.

Bug: 8734880
Change-Id: Ia735082c260b5914fc14f12551f91917c4e53b01

services/camera/libcameraservice/camera2/CallbackProcessor.cpp

index a3d6cb2..5e88102 100644 (file)
@@ -411,35 +411,61 @@ status_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
     size_t dstChromaGap = dstCStride - chromaWidth;
 
     if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
-        // NV21
+        // Flexible YUV chroma to NV21 chroma
         uint8_t *vuDst = yDst;
-        for (size_t row = 0; row < chromaHeight; row++) {
-            for (size_t col = 0; col < chromaWidth; col++) {
-                *(vuDst++) = *vSrc;
-                *(vuDst++) = *uSrc;
-                vSrc += src.chromaStep;
-                uSrc += src.chromaStep;
+        // Check for shortcuts
+        if (uSrc == vSrc + 1 && src.chromaStep == 2) {
+            // Source has semiplanar CrCb chroma layout, can copy by rows
+            for (size_t row = 0; row < chromaHeight; row++) {
+                memcpy(vuDst, uSrc, src.width);
+                vuDst += src.width;
+                uSrc += src.chromaStride;
+            }
+        } else {
+            // Generic copy, always works but not very efficient
+            for (size_t row = 0; row < chromaHeight; row++) {
+                for (size_t col = 0; col < chromaWidth; col++) {
+                    *(vuDst++) = *vSrc;
+                    *(vuDst++) = *uSrc;
+                    vSrc += src.chromaStep;
+                    uSrc += src.chromaStep;
+                }
+                vSrc += chromaGap;
+                uSrc += chromaGap;
             }
-            vSrc += chromaGap;
-            uSrc += chromaGap;
         }
     } else {
-        // YV12
+        // flexible YUV chroma to YV12 chroma
         ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
                 "Unexpected preview format 0x%x", previewFormat);
         uint8_t *vDst = yDst;
         uint8_t *uDst = yDst + chromaHeight * dstCStride;
-        for (size_t row = 0; row < chromaHeight; row++) {
-            for (size_t col = 0; col < chromaWidth; col++) {
-                *(vDst++) = *vSrc;
-                *(uDst++) = *uSrc;
-                vSrc += src.chromaStep;
-                uSrc += src.chromaStep;
+        if (src.chromaStep == 1) {
+            // Source has planar chroma layout, can copy by row
+            for (size_t row = 0; row < chromaHeight; row++) {
+                memcpy(vDst, vSrc, chromaWidth);
+                vDst += dstCStride;
+                vSrc += src.chromaStride;
+            }
+            for (size_t row = 0; row < chromaHeight; row++) {
+                memcpy(uDst, uSrc, chromaWidth);
+                uDst += dstCStride;
+                uSrc += src.chromaStride;
+            }
+        } else {
+            // Generic copy, always works but not very efficient
+            for (size_t row = 0; row < chromaHeight; row++) {
+                for (size_t col = 0; col < chromaWidth; col++) {
+                    *(vDst++) = *vSrc;
+                    *(uDst++) = *uSrc;
+                    vSrc += src.chromaStep;
+                    uSrc += src.chromaStep;
+                }
+                vSrc += chromaGap;
+                uSrc += chromaGap;
+                vDst += dstChromaGap;
+                uDst += dstChromaGap;
             }
-            vSrc += chromaGap;
-            uSrc += chromaGap;
-            vDst += dstChromaGap;
-            uDst += dstChromaGap;
         }
     }