Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34bac592 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Fix the new color converter to respect the destination crop rect."

parents e5b2a430 3571d50a
Loading
Loading
Loading
Loading
+28 −53
Original line number Diff line number Diff line
@@ -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
        src_y += src.mWidth;

        if (y & 1) {
          src_u += src.mWidth; //increment U-V line
            src_u += src.mWidth;
        }

        dst_ptr += dst.mWidth / 2;
    }

    return OK;
}

+54 −25
Original line number Diff line number Diff line
@@ -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));
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ private:
    sp<ANativeWindow> mNativeWindow;
    int32_t mWidth, mHeight;
    int32_t mCropLeft, mCropTop, mCropRight, mCropBottom;
    int32_t mCropWidth, mCropHeight;

    SoftwareRenderer(const SoftwareRenderer &);
    SoftwareRenderer &operator=(const SoftwareRenderer &);