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

Commit 0f11bc44 authored by Harish Mahendrakar's avatar Harish Mahendrakar Committed by Automerger Merge Worker
Browse files

C2SoftDav1dDec: Move libyuv calls to SimpleC2Component am: 29351ea1

parents 2984dc46 29351ea1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -42,6 +42,10 @@ cc_library {
        "libnativewindow_headers",
    ],

    static_libs: [
        "libyuv_static", // for conversion routines
    ],

    shared_libs: [
        "libcutils", // for properties
        "liblog", // for ALOG
+125 −0
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@
#include <android/hardware_buffer.h>
#include <cutils/properties.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>

#include <inttypes.h>
#include <libyuv.h>

#include <C2Config.h>
#include <C2Debug.h>
@@ -32,6 +34,15 @@
#include <SimpleC2Component.h>

namespace android {

// libyuv version required for I410ToAB30Matrix and I210ToAB30Matrix.
#if LIBYUV_VERSION >= 1780
#include <algorithm>
#define HAVE_LIBYUV_I410_I210_TO_AB30 1
#else
#define HAVE_LIBYUV_I410_I210_TO_AB30 0
#endif

constexpr uint8_t kNeutralUVBitDepth8 = 128;
constexpr uint16_t kNeutralUVBitDepth10 = 512;

@@ -506,6 +517,120 @@ void convertRGBA1010102ToYUV420Planar16(uint16_t* dstY, uint16_t* dstU, uint16_t
    }
}

void convertPlanar16ToY410OrRGBA1010102(uint8_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,
                                        std::shared_ptr<const C2ColorAspectsStruct> aspects,
                                        CONV_FORMAT_T format) {
    bool processed = false;
#if HAVE_LIBYUV_I410_I210_TO_AB30
    if (format == CONV_FORMAT_I444) {
        libyuv::I410ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dst,
                                 dstStride, &libyuv::kYuvV2020Constants, width, height);
        processed = true;
    } else if (format == CONV_FORMAT_I422) {
        libyuv::I210ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dst,
                                 dstStride, &libyuv::kYuvV2020Constants, width, height);
        processed = true;
    }
#endif  // HAVE_LIBYUV_I410_I210_TO_AB30
    if (!processed) {
        convertYUV420Planar16ToY410OrRGBA1010102(
                (uint32_t*)dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
                dstStride / sizeof(uint32_t), width, height,
                std::static_pointer_cast<const C2ColorAspectsStruct>(aspects));
    }
}

void convertPlanar16ToP010(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 dstUStride, size_t dstVStride, size_t width, size_t height,
                           bool isMonochrome, CONV_FORMAT_T format, uint16_t* tmpFrameBuffer,
                           size_t tmpFrameBufferSize) {
#if LIBYUV_VERSION >= 1779
    if ((format == CONV_FORMAT_I444) || (format == CONV_FORMAT_I422)) {
        // 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 * height + dstUStride * align(height, 2);
        CHECK(tmpSize <= tmpFrameBufferSize);

        uint16_t* const tmpY = tmpFrameBuffer;
        uint16_t* const tmpU = tmpY + dstYStride * height;
        uint16_t* const tmpV = tmpU + dstUStride * align(height, 2) / 2;
        if (format == CONV_FORMAT_I444) {
            libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, tmpY,
                               dstYStride, tmpU, dstUStride, tmpV, dstUStride, width, height);
        } else {
            libyuv::I210ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, tmpY,
                               dstYStride, tmpU, dstUStride, tmpV, dstUStride, width, height);
        }
        libyuv::I010ToP010(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride, dstY, dstYStride,
                           dstUV, dstUStride, width, height);
    } else {
        convertYUV420Planar16ToP010(dstY, dstUV, srcY, srcU, srcV, srcYStride, srcUStride,
                                    srcVStride, dstYStride, dstUStride, width, height,
                                    isMonochrome);
    }
#else   // LIBYUV_VERSION < 1779
    convertYUV420Planar16ToP010(dstY, dstUV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
                                dstYStride, dstUStride, width, height, isMonochrome);
#endif  // LIBYUV_VERSION >= 1779
}

void convertPlanar16ToYV12(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 dstUStride, size_t dstVStride, size_t width, size_t height,
                           bool isMonochrome, CONV_FORMAT_T format, uint16_t* tmpFrameBuffer,
                           size_t tmpFrameBufferSize) {
#if LIBYUV_VERSION >= 1779
    if (format == CONV_FORMAT_I444) {
        // TODO(https://crbug.com/libyuv/950): replace this block with libyuv::I410ToI420
        // when it's available.
        const size_t tmpSize = dstYStride * height + dstUStride * align(height, 2);
        CHECK(tmpSize <= tmpFrameBufferSize);

        uint16_t* const tmpY = tmpFrameBuffer;
        uint16_t* const tmpU = tmpY + dstYStride * height;
        uint16_t* const tmpV = tmpU + dstUStride * align(height, 2) / 2;
        libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, tmpY, dstYStride,
                           tmpU, dstUStride, tmpV, dstVStride, width, height);
        libyuv::I010ToI420(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride, dstY, dstYStride,
                           dstU, dstUStride, dstV, dstVStride, width, height);
    } else if (format == CONV_FORMAT_I422) {
        libyuv::I210ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY, dstYStride,
                           dstU, dstUStride, dstV, dstVStride, width, height);
    } else {
        convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                                    srcVStride, dstYStride, dstUStride, width, height,
                                    isMonochrome);
    }
#else   // LIBYUV_VERSION < 1779
    convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                                srcVStride, dstYStride, dstUStride, width, height, isMonochrome);
#endif  // LIBYUV_VERSION >= 1779
}

void convertPlanar8ToYV12(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 dstUStride, size_t dstVStride, uint32_t width, uint32_t height,
                          bool isMonochrome, CONV_FORMAT_T format) {
    if (format == CONV_FORMAT_I444) {
        libyuv::I444ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY, dstYStride,
                           dstU, dstUStride, dstV, dstVStride, width, height);
    } else if (format == CONV_FORMAT_I422) {
        libyuv::I422ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY, dstYStride,
                           dstU, dstUStride, dstV, dstVStride, width, height);
    } else {
        convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                                   srcVStride, dstYStride, dstUStride, dstVStride, width, height,
                                   isMonochrome);
    }
}
std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
    std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
    mQueue.pop_front();
+30 −0
Original line number Diff line number Diff line
@@ -31,6 +31,12 @@ struct C2ColorAspectsStruct;

namespace android {

typedef enum {
    CONV_FORMAT_I420,
    CONV_FORMAT_I422,
    CONV_FORMAT_I444,
} CONV_FORMAT_T;

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,
@@ -66,6 +72,30 @@ void convertRGBA1010102ToYUV420Planar16(uint16_t* dstY, uint16_t* dstU, uint16_t
                                        const uint32_t* srcRGBA, size_t srcRGBStride, size_t width,
                                        size_t height, C2Color::matrix_t colorMatrix,
                                        C2Color::range_t colorRange);
void convertPlanar16ToY410OrRGBA1010102(uint8_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,
                                        std::shared_ptr<const C2ColorAspectsStruct> aspects,
                                        CONV_FORMAT_T format);

void convertPlanar16ToP010(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 dstUStride, size_t dstVStride, size_t width, size_t height,
                           bool isMonochrome, CONV_FORMAT_T format, uint16_t* tmpFrameBuffer,
                           size_t tmpFrameBufferSize);
void convertPlanar16ToYV12(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 dstUStride, size_t dstVStride, size_t width, size_t height,
                           bool isMonochrome, CONV_FORMAT_T format, uint16_t* tmpFrameBuffer,
                           size_t tmpFrameBufferSize);
void convertPlanar8ToYV12(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 dstUStride, size_t dstVStride, uint32_t width, uint32_t height,
                          bool isMonochrome, CONV_FORMAT_T format);

class SimpleC2Component
        : public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
+1 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ cc_library {
    defaults: [
        "libcodec2_soft-defaults",
        "libcodec2_soft_sanitize_all-defaults",
        "libcodec2_soft_sanitize_cfi-defaults",
    ],

    cflags: [
@@ -24,7 +25,6 @@ cc_library {

    srcs: ["C2SoftDav1dDec.cpp"],
    static_libs: [
        "libyuv_static",
        "libdav1d_8bit",
        "libdav1d_16bit",
    ],
+44 −123
Original line number Diff line number Diff line
@@ -26,20 +26,11 @@
#include <Codec2CommonUtils.h>
#include <Codec2Mapper.h>
#include <SimpleC2Interface.h>
#include <libyuv.h>
#include <log/log.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include "C2SoftDav1dDec.h"

// libyuv version required for I410ToAB30Matrix and I210ToAB30Matrix.
#if LIBYUV_VERSION >= 1780
#include <algorithm>
#define HAVE_LIBYUV_I410_I210_TO_AB30 1
#else
#define HAVE_LIBYUV_I410_I210_TO_AB30 0
#endif

namespace android {

// Flag to enable dumping the bitsteram and the decoded pictures to files.
@@ -1114,16 +1105,6 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
    // out_frameIndex that the decoded picture returns from dav1d.
    int64_t out_frameIndex = img.m.timestamp;

#if LIBYUV_VERSION < 1779
    if (!(img.p.layout != DAV1D_PIXEL_LAYOUT_I400 || img.p.layout != DAV1D_PIXEL_LAYOUT_I420)) {
        ALOGE("image_format %d not supported", img.p.layout);
        mSignalledError = true;
        work->workletsProcessed = 1u;
        work->result = C2_CORRUPTED;
        return false;
    }
#endif

    const bool isMonochrome = img.p.layout == DAV1D_PIXEL_LAYOUT_I400;

    int bitdepth = img.p.bpc;
@@ -1141,17 +1122,6 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
            allowRGBA1010102 = true;
        }
        format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
#if !HAVE_LIBYUV_I410_I210_TO_AB30
        if ((format == HAL_PIXEL_FORMAT_RGBA_1010102) &&
            (is_img_ready ? img.p.layout == DAV1D_PIXEL_LAYOUT_I420
                          : 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;
        }
#endif
    }

    if (mHalPixelFormat != format) {
@@ -1206,6 +1176,19 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
    size_t dstUStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
    size_t dstVStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;

    CONV_FORMAT_T convFormat;
    switch (img.p.layout) {
        case DAV1D_PIXEL_LAYOUT_I444:
            convFormat = CONV_FORMAT_I444;
            break;
        case DAV1D_PIXEL_LAYOUT_I422:
            convFormat = CONV_FORMAT_I422;
            break;
        default:
            convFormat = CONV_FORMAT_I420;
            break;
    }

    if (bitdepth == 10) {
        // TODO: b/277797541 - Investigate if we can ask DAV1D to output the required format during
        // decompression to avoid color conversion.
@@ -1217,19 +1200,6 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
        size_t srcVStride = img.stride[1] / 2;

        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
            bool processed = false;
#if HAVE_LIBYUV_I410_I210_TO_AB30
            if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
                libyuv::I410ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
                                         dstYStride, &libyuv::kYuvV2020Constants, mWidth, mHeight);
                processed = true;
            } else if (img.p.layout == DAV1D_PIXEL_LAYOUT_I422) {
                libyuv::I210ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
                                         dstYStride, &libyuv::kYuvV2020Constants, mWidth, mHeight);
                processed = true;
            }
#endif  // HAVE_LIBYUV_I410_I210_TO_AB30
            if (!processed) {
            if (isMonochrome) {
                const size_t tmpSize = mWidth;
                const bool needFill = tmpSize > mTmpFrameBufferSize;
@@ -1244,83 +1214,42 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
                    std::fill_n(mTmpFrameBuffer.get(), tmpSize, 512);
                }
            }
                convertYUV420Planar16ToY410OrRGBA1010102(
                        (uint32_t*)dstY, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
                        dstYStride / sizeof(uint32_t), mWidth, mHeight,
                        std::static_pointer_cast<const C2ColorAspectsStruct>(codedColorAspects));
            }
            convertPlanar16ToY410OrRGBA1010102(
                    dstY, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
                    dstYStride, mWidth, mHeight,
                    std::static_pointer_cast<const C2ColorAspectsStruct>(codedColorAspects),
                    convFormat);
        } else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
            dstYStride /= 2;
            dstUStride /= 2;
            dstVStride /= 2;
#if LIBYUV_VERSION >= 1779
            size_t tmpSize = 0;
            if ((img.p.layout == DAV1D_PIXEL_LAYOUT_I444) ||
                (img.p.layout == DAV1D_PIXEL_LAYOUT_I422)) {
                // 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);
                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 (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
                    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);
            convertPlanar16ToP010((uint16_t*)dstY, (uint16_t*)dstU, srcY, srcU, srcV, srcYStride,
                                  srcUStride, srcVStride, dstYStride, dstUStride, dstVStride,
                                  mWidth, mHeight, isMonochrome, convFormat, mTmpFrameBuffer.get(),
                                  tmpSize);
        } 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, srcUStride, srcVStride, dstYStride, dstUStride,
                                        mWidth, mHeight, isMonochrome);
#endif  // LIBYUV_VERSION >= 1779
        } else {
#if LIBYUV_VERSION >= 1779
            size_t tmpSize = 0;
            if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
                // 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);
                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 (img.p.layout == DAV1D_PIXEL_LAYOUT_I422) {
                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
            convertPlanar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                                  srcVStride, dstYStride, dstUStride, dstVStride, mWidth, mHeight,
                                  isMonochrome, convFormat, mTmpFrameBuffer.get(), tmpSize);
        }

        // Dump the output buffer if dumping is enabled (debug only).
@@ -1401,17 +1330,9 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
            }
        }
#endif
        if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
            libyuv::I444ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
                               dstYStride, dstU, dstUStride, dstV, dstVStride, mWidth, mHeight);
        } else if (img.p.layout == DAV1D_PIXEL_LAYOUT_I422) {
            libyuv::I422ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
                               dstYStride, dstU, dstUStride, dstV, dstVStride, mWidth, mHeight);
        } else {
            convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                                       srcVStride, dstYStride, dstUStride, dstVStride, mWidth,
                                       mHeight, isMonochrome);
        }
        convertPlanar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
                             dstYStride, dstUStride, dstVStride, mWidth, mHeight, isMonochrome,
                             convFormat);
    }

    dav1d_picture_unref(&img);