diff options
author | Andreas Huber <andih@google.com> | 2011-05-16 15:21:26 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-16 15:21:26 -0700 |
commit | 3d0de325381b66880626357f6b68ea09da0a9dda (patch) | |
tree | 7395e633446511b74b0b3021788fe0974743145f /media/libstagefright/colorconversion | |
parent | 4bbaa8808ebc6ebe6488210f2cef70c18eb06028 (diff) | |
parent | 5e97c8861ef81d07cf1e304c1c1bed09b84513d4 (diff) | |
download | frameworks_av-3d0de325381b66880626357f6b68ea09da0a9dda.zip frameworks_av-3d0de325381b66880626357f6b68ea09da0a9dda.tar.gz frameworks_av-3d0de325381b66880626357f6b68ea09da0a9dda.tar.bz2 |
Merge "Instead of using an RGB surface and conversion yuv420->rgb565"
Diffstat (limited to 'media/libstagefright/colorconversion')
-rw-r--r-- | media/libstagefright/colorconversion/SoftwareRenderer.cpp | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index ee86148..a4e8ee4 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -56,9 +56,21 @@ SoftwareRenderer::SoftwareRenderer( } int halFormat; + size_t bufWidth, bufHeight; + switch (mColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + { + halFormat = HAL_PIXEL_FORMAT_YV12; + bufWidth = (mWidth + 1) & ~1; + bufHeight = (mHeight + 1) & ~1; + break; + } + default: halFormat = HAL_PIXEL_FORMAT_RGB_565; + bufWidth = mWidth; + bufHeight = mHeight; mConverter = new ColorConverter( mColorFormat, OMX_COLOR_Format16bitRGB565); @@ -80,8 +92,8 @@ SoftwareRenderer::SoftwareRenderer( // Width must be multiple of 32??? CHECK_EQ(0, native_window_set_buffers_geometry( mNativeWindow.get(), - mCropRight - mCropLeft + 1, - mCropBottom - mCropTop + 1, + bufWidth, + bufHeight, halFormat)); uint32_t transform; @@ -97,6 +109,14 @@ 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() { @@ -104,6 +124,11 @@ SoftwareRenderer::~SoftwareRenderer() { mConverter = NULL; } +static int ALIGN(int x, int y) { + // y must be a power of 2. + return (x + y - 1) & ~(y - 1); +} + void SoftwareRenderer::render( const void *data, size_t size, void *platformPrivate) { ANativeWindowBuffer *buf; @@ -127,14 +152,40 @@ void SoftwareRenderer::render( mConverter->convert( data, mWidth, mHeight, - mCropLeft, mCropTop, mCropRight, mCropBottom, + 0, 0, mWidth - 1, mHeight - 1, dst, buf->stride, buf->height, - 0, 0, - mCropRight - mCropLeft, - mCropBottom - mCropTop); + 0, 0, mWidth - 1, mHeight - 1); } else { - TRESPASS(); + CHECK_EQ(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); + + 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 < mHeight; ++y) { + memcpy(dst_y, src_y, mWidth); + + 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); + + src_u += mWidth / 2; + src_v += mWidth / 2; + dst_u += dst_c_stride; + dst_v += dst_c_stride; + } } CHECK_EQ(0, mapper.unlock(buf->handle)); |