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

Commit 3c8a4bfa authored by James Zern's avatar James Zern Committed by Automerger Merge Worker
Browse files

gav1: support 444 and 422 for 10bit (YV12/P010 paths) am: 0958b8ba

parents 1d72cc7f 0958b8ba
Loading
Loading
Loading
Loading
+101 −10
Original line number Diff line number Diff line
@@ -726,6 +726,24 @@ void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) {
    }
}

void C2SoftGav1Dec::setError(const std::unique_ptr<C2Work> &work, c2_status_t error) {
    mSignalledError = true;
    work->result = error;
    work->workletsProcessed = 1u;
}

bool C2SoftGav1Dec::allocTmpFrameBuffer(size_t size) {
    if (size > mTmpFrameBufferSize) {
        mTmpFrameBuffer = std::make_unique<uint16_t[]>(size);
        if (mTmpFrameBuffer == nullptr) {
            mTmpFrameBufferSize = 0;
            return false;
        }
        mTmpFrameBufferSize = size;
    }
    return true;
}

bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
                                 const std::unique_ptr<C2Work> &work) {
  if (!(work && pool)) return false;
@@ -772,6 +790,7 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
  getHDRStaticParams(buffer, work);
  getHDR10PlusInfoData(buffer, work);

#if LIBYUV_VERSION < 1779
  if (buffer->bitdepth == 10 &&
      !(buffer->image_format == libgav1::kImageFormatYuv420 ||
        buffer->image_format == libgav1::kImageFormatMonochrome400)) {
@@ -781,6 +800,7 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
    work->result = C2_CORRUPTED;
    return false;
  }
#endif

  const bool isMonochrome =
      buffer->image_format == libgav1::kImageFormatMonochrome400;
@@ -854,9 +874,6 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
  uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
  uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
  uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
  size_t srcYStride = buffer->stride[0];
  size_t srcUStride = buffer->stride[1];
  size_t srcVStride = buffer->stride[2];

  C2PlanarLayout layout = wView.layout();
  size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
@@ -867,26 +884,100 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
    const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
    const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
    const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
    size_t srcYStride = buffer->stride[0] / 2;
    size_t srcUStride = buffer->stride[1] / 2;
    size_t srcVStride = buffer->stride[2] / 2;

    if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
        convertYUV420Planar16ToY410OrRGBA1010102(
                (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
                srcUStride / 2, srcVStride / 2,
                (uint32_t *)dstY, srcY, srcU, srcV, srcYStride,
                srcUStride, srcVStride,
                dstYStride / sizeof(uint32_t), mWidth, mHeight,
                std::static_pointer_cast<const C2ColorAspectsStruct>(codedColorAspects));
    } else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
        dstYStride /= 2;
        dstUStride /= 2;
        dstVStride /= 2;
#if LIBYUV_VERSION >= 1779
        if (buffer->image_format == libgav1::kImageFormatYuv444 ||
            buffer->image_format == libgav1::kImageFormatYuv422) {
            // TODO(https://crbug.com/libyuv/952): replace this block with libyuv::I410ToP010 and
            // libyuv::I210ToP010 when they are available.
            // Note it may be safe to alias dstY in I010ToP010, but the libyuv API doesn't make any
            // guarantees.
            const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
            if (!allocTmpFrameBuffer(tmpSize)) {
                ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
                setError(work, C2_NO_MEMORY);
                return false;
            }
            uint16_t *const tmpY = mTmpFrameBuffer.get();
            uint16_t *const tmpU = tmpY + dstYStride * mHeight;
            uint16_t *const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
            if (buffer->image_format == libgav1::kImageFormatYuv444) {
                libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
                                   tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
                                   mWidth, mHeight);
            } else {
                libyuv::I210ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
                                   tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
                                   mWidth, mHeight);
            }
            libyuv::I010ToP010(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
                               (uint16_t*)dstY, dstYStride, (uint16_t*)dstU, dstUStride,
                               mWidth, mHeight);
        } else {
            convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
                                        srcYStride, srcUStride, srcVStride, dstYStride,
                                        dstUStride, mWidth, mHeight, isMonochrome);
        }
#else  // LIBYUV_VERSION < 1779
        convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
                                    srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2,
                                    dstUStride / 2, mWidth, mHeight, isMonochrome);
                                    srcYStride, srcUStride, srcVStride, dstYStride,
                                    dstUStride, mWidth, mHeight, isMonochrome);
#endif  // LIBYUV_VERSION >= 1779
    } else {
        convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2, dstYStride, dstUStride, mWidth,
                                    mHeight, isMonochrome);
#if LIBYUV_VERSION >= 1779
        if (buffer->image_format == libgav1::kImageFormatYuv444) {
            // TODO(https://crbug.com/libyuv/950): replace this block with libyuv::I410ToI420 when
            // it's available.
            const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
            if (!allocTmpFrameBuffer(tmpSize)) {
                ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
                setError(work, C2_NO_MEMORY);
                return false;
            }
            uint16_t *const tmpY = mTmpFrameBuffer.get();
            uint16_t *const tmpU = tmpY + dstYStride * mHeight;
            uint16_t *const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
            libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
                               tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
                               mWidth, mHeight);
            libyuv::I010ToI420(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
                               dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
                               mWidth, mHeight);
        } else if (buffer->image_format == libgav1::kImageFormatYuv422) {
            libyuv::I210ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
                               dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
                               mWidth, mHeight);
        } else {
            convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
                                        srcUStride, srcVStride, dstYStride, dstUStride,
                                        mWidth, mHeight, isMonochrome);
        }
#else  // LIBYUV_VERSION < 1779
        convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
                                    srcUStride, srcVStride, dstYStride, dstUStride,
                                    mWidth, mHeight, isMonochrome);
#endif  // LIBYUV_VERSION >= 1779
    }
  } 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];
    size_t srcYStride = buffer->stride[0];
    size_t srcUStride = buffer->stride[1];
    size_t srcVStride = buffer->stride[2];

    if (buffer->image_format == libgav1::kImageFormatYuv444) {
        libyuv::I444ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+8 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@

#include <inttypes.h>

#include <memory>

#include <media/stagefright/foundation/ColorUtils.h>

#include <SimpleC2Component.h>
@@ -60,6 +62,9 @@ struct C2SoftGav1Dec : public SimpleC2Component {
  uint32_t mHeight;
  bool mSignalledOutputEos;
  bool mSignalledError;
  // Used during 10-bit I444/I422 to 10-bit P010 & 8-bit I420 conversions.
  std::unique_ptr<uint16_t[]> mTmpFrameBuffer;
  size_t mTmpFrameBufferSize = 0;

  C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
  std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
@@ -97,6 +102,9 @@ struct C2SoftGav1Dec : public SimpleC2Component {
  void destroyDecoder();
  void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
                  const std::shared_ptr<C2GraphicBlock>& block);
  // Sets |work->result| and mSignalledError. Returns false.
  void setError(const std::unique_ptr<C2Work> &work, c2_status_t error);
  bool allocTmpFrameBuffer(size_t size);
  bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
                    const std::unique_ptr<C2Work>& work);
  c2_status_t drainInternal(uint32_t drainMode,