Move utility functions to a common library
This change creates a library that contains utility functions commonly
used in different EVS versions.
Bug: 13542573
Test: VTS
Change-Id: Ica8f5e6228d7d4b1426d8cc9cd2c570d6b584897
Signed-off-by: Changyeon Jo <changyeon@google.com>
diff --git a/automotive/evs/1.0/vts/functional/Android.bp b/automotive/evs/1.0/vts/functional/Android.bp
index 2ef33fd..8988bfd 100644
--- a/automotive/evs/1.0/vts/functional/Android.bp
+++ b/automotive/evs/1.0/vts/functional/Android.bp
@@ -19,13 +19,15 @@
srcs: [
"VtsHalEvsV1_0TargetTest.cpp",
"FrameHandler.cpp",
- "FormatConvert.cpp"
],
defaults: ["VtsHalTargetTestDefaults"],
shared_libs: [
"libui",
],
- static_libs: ["android.hardware.automotive.evs@1.0"],
+ static_libs: [
+ "android.hardware.automotive.evs@1.0",
+ "android.hardware.automotive.evs@common-default-lib",
+ ],
test_suites: ["general-tests"],
cflags: [
"-O0",
diff --git a/automotive/evs/1.0/vts/functional/FormatConvert.cpp b/automotive/evs/1.0/vts/functional/FormatConvert.cpp
deleted file mode 100644
index 3d82d32..0000000
--- a/automotive/evs/1.0/vts/functional/FormatConvert.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VtsHalEvsTest"
-
-#include "FormatConvert.h"
-
-
-// Round up to the nearest multiple of the given alignment value
-template<unsigned alignment>
-int align(int value) {
- static_assert((alignment && !(alignment & (alignment - 1))),
- "alignment must be a power of 2");
-
- unsigned mask = alignment - 1;
- return (value + mask) & ~mask;
-}
-
-
-// Limit the given value to the provided range. :)
-static inline float clamp(float v, float min, float max) {
- if (v < min) return min;
- if (v > max) return max;
- return v;
-}
-
-
-static uint32_t yuvToRgbx(const unsigned char Y, const unsigned char Uin, const unsigned char Vin,
- bool bgrxFormat = false) {
- // Don't use this if you want to see the best performance. :)
- // Better to do this in a pixel shader if we really have to, but on actual
- // embedded hardware we expect to be able to texture directly from the YUV data
- float U = Uin - 128.0f;
- float V = Vin - 128.0f;
-
- float Rf = Y + 1.140f*V;
- float Gf = Y - 0.395f*U - 0.581f*V;
- float Bf = Y + 2.032f*U;
- unsigned char R = (unsigned char)clamp(Rf, 0.0f, 255.0f);
- unsigned char G = (unsigned char)clamp(Gf, 0.0f, 255.0f);
- unsigned char B = (unsigned char)clamp(Bf, 0.0f, 255.0f);
-
- if (!bgrxFormat) {
- return (R ) |
- (G << 8) |
- (B << 16) |
- 0xFF000000; // Fill the alpha channel with ones
- } else {
- return (R << 16) |
- (G << 8) |
- (B ) |
- 0xFF000000; // Fill the alpha channel with ones
- }
-}
-
-
-void copyNV21toRGB32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels,
- bool bgrxFormat)
-{
- // The NV21 format provides a Y array of 8bit values, followed by a 1/2 x 1/2 interleaved
- // U/V array. It assumes an even width and height for the overall image, and a horizontal
- // stride that is an even multiple of 16 bytes for both the Y and UV arrays.
- unsigned strideLum = align<16>(width);
- unsigned sizeY = strideLum * height;
- unsigned strideColor = strideLum; // 1/2 the samples, but two interleaved channels
- unsigned offsetUV = sizeY;
-
- uint8_t* srcY = src;
- uint8_t* srcUV = src+offsetUV;
-
- for (unsigned r = 0; r < height; r++) {
- // Note that we're walking the same UV row twice for even/odd luminance rows
- uint8_t* rowY = srcY + r*strideLum;
- uint8_t* rowUV = srcUV + (r/2 * strideColor);
-
- uint32_t* rowDest = dst + r*dstStridePixels;
-
- for (unsigned c = 0; c < width; c++) {
- unsigned uCol = (c & ~1); // uCol is always even and repeats 1:2 with Y values
- unsigned vCol = uCol | 1; // vCol is always odd
- rowDest[c] = yuvToRgbx(rowY[c], rowUV[uCol], rowUV[vCol], bgrxFormat);
- }
- }
-}
-
-
-void copyYV12toRGB32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels,
- bool bgrxFormat)
-{
- // The YV12 format provides a Y array of 8bit values, followed by a 1/2 x 1/2 U array, followed
- // by another 1/2 x 1/2 V array. It assumes an even width and height for the overall image,
- // and a horizontal stride that is an even multiple of 16 bytes for each of the Y, U,
- // and V arrays.
- unsigned strideLum = align<16>(width);
- unsigned sizeY = strideLum * height;
- unsigned strideColor = align<16>(strideLum/2);
- unsigned sizeColor = strideColor * height/2;
- unsigned offsetU = sizeY;
- unsigned offsetV = sizeY + sizeColor;
-
- uint8_t* srcY = src;
- uint8_t* srcU = src+offsetU;
- uint8_t* srcV = src+offsetV;
-
- for (unsigned r = 0; r < height; r++) {
- // Note that we're walking the same U and V rows twice for even/odd luminance rows
- uint8_t* rowY = srcY + r*strideLum;
- uint8_t* rowU = srcU + (r/2 * strideColor);
- uint8_t* rowV = srcV + (r/2 * strideColor);
-
- uint32_t* rowDest = dst + r*dstStridePixels;
-
- for (unsigned c = 0; c < width; c++) {
- rowDest[c] = yuvToRgbx(rowY[c], rowU[c], rowV[c], bgrxFormat);
- }
- }
-}
-
-
-void copyYUYVtoRGB32(unsigned width, unsigned height,
- uint8_t* src, unsigned srcStridePixels,
- uint32_t* dst, unsigned dstStridePixels,
- bool bgrxFormat)
-{
- uint32_t* srcWords = (uint32_t*)src;
-
- const int srcRowPadding32 = srcStridePixels/2 - width/2; // 2 bytes per pixel, 4 bytes per word
- const int dstRowPadding32 = dstStridePixels - width; // 4 bytes per pixel, 4 bytes per word
-
- for (unsigned r = 0; r < height; r++) {
- for (unsigned c = 0; c < width/2; c++) {
- // Note: we're walking two pixels at a time here (even/odd)
- uint32_t srcPixel = *srcWords++;
-
- uint8_t Y1 = (srcPixel) & 0xFF;
- uint8_t U = (srcPixel >> 8) & 0xFF;
- uint8_t Y2 = (srcPixel >> 16) & 0xFF;
- uint8_t V = (srcPixel >> 24) & 0xFF;
-
- // On the RGB output, we're writing one pixel at a time
- *(dst+0) = yuvToRgbx(Y1, U, V, bgrxFormat);
- *(dst+1) = yuvToRgbx(Y2, U, V, bgrxFormat);
- dst += 2;
- }
-
- // Skip over any extra data or end of row alignment padding
- srcWords += srcRowPadding32;
- dst += dstRowPadding32;
- }
-}
-
-
-void copyNV21toBGR32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels)
-{
- return copyNV21toRGB32(width, height, src, dst, dstStridePixels, true);
-}
-
-
-void copyYV12toBGR32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels)
-{
- return copyYV12toRGB32(width, height, src, dst, dstStridePixels, true);
-}
-
-
-void copyYUYVtoBGR32(unsigned width, unsigned height,
- uint8_t* src, unsigned srcStridePixels,
- uint32_t* dst, unsigned dstStridePixels)
-{
- return copyYUYVtoRGB32(width, height, src, srcStridePixels, dst, dstStridePixels, true);
-}
-
-
-void copyMatchedInterleavedFormats(unsigned width, unsigned height,
- void* src, unsigned srcStridePixels,
- void* dst, unsigned dstStridePixels,
- unsigned pixelSize) {
- for (unsigned row = 0; row < height; row++) {
- // Copy the entire row of pixel data
- memcpy(dst, src, width * pixelSize);
-
- // Advance to the next row (keeping in mind that stride here is in units of pixels)
- src = (uint8_t*)src + srcStridePixels * pixelSize;
- dst = (uint8_t*)dst + dstStridePixels * pixelSize;
- }
-}
diff --git a/automotive/evs/1.0/vts/functional/FormatConvert.h b/automotive/evs/1.0/vts/functional/FormatConvert.h
deleted file mode 100644
index 4a94f99..0000000
--- a/automotive/evs/1.0/vts/functional/FormatConvert.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef EVS_VTS_FORMATCONVERT_H
-#define EVS_VTS_FORMATCONVERT_H
-
-#include <queue>
-#include <stdint.h>
-
-
-// Given an image buffer in NV21 format (HAL_PIXEL_FORMAT_YCRCB_420_SP), output 32bit RGBx/BGRx
-// values. The NV21 format provides a Y array of 8bit values, followed by a 1/2 x 1/2 interleaved
-// U/V array. It assumes an even width and height for the overall image, and a horizontal
-// stride that is an even multiple of 16 bytes for both the Y and UV arrays.
-void copyNV21toRGB32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels,
- bool bgrxFormat = false);
-
-void copyNV21toBGR32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels);
-
-
-// Given an image buffer in YV12 format (HAL_PIXEL_FORMAT_YV12), output 32bit RGBx/BGRx values.
-// The YV12 format provides a Y array of 8bit values, followed by a 1/2 x 1/2 U array, followed
-// by another 1/2 x 1/2 V array. It assumes an even width and height for the overall image,
-// and a horizontal stride that is an even multiple of 16 bytes for each of the Y, U,
-// and V arrays.
-void copyYV12toRGB32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels,
- bool bgrxFormat = false);
-
-void copyYV12toBGR32(unsigned width, unsigned height,
- uint8_t* src,
- uint32_t* dst, unsigned dstStridePixels);
-
-// Given an image buffer in YUYV format (HAL_PIXEL_FORMAT_YCBCR_422_I), output 32bit RGBx/BGRx
-// values. The NV21 format provides a Y array of 8bit values, followed by a 1/2 x 1/2 interleaved
-// U/V array. It assumes an even width and height for the overall image, and a horizontal
-// stride that is an even multiple of 16 bytes for both the Y and UV arrays.
-void copyYUYVtoRGB32(unsigned width, unsigned height,
- uint8_t* src, unsigned srcStrideBytes,
- uint32_t* dst, unsigned dstStrideBytes,
- bool bgrxFormat = false);
-
-void copyYUYVtoBGR32(unsigned width, unsigned height,
- uint8_t* src, unsigned srcStrideBytes,
- uint32_t* dst, unsigned dstStrideBytes);
-
-
-// Given an simple rectangular image buffer with an integer number of bytes per pixel,
-// copy the pixel values into a new rectangular buffer (potentially with a different stride).
-// This is typically used to copy RGBx data into an RGBx output buffer.
-void copyMatchedInterleavedFormats(unsigned width, unsigned height,
- void* src, unsigned srcStridePixels,
- void* dst, unsigned dstStridePixels,
- unsigned pixelSize);
-
-#endif // EVS_VTS_FORMATCONVERT_H
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.cpp b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
index bc3790f..6a01a44 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.cpp
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
@@ -240,46 +240,47 @@
tgt->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)&tgtPixels);
if (srcPixels && tgtPixels) {
+ using namespace ::android::hardware::automotive::evs::common;
if (tgtBuffer.format == HAL_PIXEL_FORMAT_RGBA_8888) {
if (srcBuffer.format == HAL_PIXEL_FORMAT_YCRCB_420_SP) { // 420SP == NV21
- copyNV21toRGB32(width, height,
- srcPixels,
- tgtPixels, tgtBuffer.stride);
+ Utils::copyNV21toRGB32(width, height,
+ srcPixels,
+ tgtPixels, tgtBuffer.stride);
} else if (srcBuffer.format == HAL_PIXEL_FORMAT_YV12) { // YUV_420P == YV12
- copyYV12toRGB32(width, height,
- srcPixels,
- tgtPixels, tgtBuffer.stride);
+ Utils::copyYV12toRGB32(width, height,
+ srcPixels,
+ tgtPixels, tgtBuffer.stride);
} else if (srcBuffer.format == HAL_PIXEL_FORMAT_YCBCR_422_I) { // YUYV
- copyYUYVtoRGB32(width, height,
- srcPixels, srcBuffer.stride,
- tgtPixels, tgtBuffer.stride);
+ Utils::copyYUYVtoRGB32(width, height,
+ srcPixels, srcBuffer.stride,
+ tgtPixels, tgtBuffer.stride);
} else if (srcBuffer.format == tgtBuffer.format) { // 32bit RGBA
- copyMatchedInterleavedFormats(width, height,
- srcPixels, srcBuffer.stride,
- tgtPixels, tgtBuffer.stride,
- tgtBuffer.pixelSize);
+ Utils::copyMatchedInterleavedFormats(width, height,
+ srcPixels, srcBuffer.stride,
+ tgtPixels, tgtBuffer.stride,
+ tgtBuffer.pixelSize);
} else {
ALOGE("Camera buffer format is not supported");
success = false;
}
} else if (tgtBuffer.format == HAL_PIXEL_FORMAT_BGRA_8888) {
if (srcBuffer.format == HAL_PIXEL_FORMAT_YCRCB_420_SP) { // 420SP == NV21
- copyNV21toBGR32(width, height,
- srcPixels,
- tgtPixels, tgtBuffer.stride);
+ Utils::copyNV21toBGR32(width, height,
+ srcPixels,
+ tgtPixels, tgtBuffer.stride);
} else if (srcBuffer.format == HAL_PIXEL_FORMAT_YV12) { // YUV_420P == YV12
- copyYV12toBGR32(width, height,
- srcPixels,
- tgtPixels, tgtBuffer.stride);
+ Utils::copyYV12toBGR32(width, height,
+ srcPixels,
+ tgtPixels, tgtBuffer.stride);
} else if (srcBuffer.format == HAL_PIXEL_FORMAT_YCBCR_422_I) { // YUYV
- copyYUYVtoBGR32(width, height,
- srcPixels, srcBuffer.stride,
- tgtPixels, tgtBuffer.stride);
+ Utils::copyYUYVtoBGR32(width, height,
+ srcPixels, srcBuffer.stride,
+ tgtPixels, tgtBuffer.stride);
} else if (srcBuffer.format == tgtBuffer.format) { // 32bit RGBA
- copyMatchedInterleavedFormats(width, height,
- srcPixels, srcBuffer.stride,
- tgtPixels, tgtBuffer.stride,
- tgtBuffer.pixelSize);
+ Utils::copyMatchedInterleavedFormats(width, height,
+ srcPixels, srcBuffer.stride,
+ tgtPixels, tgtBuffer.stride,
+ tgtBuffer.pixelSize);
} else {
ALOGE("Camera buffer format is not supported");
success = false;