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

Commit 0b183338 authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am f7c3679f: Merge change 25158 into eclair

Merge commit 'f7c3679f898cdcb208bc1675c79573e1d637083a' into eclair-plus-aosp

* commit 'f7c3679f898cdcb208bc1675c79573e1d637083a':
  Another software color conversion implementation, this time OMX_QCOM_COLOR_FormatYVU420SemiPlanar => rgb565.
parents eed9de37 56a9496a
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@ private:


    void renderCbYCrY(const void *data, size_t size);
    void renderCbYCrY(const void *data, size_t size);
    void renderYUV420Planar(const void *data, size_t size);
    void renderYUV420Planar(const void *data, size_t size);
    void renderQCOMYUV420SemiPlanar(const void *data, size_t size);


    OMX_COLOR_FORMATTYPE mColorFormat;
    OMX_COLOR_FORMATTYPE mColorFormat;
    sp<ISurface> mISurface;
    sp<ISurface> mISurface;
+75 −0
Original line number Original line Diff line number Diff line
@@ -65,6 +65,8 @@ SoftwareRenderer::~SoftwareRenderer() {


void SoftwareRenderer::render(
void SoftwareRenderer::render(
        const void *data, size_t size, void *platformPrivate) {
        const void *data, size_t size, void *platformPrivate) {
    static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;

    switch (mColorFormat) {
    switch (mColorFormat) {
        case OMX_COLOR_FormatYUV420Planar:
        case OMX_COLOR_FormatYUV420Planar:
            return renderYUV420Planar(data, size);
            return renderYUV420Planar(data, size);
@@ -72,6 +74,9 @@ void SoftwareRenderer::render(
        case OMX_COLOR_FormatCbYCrY:
        case OMX_COLOR_FormatCbYCrY:
            return renderCbYCrY(data, size);
            return renderCbYCrY(data, size);


        case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
            return renderQCOMYUV420SemiPlanar(data, size);

        default:
        default:
        {
        {
            LOGW("Cannot render color format %ld", mColorFormat);
            LOGW("Cannot render color format %ld", mColorFormat);
@@ -242,6 +247,76 @@ void SoftwareRenderer::renderCbYCrY(
    mIndex = 1 - mIndex;
    mIndex = 1 - mIndex;
}
}


void SoftwareRenderer::renderQCOMYUV420SemiPlanar(
        const void *data, size_t size) {
    if (size != (mDecodedHeight * mDecodedWidth * 3) / 2) {
        LOGE("size is %d, expected %d",
                size, (mDecodedHeight * mDecodedWidth * 3) / 2);
    }
    CHECK(size >= (mDecodedWidth * mDecodedHeight * 3) / 2);

    uint8_t *kAdjustedClip = initClip();

    size_t offset = mIndex * mFrameSize;

    void *dst = (uint8_t *)mMemoryHeap->getBase() + offset;

    uint32_t *dst_ptr = (uint32_t *)dst;

    const uint8_t *src_y = (const uint8_t *)data;

    const uint8_t *src_u =
        (const uint8_t *)src_y + mDecodedWidth * mDecodedHeight;

    for (size_t y = 0; y < mDecodedHeight; ++y) {
        for (size_t x = 0; x < mDecodedWidth; 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);

            dst_ptr[x / 2] = (rgb2 << 16) | rgb1;
        }

        src_y += mDecodedWidth;

        if (y & 1) {
            src_u += mDecodedWidth;
        }

        dst_ptr += mDecodedWidth / 2;
    }

    mISurface->postBuffer(offset);
    mIndex = 1 - mIndex;
}

uint8_t *SoftwareRenderer::initClip() {
uint8_t *SoftwareRenderer::initClip() {
    static const signed kClipMin = -278;
    static const signed kClipMin = -278;
    static const signed kClipMax = 535;
    static const signed kClipMax = 535;