summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/colorconversion
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-06-24 13:16:42 -0700
committerAndreas Huber <andih@google.com>2011-06-27 09:26:09 -0700
commit3571d50a2582bc9c63f09cd81b4f490ea3522bd9 (patch)
tree75922c68e5f7ad9af3d36f4a05739d58c86886e4 /media/libstagefright/colorconversion
parent884946a23cfe804491ef6067bd9361371d7848fd (diff)
downloadframeworks_av-3571d50a2582bc9c63f09cd81b4f490ea3522bd9.zip
frameworks_av-3571d50a2582bc9c63f09cd81b4f490ea3522bd9.tar.gz
frameworks_av-3571d50a2582bc9c63f09cd81b4f490ea3522bd9.tar.bz2
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
Diffstat (limited to 'media/libstagefright/colorconversion')
-rw-r--r--media/libstagefright/colorconversion/ColorConverter.cpp81
-rw-r--r--media/libstagefright/colorconversion/SoftwareRenderer.cpp79
2 files changed, 82 insertions, 78 deletions
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 <utils/Log.h>
+
#include <media/stagefright/ColorConverter.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaErrors.h>
@@ -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));