From 3571d50a2582bc9c63f09cd81b4f490ea3522bd9 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 24 Jun 2011 13:16:42 -0700 Subject: Fix the new color converter to respect the destination crop rect. Also fixes the SoftwareRenderer to request blitting the correct crop rectangles. Change-Id: I38706cf9b42d96c6d5b35a9380f006ea4fbbf1ea --- .../colorconversion/ColorConverter.cpp | 81 ++++++++-------------- .../colorconversion/SoftwareRenderer.cpp | 79 ++++++++++++++------- 2 files changed, 82 insertions(+), 78 deletions(-) (limited to 'media/libstagefright/colorconversion') diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp index fd933cc..5cc3f78 100644 --- a/media/libstagefright/colorconversion/ColorConverter.cpp +++ b/media/libstagefright/colorconversion/ColorConverter.cpp @@ -14,6 +14,10 @@ * limitations under the License. */ +//#define LOG_NDEBUG 0 +#define LOG_TAG "ColorConverter" +#include + #include #include #include @@ -424,61 +428,30 @@ status_t ColorConverter::convertYUV420SemiPlanar( status_t ColorConverter::convertTIYUV420PackedSemiPlanar( const BitmapParams &src, const BitmapParams &dst) { + uint8_t *kAdjustedClip = initClip(); -/* -The TIYUV420PackedSemiPlanar format is same as YUV420PackedSemiPlanar but with -additional padding as shown in the diagram below. The padded width and padded -height is different for different compression formats and it is read from the -codec. In this color conversion routine, the padded resolution is obtained from -src bitmap. - - ------------------------------------ -| | -| | -| ------------------------- | -| | | | -| | | | -| | Y DATA | | -| | | | -| | | | -| | | | -| ------------------------- | -| | -| ------------ | -| | | | -| | | | -| | UV DATA | | -| | | | -| | | | -| | | | -| ------------ | -| | -| | - ------------------------------------ -*/ - - LOGV("src.mCropLeft = %d src.mCropTop =%d src.mWidth = %d src.mHeight = %d" - " dst.mWidth = %d dst.mHeight = %d", src.mCropLeft , src.mCropTop, - src.mWidth, src.mHeight, dst.mWidth, dst.mHeight); - - size_t offset = (src.mWidth * src.mCropTop) + src.mCropLeft; + if (!((dst.mWidth & 3) == 0 + && (src.mCropLeft & 1) == 0 + && src.cropWidth() == dst.cropWidth() + && src.cropHeight() == dst.cropHeight())) { + return ERROR_UNSUPPORTED; + } - uint8_t *kAdjustedClip = initClip(); + uint32_t *dst_ptr = (uint32_t *)dst.mBits + + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2; - uint32_t *dst_ptr = (uint32_t *)dst.mBits; const uint8_t *src_y = (const uint8_t *)src.mBits; - const uint8_t *src_u = (const uint8_t *)(src_y-offset) + (src.mWidth * src.mHeight); - src_u += ( ( src.mWidth * (src.mCropTop/2) ) + src.mCropLeft ); - const uint8_t *src_v = src_u + 1; - for (size_t y = 0; y < dst.mHeight; ++y) { - for (size_t x = 0; x < dst.mWidth; x += 2) { + const uint8_t *src_u = + (const uint8_t *)src_y + src.mWidth * (src.mHeight - src.mCropTop / 2); - signed y1 = (signed)src_y[x] - 16; //Y pixel - signed y2 = (signed)src_y[x + 1] - 16; //2nd Y pixel + 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; //U component - signed v = (signed)src_u[(x & ~1) + 1] - 128; //V component + 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; @@ -502,19 +475,21 @@ src bitmap. uint32_t rgb2 = ((kAdjustedClip[r2] >> 3) << 11) - | ((kAdjustedClip[g1] >> 2) << 5) - | (kAdjustedClip[b1] >> 3); + | ((kAdjustedClip[g2] >> 2) << 5) + | (kAdjustedClip[b2] >> 3); dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } - src_y += src.mWidth; //increment Y-pixel line - if (y&1) { - src_u += src.mWidth; //increment U-V line + src_y += src.mWidth; + + if (y & 1) { + src_u += src.mWidth; } dst_ptr += dst.mWidth / 2; } + return OK; } diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index a4e8ee4..a4ca32d 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -50,6 +50,9 @@ SoftwareRenderer::SoftwareRenderer( mCropBottom = mHeight - 1; } + mCropWidth = mCropRight - mCropLeft + 1; + mCropHeight = mCropBottom - mCropTop + 1; + int32_t rotationDegrees; if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { rotationDegrees = 0; @@ -60,17 +63,18 @@ SoftwareRenderer::SoftwareRenderer( switch (mColorFormat) { case OMX_COLOR_FormatYUV420Planar: + case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: { halFormat = HAL_PIXEL_FORMAT_YV12; - bufWidth = (mWidth + 1) & ~1; - bufHeight = (mHeight + 1) & ~1; + bufWidth = (mCropWidth + 1) & ~1; + bufHeight = (mCropHeight + 1) & ~1; break; } default: halFormat = HAL_PIXEL_FORMAT_RGB_565; - bufWidth = mWidth; - bufHeight = mHeight; + bufWidth = mCropWidth; + bufHeight = mCropHeight; mConverter = new ColorConverter( mColorFormat, OMX_COLOR_Format16bitRGB565); @@ -79,8 +83,8 @@ SoftwareRenderer::SoftwareRenderer( } CHECK(mNativeWindow != NULL); - CHECK(mWidth > 0); - CHECK(mHeight > 0); + CHECK(mCropWidth > 0); + CHECK(mCropHeight > 0); CHECK(mConverter == NULL || mConverter->isValid()); CHECK_EQ(0, @@ -109,14 +113,6 @@ SoftwareRenderer::SoftwareRenderer( CHECK_EQ(0, native_window_set_buffers_transform( mNativeWindow.get(), transform)); } - - android_native_rect_t crop; - crop.left = mCropLeft; - crop.top = mCropTop; - crop.right = mCropRight + 1; - crop.bottom = mCropBottom + 1; - - CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop)); } SoftwareRenderer::~SoftwareRenderer() { @@ -142,7 +138,7 @@ void SoftwareRenderer::render( GraphicBufferMapper &mapper = GraphicBufferMapper::get(); - Rect bounds(mWidth, mHeight); + Rect bounds(mCropWidth, mCropHeight); void *dst; CHECK_EQ(0, mapper.lock( @@ -152,13 +148,11 @@ void SoftwareRenderer::render( mConverter->convert( data, mWidth, mHeight, - 0, 0, mWidth - 1, mHeight - 1, + mCropLeft, mCropTop, mCropRight, mCropBottom, dst, buf->stride, buf->height, - 0, 0, mWidth - 1, mHeight - 1); - } else { - CHECK_EQ(mColorFormat, OMX_COLOR_FormatYUV420Planar); - + 0, 0, mCropWidth - 1, mCropHeight - 1); + } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) { const uint8_t *src_y = (const uint8_t *)data; const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight; const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2); @@ -170,22 +164,57 @@ void SoftwareRenderer::render( uint8_t *dst_v = dst_y + dst_y_size; uint8_t *dst_u = dst_v + dst_c_size; - for (int y = 0; y < mHeight; ++y) { - memcpy(dst_y, src_y, mWidth); + for (int y = 0; y < mCropHeight; ++y) { + memcpy(dst_y, src_y, mCropWidth); src_y += mWidth; dst_y += buf->stride; } - for (int y = 0; y < (mHeight + 1) / 2; ++y) { - memcpy(dst_u, src_u, (mWidth + 1) / 2); - memcpy(dst_v, src_v, (mWidth + 1) / 2); + for (int y = 0; y < (mCropHeight + 1) / 2; ++y) { + memcpy(dst_u, src_u, (mCropWidth + 1) / 2); + memcpy(dst_v, src_v, (mCropWidth + 1) / 2); src_u += mWidth / 2; src_v += mWidth / 2; dst_u += dst_c_stride; dst_v += dst_c_stride; } + } else { + CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar); + + const uint8_t *src_y = + (const uint8_t *)data; + + const uint8_t *src_uv = + (const uint8_t *)data + mWidth * (mHeight - mCropTop / 2); + + uint8_t *dst_y = (uint8_t *)dst; + + size_t dst_y_size = buf->stride * buf->height; + size_t dst_c_stride = ALIGN(buf->stride / 2, 16); + size_t dst_c_size = dst_c_stride * buf->height / 2; + uint8_t *dst_v = dst_y + dst_y_size; + uint8_t *dst_u = dst_v + dst_c_size; + + for (int y = 0; y < mCropHeight; ++y) { + memcpy(dst_y, src_y, mCropWidth); + + src_y += mWidth; + dst_y += buf->stride; + } + + for (int y = 0; y < (mCropHeight + 1) / 2; ++y) { + size_t tmp = (mCropWidth + 1) / 2; + for (size_t x = 0; x < tmp; ++x) { + dst_u[x] = src_uv[2 * x]; + dst_v[x] = src_uv[2 * x + 1]; + } + + src_uv += mWidth; + dst_u += dst_c_stride; + dst_v += dst_c_stride; + } } CHECK_EQ(0, mapper.unlock(buf->handle)); -- cgit v1.1