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

Commit bfd9a210 authored by Vignesh Venkatasubramanian's avatar Vignesh Venkatasubramanian Committed by James Zern
Browse files

gav1: Support monochrome videos/images

Support monochrome videos by filling U&V planes with neutral
values. Since all our output is in 8bit, the neutral value would
be 128.

Bug: 141654151
Test: AV1 related CTS tests continue to pass
Merged-In: I87eb5e11ab8bd88d4d3baf8d59c3bc53398b288d
Change-Id: I87eb5e11ab8bd88d4d3baf8d59c3bc53398b288d
(cherry picked from commit e7718810)
parent 2509e1ae
Loading
Loading
Loading
Loading
+48 −14
Original line number Original line Diff line number Diff line
@@ -26,6 +26,11 @@
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/foundation/MediaDefs.h>


namespace android {
namespace android {
namespace {

constexpr uint8_t NEUTRAL_UV_VALUE = 128;

}  // namespace


// codecname set and passed in as a compile flag from Android.bp
// codecname set and passed in as a compile flag from Android.bp
constexpr char COMPONENT_NAME[] = CODECNAME;
constexpr char COMPONENT_NAME[] = CODECNAME;
@@ -464,7 +469,8 @@ static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *d
                                        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
                                        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
                                        size_t srcYStride, size_t srcUStride, size_t srcVStride,
                                        size_t srcYStride, size_t srcUStride, size_t srcVStride,
                                        size_t dstYStride, size_t dstUVStride,
                                        size_t dstYStride, size_t dstUVStride,
                                        uint32_t width, uint32_t height) {
                                        uint32_t width, uint32_t height,
                                        bool isMonochrome) {


  for (size_t i = 0; i < height; ++i) {
  for (size_t i = 0; i < height; ++i) {
    memcpy(dstY, srcY, width);
    memcpy(dstY, srcY, width);
@@ -472,6 +478,17 @@ static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *d
    dstY += dstYStride;
    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) {
  for (size_t i = 0; i < height / 2; ++i) {
    memcpy(dstV, srcV, width / 2);
    memcpy(dstV, srcV, width / 2);
    srcV += srcVStride;
    srcV += srcVStride;
@@ -557,7 +574,7 @@ static void convertYUV420Planar16ToYUV420Planar(
    const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
    const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
    size_t srcYStride, size_t srcUStride, size_t srcVStride,
    size_t srcYStride, size_t srcUStride, size_t srcVStride,
    size_t dstYStride, size_t dstUVStride,
    size_t dstYStride, size_t dstUVStride,
    size_t width, size_t height) {
    size_t width, size_t height, bool isMonochrome) {


  for (size_t y = 0; y < height; ++y) {
  for (size_t y = 0; y < height; ++y) {
    for (size_t x = 0; x < width; ++x) {
    for (size_t x = 0; x < width; ++x) {
@@ -568,6 +585,17 @@ static void convertYUV420Planar16ToYUV420Planar(
    dstY += dstYStride;
    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 y = 0; y < (height + 1) / 2; ++y) {
    for (size_t x = 0; x < (width + 1) / 2; ++x) {
    for (size_t x = 0; x < (width + 1) / 2; ++x) {
      dstU[x] = (uint8_t)(srcU[x] >> 2);
      dstU[x] = (uint8_t)(srcU[x] >> 2);
@@ -623,8 +651,10 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
    }
    }
  }
  }


  // TODO(vigneshv): Add support for monochrome videos since AV1 supports it.
  CHECK(buffer->image_format == libgav1::kImageFormatYuv420 ||
  CHECK(buffer->image_format == libgav1::kImageFormatYuv420);
        buffer->image_format == libgav1::kImageFormatMonochrome400);
  const bool isMonochrome =
      buffer->image_format == libgav1::kImageFormatMonochrome400;


  std::shared_ptr<C2GraphicBlock> block;
  std::shared_ptr<C2GraphicBlock> block;
  uint32_t format = HAL_PIXEL_FORMAT_YV12;
  uint32_t format = HAL_PIXEL_FORMAT_YV12;
@@ -636,6 +666,13 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
    if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
    if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
        defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
        defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
        defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
        defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
      if (buffer->image_format != libgav1::kImageFormatYuv420) {
        ALOGE("Only YUV420 output is supported when targeting RGBA_1010102");
        mSignalledError = true;
        work->result = C2_OMITTED;
        work->workletsProcessed = 1u;
        return false;
      }
      format = HAL_PIXEL_FORMAT_RGBA_1010102;
      format = HAL_PIXEL_FORMAT_RGBA_1010102;
    }
    }
  }
  }
@@ -682,21 +719,18 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
          (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
          (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
          srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight);
          srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight);
    } else {
    } else {
      convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
      convertYUV420Planar16ToYUV420Planar(
                                          srcY, srcU, srcV,
          dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
                                          srcYStride / 2, srcUStride / 2, srcVStride / 2,
          srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight,
                                          dstYStride, dstUVStride,
          isMonochrome);
                                          mWidth, mHeight);
    }
    }
  } else {
  } else {
    const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
    const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
    const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
    const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
    const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
    const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
    copyOutputBufferToYV12Frame(dstY, dstU, dstV,
    copyOutputBufferToYV12Frame(
                                srcY, srcU, srcV,
        dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
                                srcYStride, srcUStride, srcVStride,
        dstYStride, dstUVStride, mWidth, mHeight, isMonochrome);
                                dstYStride, dstUVStride,
                                mWidth, mHeight);
  }
  }
  finishWork(buffer->user_private_data, work, std::move(block));
  finishWork(buffer->user_private_data, work, std::move(block));
  block = nullptr;
  block = nullptr;