summaryrefslogtreecommitdiffstats
path: root/libyv12colorconvert/ColorConvert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libyv12colorconvert/ColorConvert.cpp')
-rw-r--r--libyv12colorconvert/ColorConvert.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/libyv12colorconvert/ColorConvert.cpp b/libyv12colorconvert/ColorConvert.cpp
new file mode 100644
index 0000000..41dcbad
--- /dev/null
+++ b/libyv12colorconvert/ColorConvert.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "IYV12ColorConverter.h"
+#include <OMX_IVCommon.h>
+#include <string.h>
+
+static int getDecoderOutputFormat() {
+ return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
+}
+
+static int convertDecoderOutputToYV12(
+ void* srcBits, int srcWidth, int srcHeight, ARect srcRect, void* dstBits) {
+
+ const uint8_t *pSrc_y = (const uint8_t *)srcBits +
+ srcWidth * srcRect.top + srcRect.left;
+ const uint8_t *pSrc_uv = (const uint8_t *)pSrc_y +
+ srcWidth * (srcHeight - srcRect.top / 2);
+
+ int dstWidth = srcRect.right - srcRect.left + 1;
+ int dstHeight = srcRect.bottom - srcRect.top + 1;
+ size_t dst_y_size = dstWidth * dstHeight;
+ size_t dst_uv_stride = dstWidth / 2;
+ size_t dst_uv_size = dstWidth / 2 * dstHeight / 2;
+ uint8_t *pDst_y = (uint8_t *)dstBits;
+ uint8_t *pDst_u = pDst_y + dst_y_size;
+ uint8_t *pDst_v = pDst_u + dst_uv_size;
+
+ for (int y = 0; y < dstHeight; ++y) {
+ memcpy(pDst_y, pSrc_y, dstWidth);
+ pSrc_y += srcWidth;
+ pDst_y += dstWidth;
+ }
+
+ size_t tmp = (dstWidth + 1) / 2;
+ for (int y = 0; y < (dstHeight + 1) / 2; ++y) {
+ for (size_t x = 0; x < tmp; ++x) {
+ pDst_u[x] = pSrc_uv[2 * x];
+ pDst_v[x] = pSrc_uv[2 * x + 1];
+ }
+ pSrc_uv += srcWidth;
+ pDst_u += dst_uv_stride;
+ pDst_v += dst_uv_stride;
+ }
+ return 0;
+}
+
+static int getEncoderInputFormat() {
+ return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
+}
+
+static int convertYV12ToEncoderInput(
+ void* srcBits, int srcWidth, int srcHeight,
+ int dstWidth, int dstHeight, ARect dstRect,
+ void* dstBits) {
+ uint8_t *pSrc_y = (uint8_t*) srcBits;
+ uint8_t *pDst_y = (uint8_t*) dstBits;
+ for(int i=0; i < srcHeight; i++) {
+ memcpy(pDst_y, pSrc_y, srcWidth);
+ pSrc_y += srcWidth;
+ pDst_y += dstWidth;
+ }
+ uint8_t* pSrc_u = (uint8_t*)srcBits + (srcWidth * srcHeight);
+ uint8_t* pSrc_v = (uint8_t*)pSrc_u + (srcWidth / 2) * (srcHeight / 2);
+ uint8_t* pDst_uv = (uint8_t*)dstBits + dstWidth * dstHeight;
+
+ for(int i=0; i < srcHeight / 2; i++) {
+ for(int j=0, k=0; j < srcWidth / 2; j++, k+=2) {
+ pDst_uv[k] = pSrc_u[j];
+ pDst_uv[k+1] = pSrc_v[j];
+ }
+ pDst_uv += dstWidth;
+ pSrc_u += srcWidth / 2;
+ pSrc_v += srcWidth / 2;
+ }
+ return 0;
+}
+
+static int getEncoderInputBufferInfo(
+ int actualWidth, int actualHeight,
+ int* encoderWidth, int* encoderHeight,
+ ARect* encoderRect, int* encoderBufferSize) {
+
+ *encoderWidth = actualWidth;
+ *encoderHeight = actualHeight;
+ encoderRect->left = 0;
+ encoderRect->top = 0;
+ encoderRect->right = actualWidth - 1;
+ encoderRect->bottom = actualHeight - 1;
+ *encoderBufferSize = (actualWidth * actualHeight * 3 / 2);
+
+ return 0;
+}
+
+extern "C" void getYV12ColorConverter(IYV12ColorConverter *converter) {
+ converter->getDecoderOutputFormat = getDecoderOutputFormat;
+ converter->convertDecoderOutputToYV12 = convertDecoderOutputToYV12;
+ converter->getEncoderInputFormat = getEncoderInputFormat;
+ converter->convertYV12ToEncoderInput = convertYV12ToEncoderInput;
+ converter->getEncoderInputBufferInfo = getEncoderInputBufferInfo;
+}