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

Commit 007f42d8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "C2 Decoders: Move copy/convert functions to SimpleC2Component" am: 2a66dac0 am: f58ef12c

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1935518

Change-Id: I233277c71942a455e9057ddb372bfa0636598213
parents e262ff06 f58ef12c
Loading
Loading
Loading
Loading
+5 −128
Original line number Diff line number Diff line
@@ -505,124 +505,6 @@ void C2SoftAomDec::process(const std::unique_ptr<C2Work>& work,
    }
}

static void copyOutputBufferToYuvPlanarFrame(
        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
        size_t srcYStride, size_t srcUStride, size_t srcVStride,
        size_t dstYStride, size_t dstUVStride,
        uint32_t width, uint32_t height) {

    for (size_t i = 0; i < height; ++i) {
        memcpy(dstY, srcY, width);
        srcY += srcYStride;
        dstY += dstYStride;
    }

    for (size_t i = 0; i < height / 2; ++i) {
        memcpy(dstV, srcV, width / 2);
        srcV += srcVStride;
        dstV += dstUVStride;
    }

    for (size_t i = 0; i < height / 2; ++i) {
        memcpy(dstU, srcU, width / 2);
        srcU += srcUStride;
        dstU += dstUVStride;
    }
}

static void convertYUV420Planar16ToY410(uint32_t *dst,
        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
        size_t srcYStride, size_t srcUStride, size_t srcVStride,
        size_t dstStride, size_t width, size_t height) {

    // Converting two lines at a time, slightly faster
    for (size_t y = 0; y < height; y += 2) {
        uint32_t *dstTop = (uint32_t *) dst;
        uint32_t *dstBot = (uint32_t *) (dst + dstStride);
        uint16_t *ySrcTop = (uint16_t*) srcY;
        uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride);
        uint16_t *uSrc = (uint16_t*) srcU;
        uint16_t *vSrc = (uint16_t*) srcV;

        uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
        size_t x = 0;
        for (; x < width - 3; x += 4) {

            u01 = *((uint32_t*)uSrc); uSrc += 2;
            v01 = *((uint32_t*)vSrc); vSrc += 2;

            y01 = *((uint32_t*)ySrcTop); ySrcTop += 2;
            y23 = *((uint32_t*)ySrcTop); ySrcTop += 2;
            y45 = *((uint32_t*)ySrcBot); ySrcBot += 2;
            y67 = *((uint32_t*)ySrcBot); ySrcBot += 2;

            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
            uv1 = (u01 >> 16) | ((v01 >> 16) << 20);

            *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
            *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
            *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
            *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;

            *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
            *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
            *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
            *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
        }

        // There should be at most 2 more pixels to process. Note that we don't
        // need to consider odd case as the buffer is always aligned to even.
        if (x < width) {
            u01 = *uSrc;
            v01 = *vSrc;
            y01 = *((uint32_t*)ySrcTop);
            y45 = *((uint32_t*)ySrcBot);
            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
            *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
            *dstTop++ = ((y01 >> 16) << 10) | uv0;
            *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
            *dstBot++ = ((y45 >> 16) << 10) | uv0;
        }

        srcY += srcYStride * 2;
        srcU += srcUStride;
        srcV += srcVStride;
        dst += dstStride * 2;
    }

    return;
}

static void convertYUV420Planar16ToYUV420Planar(
        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
        size_t srcYStride, size_t srcUStride, size_t srcVStride,
        size_t dstYStride, size_t dstUVStride,
        size_t width, size_t height) {

    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            dstY[x] = (uint8_t)(srcY[x] >> 2);
        }

        srcY += srcYStride;
        dstY += dstYStride;
    }

    for (size_t y = 0; y < (height + 1) / 2; ++y) {
        for (size_t x = 0; x < (width + 1) / 2; ++x) {
            dstU[x] = (uint8_t)(srcU[x] >> 2);
            dstV[x] = (uint8_t)(srcV[x] >> 2);
        }

        srcU += srcUStride;
        srcV += srcVStride;
        dstU += dstUVStride;
        dstV += dstUVStride;
    }
    return;
}
bool C2SoftAomDec::outputBuffer(
        const std::shared_ptr<C2BlockPool> &pool,
        const std::unique_ptr<C2Work> &work)
@@ -711,21 +593,16 @@ bool C2SoftAomDec::outputBuffer(
                                    dstYStride / sizeof(uint32_t),
                                    mWidth, mHeight);
        } else {
            convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
                                    srcY, srcU, srcV,
                                    srcYStride / 2, srcUStride / 2, srcVStride / 2,
                                    dstYStride, dstUVStride,
            convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
                                        srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride,
                                        mWidth, mHeight);
        }
    } else {
        const uint8_t *srcY = (const uint8_t *)img->planes[AOM_PLANE_Y];
        const uint8_t *srcU = (const uint8_t *)img->planes[AOM_PLANE_U];
        const uint8_t *srcV = (const uint8_t *)img->planes[AOM_PLANE_V];
        copyOutputBufferToYuvPlanarFrame(
                dstY, dstU, dstV, srcY, srcU, srcV,
                srcYStride, srcUStride, srcVStride,
                dstYStride, dstUVStride,
                mWidth, mHeight);
        convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                                   srcVStride, dstYStride, dstUVStride, mWidth, mHeight);
    }
    finishWork(*(int64_t*)img->user_priv, work, std::move(block));
    block = nullptr;
+172 −0
Original line number Diff line number Diff line
@@ -29,7 +29,179 @@
#include <SimpleC2Component.h>

namespace android {
constexpr uint8_t kNeutralUVBitDepth8 = 128;
constexpr uint16_t kNeutralUVBitDepth10 = 512;

void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY,
                                const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride,
                                size_t srcUStride, size_t srcVStride, size_t dstYStride,
                                size_t dstUVStride, uint32_t width, uint32_t height,
                                bool isMonochrome) {
    for (size_t i = 0; i < height; ++i) {
        memcpy(dstY, srcY, width);
        srcY += srcYStride;
        dstY += dstYStride;
    }

    if (isMonochrome) {
        // Fill with neutral U/V values.
        for (size_t i = 0; i < height / 2; ++i) {
            memset(dstV, kNeutralUVBitDepth8, width / 2);
            memset(dstU, kNeutralUVBitDepth8, width / 2);
            dstV += dstUVStride;
            dstU += dstUVStride;
        }
        return;
    }

    for (size_t i = 0; i < height / 2; ++i) {
        memcpy(dstV, srcV, width / 2);
        srcV += srcVStride;
        dstV += dstUVStride;
    }

    for (size_t i = 0; i < height / 2; ++i) {
        memcpy(dstU, srcU, width / 2);
        srcU += srcUStride;
        dstU += dstUVStride;
    }
}

void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU,
                                 const uint16_t *srcV, size_t srcYStride, size_t srcUStride,
                                 size_t srcVStride, size_t dstStride, size_t width, size_t height) {
    // Converting two lines at a time, slightly faster
    for (size_t y = 0; y < height; y += 2) {
        uint32_t *dstTop = (uint32_t *)dst;
        uint32_t *dstBot = (uint32_t *)(dst + dstStride);
        uint16_t *ySrcTop = (uint16_t *)srcY;
        uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride);
        uint16_t *uSrc = (uint16_t *)srcU;
        uint16_t *vSrc = (uint16_t *)srcV;

        uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
        size_t x = 0;
        for (; x < width - 3; x += 4) {
            u01 = *((uint32_t *)uSrc);
            uSrc += 2;
            v01 = *((uint32_t *)vSrc);
            vSrc += 2;

            y01 = *((uint32_t *)ySrcTop);
            ySrcTop += 2;
            y23 = *((uint32_t *)ySrcTop);
            ySrcTop += 2;
            y45 = *((uint32_t *)ySrcBot);
            ySrcBot += 2;
            y67 = *((uint32_t *)ySrcBot);
            ySrcBot += 2;

            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
            uv1 = (u01 >> 16) | ((v01 >> 16) << 20);

            *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
            *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
            *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
            *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;

            *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
            *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
            *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
            *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
        }

        // There should be at most 2 more pixels to process. Note that we don't
        // need to consider odd case as the buffer is always aligned to even.
        if (x < width) {
            u01 = *uSrc;
            v01 = *vSrc;
            y01 = *((uint32_t *)ySrcTop);
            y45 = *((uint32_t *)ySrcBot);
            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
            *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
            *dstTop++ = ((y01 >> 16) << 10) | uv0;
            *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
            *dstBot++ = ((y45 >> 16) << 10) | uv0;
        }

        srcY += srcYStride * 2;
        srcU += srcUStride;
        srcV += srcVStride;
        dst += dstStride * 2;
    }
}

void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY,
                                 const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride,
                                 size_t srcUStride, size_t srcVStride, size_t dstYStride,
                                 size_t dstUVStride, size_t width, size_t height,
                                 bool isMonochrome) {
    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            dstY[x] = (uint8_t)(srcY[x] >> 2);
        }
        srcY += srcYStride;
        dstY += dstYStride;
    }

    if (isMonochrome) {
        // Fill with neutral U/V values.
        for (size_t y = 0; y < (height + 1) / 2; ++y) {
            memset(dstV, kNeutralUVBitDepth8, (width + 1) / 2);
            memset(dstU, kNeutralUVBitDepth8, (width + 1) / 2);
            dstV += dstUVStride;
            dstU += dstUVStride;
        }
        return;
    }

    for (size_t y = 0; y < (height + 1) / 2; ++y) {
        for (size_t x = 0; x < (width + 1) / 2; ++x) {
            dstU[x] = (uint8_t)(srcU[x] >> 2);
            dstV[x] = (uint8_t)(srcV[x] >> 2);
        }
        srcU += srcUStride;
        srcV += srcVStride;
        dstU += dstUVStride;
        dstV += dstUVStride;
    }
}

void convertYUV420Planar16ToP010(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY,
                                 const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride,
                                 size_t srcUStride, size_t srcVStride, size_t dstYStride,
                                 size_t dstUVStride, size_t width, size_t height,
                                 bool isMonochrome) {
    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            dstY[x] = srcY[x] << 6;
        }
        srcY += srcYStride;
        dstY += dstYStride;
    }

    if (isMonochrome) {
        // Fill with neutral U/V values.
        for (size_t y = 0; y < (height + 1) / 2; ++y) {
            for (size_t x = 0; x < (width + 1) / 2; ++x) {
                dstUV[2 * x] = kNeutralUVBitDepth10 << 6;
                dstUV[2 * x + 1] = kNeutralUVBitDepth10 << 6;
            }
            dstUV += dstUVStride;
        }
        return;
    }

    for (size_t y = 0; y < (height + 1) / 2; ++y) {
        for (size_t x = 0; x < (width + 1) / 2; ++x) {
            dstUV[2 * x] = srcU[x] << 6;
            dstUV[2 * x + 1] = srcV[x] << 6;
        }
        srcU += srcUStride;
        srcV += srcVStride;
        dstUV += dstUVStride;
    }
}
std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
    std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
    mQueue.pop_front();
+18 −0
Original line number Diff line number Diff line
@@ -28,6 +28,24 @@

namespace android {

void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY,
                                const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride,
                                size_t srcUStride, size_t srcVStride, size_t dstYStride,
                                size_t dstUVStride, uint32_t width, uint32_t height,
                                bool isMonochrome = false);
void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU,
                                 const uint16_t *srcV, size_t srcYStride, size_t srcUStride,
                                 size_t srcVStride, size_t dstStride, size_t width, size_t height);
void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY,
                                 const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride,
                                 size_t srcUStride, size_t srcVStride, size_t dstYStride,
                                 size_t dstUVStride, size_t width, size_t height,
                                 bool isMonochrome = false);
void convertYUV420Planar16ToP010(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY,
                                 const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride,
                                 size_t srcUStride, size_t srcVStride, size_t dstYStride,
                                 size_t dstUVStride, size_t width, size_t height,
                                 bool isMonochrome = false);
class SimpleC2Component
        : public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
public:
+12 −159
Original line number Diff line number Diff line
@@ -28,11 +28,6 @@
#include <media/stagefright/foundation/MediaDefs.h>

namespace android {
namespace {

constexpr uint8_t NEUTRAL_UV_VALUE = 128;

}  // namespace

// codecname set and passed in as a compile flag from Android.bp
constexpr char COMPONENT_NAME[] = CODECNAME;
@@ -545,150 +540,6 @@ void C2SoftGav1Dec::process(const std::unique_ptr<C2Work> &work,
  }
}

static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
                                        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
                                        size_t srcYStride, size_t srcUStride, size_t srcVStride,
                                        size_t dstYStride, size_t dstUVStride,
                                        uint32_t width, uint32_t height,
                                        bool isMonochrome) {

  for (size_t i = 0; i < height; ++i) {
    memcpy(dstY, srcY, width);
    srcY += srcYStride;
    dstY += dstYStride;
  }

  if (isMonochrome) {
    // Fill with neutral U/V values.
    for (size_t i = 0; i < height / 2; ++i) {
      memset(dstV, NEUTRAL_UV_VALUE, width / 2);
      memset(dstU, NEUTRAL_UV_VALUE, width / 2);
      dstV += dstUVStride;
      dstU += dstUVStride;
    }
    return;
  }

  for (size_t i = 0; i < height / 2; ++i) {
    memcpy(dstV, srcV, width / 2);
    srcV += srcVStride;
    dstV += dstUVStride;
  }

  for (size_t i = 0; i < height / 2; ++i) {
    memcpy(dstU, srcU, width / 2);
    srcU += srcUStride;
    dstU += dstUVStride;
  }
}

static void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY,
                                        const uint16_t *srcU,
                                        const uint16_t *srcV, size_t srcYStride,
                                        size_t srcUStride, size_t srcVStride,
                                        size_t dstStride, size_t width,
                                        size_t height) {
  // Converting two lines at a time, slightly faster
  for (size_t y = 0; y < height; y += 2) {
    uint32_t *dstTop = (uint32_t *)dst;
    uint32_t *dstBot = (uint32_t *)(dst + dstStride);
    uint16_t *ySrcTop = (uint16_t *)srcY;
    uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride);
    uint16_t *uSrc = (uint16_t *)srcU;
    uint16_t *vSrc = (uint16_t *)srcV;

    uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
    size_t x = 0;
    for (; x < width - 3; x += 4) {
      u01 = *((uint32_t *)uSrc);
      uSrc += 2;
      v01 = *((uint32_t *)vSrc);
      vSrc += 2;

      y01 = *((uint32_t *)ySrcTop);
      ySrcTop += 2;
      y23 = *((uint32_t *)ySrcTop);
      ySrcTop += 2;
      y45 = *((uint32_t *)ySrcBot);
      ySrcBot += 2;
      y67 = *((uint32_t *)ySrcBot);
      ySrcBot += 2;

      uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
      uv1 = (u01 >> 16) | ((v01 >> 16) << 20);

      *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
      *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
      *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
      *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;

      *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
      *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
      *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
      *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
    }

    // There should be at most 2 more pixels to process. Note that we don't
    // need to consider odd case as the buffer is always aligned to even.
    if (x < width) {
      u01 = *uSrc;
      v01 = *vSrc;
      y01 = *((uint32_t *)ySrcTop);
      y45 = *((uint32_t *)ySrcBot);
      uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
      *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
      *dstTop++ = ((y01 >> 16) << 10) | uv0;
      *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
      *dstBot++ = ((y45 >> 16) << 10) | uv0;
    }

    srcY += srcYStride * 2;
    srcU += srcUStride;
    srcV += srcVStride;
    dst += dstStride * 2;
  }
}

static void convertYUV420Planar16ToYUV420Planar(
    uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
    const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
    size_t srcYStride, size_t srcUStride, size_t srcVStride,
    size_t dstYStride, size_t dstUVStride,
    size_t width, size_t height, bool isMonochrome) {

  for (size_t y = 0; y < height; ++y) {
    for (size_t x = 0; x < width; ++x) {
      dstY[x] = (uint8_t)(srcY[x] >> 2);
    }

    srcY += srcYStride;
    dstY += dstYStride;
  }

  if (isMonochrome) {
    // Fill with neutral U/V values.
    for (size_t y = 0; y < (height + 1) / 2; ++y) {
      memset(dstV, NEUTRAL_UV_VALUE, (width + 1) / 2);
      memset(dstU, NEUTRAL_UV_VALUE, (width + 1) / 2);
      dstV += dstUVStride;
      dstU += dstUVStride;
    }
    return;
  }

  for (size_t y = 0; y < (height + 1) / 2; ++y) {
    for (size_t x = 0; x < (width + 1) / 2; ++x) {
      dstU[x] = (uint8_t)(srcU[x] >> 2);
      dstV[x] = (uint8_t)(srcV[x] >> 2);
    }

    srcU += srcUStride;
    srcV += srcVStride;
    dstU += dstUVStride;
    dstV += dstUVStride;
  }
}

void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) {
    VuiColorAspects vuiColorAspects;
    vuiColorAspects.primaries = buffer->color_primary;
@@ -841,22 +692,24 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
    const uint16_t *srcV = (const uint16_t *)buffer->plane[2];

    if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
      convertYUV420Planar16ToY410(
          (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
          srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight);
        convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
                                    mWidth, mHeight);
    } else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
        convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
                                    srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2,
                                    dstUVStride / 2, mWidth, mHeight, isMonochrome);
    } else {
      convertYUV420Planar16ToYUV420Planar(
          dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
          srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight,
          isMonochrome);
        convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth,
                                    mHeight, isMonochrome);
    }
  } else {
    const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
    const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
    const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
    copyOutputBufferToYV12Frame(
        dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
        dstYStride, dstUVStride, mWidth, mHeight, isMonochrome);
    convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                               srcVStride, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome);
  }
  finishWork(buffer->user_private_data, work, std::move(block));
  block = nullptr;
+11 −39
Original line number Diff line number Diff line
@@ -419,40 +419,6 @@ bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) {
    return resChanged;
}

/* TODO: can remove temporary copy after library supports writing to display
 * buffer Y, U and V plane pointers using stride info. */
static void copyOutputBufferToYuvPlanarFrame(
        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, uint8_t *src,
        size_t dstYStride, size_t dstUVStride,
        size_t srcYStride, uint32_t width,
        uint32_t height) {
    size_t srcUVStride = srcYStride / 2;
    uint8_t *srcStart = src;

    size_t vStride = align(height, 16);
    for (size_t i = 0; i < height; ++i) {
         memcpy(dstY, src, width);
         src += srcYStride;
         dstY += dstYStride;
    }

    /* U buffer */
    src = srcStart + vStride * srcYStride;
    for (size_t i = 0; i < height / 2; ++i) {
         memcpy(dstU, src, width / 2);
         src += srcUVStride;
         dstU += dstUVStride;
    }

    /* V buffer */
    src = srcStart + vStride * srcYStride * 5 / 4;
    for (size_t i = 0; i < height / 2; ++i) {
         memcpy(dstV, src, width / 2);
         src += srcUVStride;
         dstV += dstUVStride;
    }
}

void C2SoftMpeg4Dec::process(
        const std::unique_ptr<C2Work> &work,
        const std::shared_ptr<C2BlockPool> &pool) {
@@ -636,11 +602,17 @@ void C2SoftMpeg4Dec::process(
        C2PlanarLayout layout = wView.layout();
        size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
        size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
        (void)copyOutputBufferToYuvPlanarFrame(
                outputBufferY, outputBufferU, outputBufferV,
                mOutputBuffer[mNumSamplesOutput & 1],
                dstYStride, dstUVStride,
                align(mWidth, 16), mWidth, mHeight);
        size_t srcYStride = align(mWidth, 16);
        size_t srcUStride = srcYStride / 2;
        size_t srcVStride = srcYStride / 2;
        size_t vStride = align(mHeight, 16);
        const uint8_t *srcY = (const uint8_t *)mOutputBuffer[mNumSamplesOutput & 1];
        const uint8_t *srcU = (const uint8_t *)srcY + vStride * srcYStride;
        const uint8_t *srcV = (const uint8_t *)srcY + vStride * srcYStride * 5 / 4;

        convertYUV420Planar8ToYV12(outputBufferY, outputBufferU, outputBufferV, srcY, srcU, srcV,
                                   srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride,
                                   mWidth, mHeight);

        inPos += inSize - (size_t)tmpInSize;
        finishWork(workIndex, work);
Loading