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

Commit f80fc08e authored by Vignesh Venkatasubramanian's avatar Vignesh Venkatasubramanian
Browse files

av1: Allow odd width/height for YUV420

Allow odd width/height values for the gav1 software decoder.

Notes:
* We already allocate the graphic block with a stride that is a
  multiple of 16, that behavior is retained.
* We also allocate the graphic buffer with a height alignment of 2 (this
  change is needed because fetchGraphicBlock fails for odd height
  values.
* We set the correct "crop" value in createGraphicBuffer() which will
  handle odd width/height appropriately.
* This change also enables decoding of AVIF images that have odd
  dimensions.

This CL contains changes to the mainline files.

Test: CtsMediaTestCases still pass
Bug: 175243729
Merged-In: I6b811fed5cc9c599177fffd24d4d96d65c52ae8e
Merged-In: I89a8d13a3faf172015b79083b40abe3b98ac9809

Change-Id: I6b811fed5cc9c599177fffd24d4d96d65c52ae8e
(cherry picked from commit db0859ec)
parent c971bbd9
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -59,8 +59,8 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
        DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
            .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
            .withFields({
                C2F(mSize, width).inRange(2, 4096, 2),
                C2F(mSize, height).inRange(2, 4096, 2),
                C2F(mSize, width).inRange(2, 4096),
                C2F(mSize, height).inRange(2, 4096),
            })
            .withSetter(SizeSetter)
            .build());
@@ -559,23 +559,23 @@ static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *d

  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);
    for (size_t i = 0; i < (height + 1) / 2; ++i) {
      memset(dstV, NEUTRAL_UV_VALUE, (width + 1) / 2);
      memset(dstU, NEUTRAL_UV_VALUE, (width + 1) / 2);
      dstV += dstUVStride;
      dstU += dstUVStride;
    }
    return;
  }

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

  for (size_t i = 0; i < height / 2; ++i) {
    memcpy(dstU, srcU, width / 2);
  for (size_t i = 0; i < (height + 1) / 2; ++i) {
    memcpy(dstU, srcU, (width + 1) / 2);
    srcU += srcUStride;
    dstU += dstUVStride;
  }
@@ -796,8 +796,12 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
  }
  C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};

  c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format,
                                            usage, &block);
  // We always create a graphic block that is width aligned to 16 and height
  // aligned to 2. We set the correct "crop" value of the image in the call to
  // createGraphicBuffer() by setting the correct image dimensions.
  c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16),
                                            align(mHeight, 2), format, usage,
                                            &block);

  if (err != C2_OK) {
    ALOGE("fetchGraphicBlock for Output failed with status %d", err);