diff options
Diffstat (limited to 'media/libstagefright/colorconversion/ColorConverter.cpp')
-rw-r--r-- | media/libstagefright/colorconversion/ColorConverter.cpp | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp deleted file mode 100644 index 597167f..0000000 --- a/media/libstagefright/colorconversion/ColorConverter.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (C) 2009 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_NDEBUG 0 -#define LOG_TAG "ColorConverter" -#include <utils/Log.h> - -#include <media/stagefright/foundation/ADebug.h> -#include <media/stagefright/ColorConverter.h> -#include <media/stagefright/MediaErrors.h> - -namespace android { - -ColorConverter::ColorConverter( - OMX_COLOR_FORMATTYPE from, OMX_COLOR_FORMATTYPE to) - : mSrcFormat(from), - mDstFormat(to), - mClip(NULL) { -} - -ColorConverter::~ColorConverter() { - delete[] mClip; - mClip = NULL; -} - -bool ColorConverter::isValid() const { - if (mDstFormat != OMX_COLOR_Format16bitRGB565) { - return false; - } - - switch (mSrcFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatCbYCrY: - case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: - return true; - - default: - return false; - } -} - -ColorConverter::BitmapParams::BitmapParams( - void *bits, - size_t width, size_t height, - size_t cropLeft, size_t cropTop, - size_t cropRight, size_t cropBottom) - : mBits(bits), - mWidth(width), - mHeight(height), - mCropLeft(cropLeft), - mCropTop(cropTop), - mCropRight(cropRight), - mCropBottom(cropBottom) { -} - -size_t ColorConverter::BitmapParams::cropWidth() const { - return mCropRight - mCropLeft + 1; -} - -size_t ColorConverter::BitmapParams::cropHeight() const { - return mCropBottom - mCropTop + 1; -} - -status_t ColorConverter::convert( - const void *srcBits, - size_t srcWidth, size_t srcHeight, - size_t srcCropLeft, size_t srcCropTop, - size_t srcCropRight, size_t srcCropBottom, - void *dstBits, - size_t dstWidth, size_t dstHeight, - size_t dstCropLeft, size_t dstCropTop, - size_t dstCropRight, size_t dstCropBottom) { - if (mDstFormat != OMX_COLOR_Format16bitRGB565) { - return ERROR_UNSUPPORTED; - } - - BitmapParams src( - const_cast<void *>(srcBits), - srcWidth, srcHeight, - srcCropLeft, srcCropTop, srcCropRight, srcCropBottom); - - BitmapParams dst( - dstBits, - dstWidth, dstHeight, - dstCropLeft, dstCropTop, dstCropRight, dstCropBottom); - - status_t err; - - switch (mSrcFormat) { - case OMX_COLOR_FormatYUV420Planar: - err = convertYUV420Planar(src, dst); - break; - - case OMX_COLOR_FormatCbYCrY: - err = convertCbYCrY(src, dst); - break; - - case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: - err = convertQCOMYUV420SemiPlanar(src, dst); - break; - - case OMX_COLOR_FormatYUV420SemiPlanar: - err = convertYUV420SemiPlanar(src, dst); - break; - - case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: - err = convertTIYUV420PackedSemiPlanar(src, dst); - break; - - default: - { - CHECK(!"Should not be here. Unknown color conversion."); - break; - } - } - - return err; -} - -status_t ColorConverter::convertCbYCrY( - const BitmapParams &src, const BitmapParams &dst) { - // XXX Untested - - uint8_t *kAdjustedClip = initClip(); - - if (!((src.mCropLeft & 1) == 0 - && src.cropWidth() == dst.cropWidth() - && src.cropHeight() == dst.cropHeight())) { - return ERROR_UNSUPPORTED; - } - - uint16_t *dst_ptr = (uint16_t *)dst.mBits - + dst.mCropTop * dst.mWidth + dst.mCropLeft; - - const uint8_t *src_ptr = (const uint8_t *)src.mBits - + (src.mCropTop * dst.mWidth + src.mCropLeft) * 2; - - for (size_t y = 0; y < src.cropHeight(); ++y) { - for (size_t x = 0; x < src.cropWidth(); x += 2) { - signed y1 = (signed)src_ptr[2 * x + 1] - 16; - signed y2 = (signed)src_ptr[2 * x + 3] - 16; - signed u = (signed)src_ptr[2 * x] - 128; - signed v = (signed)src_ptr[2 * x + 2] - 128; - - signed u_b = u * 517; - signed u_g = -u * 100; - signed v_g = -v * 208; - signed v_r = v * 409; - - signed tmp1 = y1 * 298; - signed b1 = (tmp1 + u_b) / 256; - signed g1 = (tmp1 + v_g + u_g) / 256; - signed r1 = (tmp1 + v_r) / 256; - - signed tmp2 = y2 * 298; - signed b2 = (tmp2 + u_b) / 256; - signed g2 = (tmp2 + v_g + u_g) / 256; - signed r2 = (tmp2 + v_r) / 256; - - uint32_t rgb1 = - ((kAdjustedClip[r1] >> 3) << 11) - | ((kAdjustedClip[g1] >> 2) << 5) - | (kAdjustedClip[b1] >> 3); - - uint32_t rgb2 = - ((kAdjustedClip[r2] >> 3) << 11) - | ((kAdjustedClip[g2] >> 2) << 5) - | (kAdjustedClip[b2] >> 3); - - if (x + 1 < src.cropWidth()) { - *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; - } else { - dst_ptr[x] = rgb1; - } - } - - src_ptr += src.mWidth * 2; - dst_ptr += dst.mWidth; - } - - return OK; -} - -status_t ColorConverter::convertYUV420Planar( - const BitmapParams &src, const BitmapParams &dst) { - if (!((src.mCropLeft & 1) == 0 - && src.cropWidth() == dst.cropWidth() - && src.cropHeight() == dst.cropHeight())) { - return ERROR_UNSUPPORTED; - } - - uint8_t *kAdjustedClip = initClip(); - - uint16_t *dst_ptr = (uint16_t *)dst.mBits - + dst.mCropTop * dst.mWidth + dst.mCropLeft; - - const uint8_t *src_y = - (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; - - const uint8_t *src_u = - (const uint8_t *)src_y + src.mWidth * src.mHeight - + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2; - - const uint8_t *src_v = - src_u + (src.mWidth / 2) * (src.mHeight / 2); - - for (size_t y = 0; y < src.cropHeight(); ++y) { - for (size_t x = 0; x < src.cropWidth(); x += 2) { - // B = 1.164 * (Y - 16) + 2.018 * (U - 128) - // G = 1.164 * (Y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128) - // R = 1.164 * (Y - 16) + 1.596 * (V - 128) - - // B = 298/256 * (Y - 16) + 517/256 * (U - 128) - // G = .................. - 208/256 * (V - 128) - 100/256 * (U - 128) - // R = .................. + 409/256 * (V - 128) - - // min_B = (298 * (- 16) + 517 * (- 128)) / 256 = -277 - // min_G = (298 * (- 16) - 208 * (255 - 128) - 100 * (255 - 128)) / 256 = -172 - // min_R = (298 * (- 16) + 409 * (- 128)) / 256 = -223 - - // max_B = (298 * (255 - 16) + 517 * (255 - 128)) / 256 = 534 - // max_G = (298 * (255 - 16) - 208 * (- 128) - 100 * (- 128)) / 256 = 432 - // max_R = (298 * (255 - 16) + 409 * (255 - 128)) / 256 = 481 - - // clip range -278 .. 535 - - signed y1 = (signed)src_y[x] - 16; - signed y2 = (signed)src_y[x + 1] - 16; - - signed u = (signed)src_u[x / 2] - 128; - signed v = (signed)src_v[x / 2] - 128; - - signed u_b = u * 517; - signed u_g = -u * 100; - signed v_g = -v * 208; - signed v_r = v * 409; - - signed tmp1 = y1 * 298; - signed b1 = (tmp1 + u_b) / 256; - signed g1 = (tmp1 + v_g + u_g) / 256; - signed r1 = (tmp1 + v_r) / 256; - - signed tmp2 = y2 * 298; - signed b2 = (tmp2 + u_b) / 256; - signed g2 = (tmp2 + v_g + u_g) / 256; - signed r2 = (tmp2 + v_r) / 256; - - uint32_t rgb1 = - ((kAdjustedClip[r1] >> 3) << 11) - | ((kAdjustedClip[g1] >> 2) << 5) - | (kAdjustedClip[b1] >> 3); - - uint32_t rgb2 = - ((kAdjustedClip[r2] >> 3) << 11) - | ((kAdjustedClip[g2] >> 2) << 5) - | (kAdjustedClip[b2] >> 3); - - if (x + 1 < src.cropWidth()) { - *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; - } else { - dst_ptr[x] = rgb1; - } - } - - src_y += src.mWidth; - - if (y & 1) { - src_u += src.mWidth / 2; - src_v += src.mWidth / 2; - } - - dst_ptr += dst.mWidth; - } - - return OK; -} - -status_t ColorConverter::convertQCOMYUV420SemiPlanar( - const BitmapParams &src, const BitmapParams &dst) { - uint8_t *kAdjustedClip = initClip(); - - if (!((src.mCropLeft & 1) == 0 - && src.cropWidth() == dst.cropWidth() - && src.cropHeight() == dst.cropHeight())) { - return ERROR_UNSUPPORTED; - } - - uint16_t *dst_ptr = (uint16_t *)dst.mBits - + dst.mCropTop * dst.mWidth + dst.mCropLeft; - - const uint8_t *src_y = - (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; - - const uint8_t *src_u = - (const uint8_t *)src_y + src.mWidth * src.mHeight - + src.mCropTop * src.mWidth + src.mCropLeft; - - for (size_t y = 0; y < src.cropHeight(); ++y) { - for (size_t x = 0; x < src.cropWidth(); x += 2) { - signed y1 = (signed)src_y[x] - 16; - signed y2 = (signed)src_y[x + 1] - 16; - - signed u = (signed)src_u[x & ~1] - 128; - signed v = (signed)src_u[(x & ~1) + 1] - 128; - - signed u_b = u * 517; - signed u_g = -u * 100; - signed v_g = -v * 208; - signed v_r = v * 409; - - signed tmp1 = y1 * 298; - signed b1 = (tmp1 + u_b) / 256; - signed g1 = (tmp1 + v_g + u_g) / 256; - signed r1 = (tmp1 + v_r) / 256; - - signed tmp2 = y2 * 298; - signed b2 = (tmp2 + u_b) / 256; - signed g2 = (tmp2 + v_g + u_g) / 256; - signed r2 = (tmp2 + v_r) / 256; - - uint32_t rgb1 = - ((kAdjustedClip[b1] >> 3) << 11) - | ((kAdjustedClip[g1] >> 2) << 5) - | (kAdjustedClip[r1] >> 3); - - uint32_t rgb2 = - ((kAdjustedClip[b2] >> 3) << 11) - | ((kAdjustedClip[g2] >> 2) << 5) - | (kAdjustedClip[r2] >> 3); - - if (x + 1 < src.cropWidth()) { - *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; - } else { - dst_ptr[x] = rgb1; - } - } - - src_y += src.mWidth; - - if (y & 1) { - src_u += src.mWidth; - } - - dst_ptr += dst.mWidth; - } - - return OK; -} - -status_t ColorConverter::convertYUV420SemiPlanar( - const BitmapParams &src, const BitmapParams &dst) { - // XXX Untested - - uint8_t *kAdjustedClip = initClip(); - - if (!((src.mCropLeft & 1) == 0 - && src.cropWidth() == dst.cropWidth() - && src.cropHeight() == dst.cropHeight())) { - return ERROR_UNSUPPORTED; - } - - uint16_t *dst_ptr = (uint16_t *)dst.mBits - + dst.mCropTop * dst.mWidth + dst.mCropLeft; - - const uint8_t *src_y = - (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; - - const uint8_t *src_u = - (const uint8_t *)src_y + src.mWidth * src.mHeight - + src.mCropTop * src.mWidth + src.mCropLeft; - - for (size_t y = 0; y < src.cropHeight(); ++y) { - for (size_t x = 0; x < src.cropWidth(); x += 2) { - signed y1 = (signed)src_y[x] - 16; - signed y2 = (signed)src_y[x + 1] - 16; - - signed v = (signed)src_u[x & ~1] - 128; - signed u = (signed)src_u[(x & ~1) + 1] - 128; - - signed u_b = u * 517; - signed u_g = -u * 100; - signed v_g = -v * 208; - signed v_r = v * 409; - - signed tmp1 = y1 * 298; - signed b1 = (tmp1 + u_b) / 256; - signed g1 = (tmp1 + v_g + u_g) / 256; - signed r1 = (tmp1 + v_r) / 256; - - signed tmp2 = y2 * 298; - signed b2 = (tmp2 + u_b) / 256; - signed g2 = (tmp2 + v_g + u_g) / 256; - signed r2 = (tmp2 + v_r) / 256; - - uint32_t rgb1 = - ((kAdjustedClip[b1] >> 3) << 11) - | ((kAdjustedClip[g1] >> 2) << 5) - | (kAdjustedClip[r1] >> 3); - - uint32_t rgb2 = - ((kAdjustedClip[b2] >> 3) << 11) - | ((kAdjustedClip[g2] >> 2) << 5) - | (kAdjustedClip[r2] >> 3); - - if (x + 1 < src.cropWidth()) { - *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; - } else { - dst_ptr[x] = rgb1; - } - } - - src_y += src.mWidth; - - if (y & 1) { - src_u += src.mWidth; - } - - dst_ptr += dst.mWidth; - } - - return OK; -} - -status_t ColorConverter::convertTIYUV420PackedSemiPlanar( - const BitmapParams &src, const BitmapParams &dst) { - uint8_t *kAdjustedClip = initClip(); - - if (!((src.mCropLeft & 1) == 0 - && src.cropWidth() == dst.cropWidth() - && src.cropHeight() == dst.cropHeight())) { - return ERROR_UNSUPPORTED; - } - - uint16_t *dst_ptr = (uint16_t *)dst.mBits - + dst.mCropTop * dst.mWidth + dst.mCropLeft; - - const uint8_t *src_y = (const uint8_t *)src.mBits; - - const uint8_t *src_u = - (const uint8_t *)src_y + src.mWidth * (src.mHeight - src.mCropTop / 2); - - for (size_t y = 0; y < src.cropHeight(); ++y) { - for (size_t x = 0; x < src.cropWidth(); x += 2) { - signed y1 = (signed)src_y[x] - 16; - signed y2 = (signed)src_y[x + 1] - 16; - - signed u = (signed)src_u[x & ~1] - 128; - signed v = (signed)src_u[(x & ~1) + 1] - 128; - - signed u_b = u * 517; - signed u_g = -u * 100; - signed v_g = -v * 208; - signed v_r = v * 409; - - signed tmp1 = y1 * 298; - signed b1 = (tmp1 + u_b) / 256; - signed g1 = (tmp1 + v_g + u_g) / 256; - signed r1 = (tmp1 + v_r) / 256; - - signed tmp2 = y2 * 298; - signed b2 = (tmp2 + u_b) / 256; - signed g2 = (tmp2 + v_g + u_g) / 256; - signed r2 = (tmp2 + v_r) / 256; - - uint32_t rgb1 = - ((kAdjustedClip[r1] >> 3) << 11) - | ((kAdjustedClip[g1] >> 2) << 5) - | (kAdjustedClip[b1] >> 3); - - uint32_t rgb2 = - ((kAdjustedClip[r2] >> 3) << 11) - | ((kAdjustedClip[g2] >> 2) << 5) - | (kAdjustedClip[b2] >> 3); - - if (x + 1 < src.cropWidth()) { - *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; - } else { - dst_ptr[x] = rgb1; - } - } - - src_y += src.mWidth; - - if (y & 1) { - src_u += src.mWidth; - } - - dst_ptr += dst.mWidth; - } - - return OK; -} - -uint8_t *ColorConverter::initClip() { - static const signed kClipMin = -278; - static const signed kClipMax = 535; - - if (mClip == NULL) { - mClip = new uint8_t[kClipMax - kClipMin + 1]; - - for (signed i = kClipMin; i <= kClipMax; ++i) { - mClip[i - kClipMin] = (i < 0) ? 0 : (i > 255) ? 255 : (uint8_t)i; - } - } - - return &mClip[-kClipMin]; -} - -} // namespace android |