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

Commit c1c8bd5b authored by Fyodor Kyslov's avatar Fyodor Kyslov Committed by Gerrit Code Review
Browse files

Merge "APV: Fix color conversion functions" into main

parents 32325124 30296bc7
Loading
Loading
Loading
Loading
+78 −58
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ const char* MEDIA_MIMETYPE_VIDEO_APV = "video/apv";
#define IS_AUX_FRM(frm) (!(IS_NON_AUX_FRM(frm)))
#define OUTPUT_CSP_NATIVE (0)
#define OUTPUT_CSP_P210 (1)
#define CLIP3(min, v, max) (((v) < (min)) ? (min) : (((max) > (v)) ? (v) : (max)))

namespace android {
namespace {
@@ -881,14 +882,17 @@ static void copyBufferFromP210ToYV12(uint8_t* dstY, uint8_t* dstU, uint8_t* dstV
                                     size_t dstVStride, size_t width, size_t height) {
    for (size_t i = 0; i < height; ++i) {
        for (size_t j = 0; j < width; ++j) {
            dstY[i * dstYStride + j] = (srcY[i * srcYStride + j] >> 8) & 0xFF;
            dstY[i * dstYStride + j] = (uint8_t)CLIP3(0, 255,
                            ((((int)srcY[i * srcYStride + j] >> 6) * 255.0) / 1023.0 + 0.5));
        }
    }

    for (size_t i = 0; i < height / 2; ++i) {
        for (size_t j = 0; j < width / 2; ++j) {
            dstV[i * dstVStride + j] = (srcUV[i * srcUVStride * 2 + j * 2] >> 8) & 0xFF;
            dstU[i * dstUStride + j] = (srcUV[i * srcUVStride * 2 + j * 2 + 1] >> 8) & 0xFF;
            dstU[i * dstVStride + j] = (uint8_t)CLIP3(0, 255,
                ((((int)srcUV[i * srcUVStride * 2 + j * 2] >> 6) * 255.0) / 1023.0 + 0.5));
            dstV[i * dstUStride + j] = (uint8_t)CLIP3(0, 255,
                ((((int)srcUV[i * srcUVStride * 2 + j * 2 + 1] >> 6) * 255.0) / 1023.0 + 0.5));
        }
    }
}
@@ -1370,6 +1374,9 @@ status_t C2SoftApvDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
                                     : (format == HAL_PIXEL_FORMAT_YV12 ? "YV12" : "UNKNOWN")));
        }
    } else {  // HAL_PIXEL_FORMAT_YV12
        if (!IsI420(wView)) {
            ALOGE("Only P210 to I420 conversion is supported.");
        } else {
            if (OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs) == 10) {
                const uint16_t* srcY = (const uint16_t*)imgbOutput->a[0];
                const uint16_t* srcV = (const uint16_t*)imgbOutput->a[1];
@@ -1379,20 +1386,24 @@ status_t C2SoftApvDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
                size_t srcUStride = imgbOutput->s[2] / 2;
                if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420) {
                    ALOGV("OAPV_CS_YUV420 10bit to YV12");
                copyBufferFromYUV42010bitToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
                                                srcUStride, srcVStride, dstYStride, dstUStride,
                                                dstVStride, mWidth, mHeight);
                    copyBufferFromYUV42010bitToYV12(
                        dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                        srcVStride, dstYStride, dstUStride, dstVStride, mWidth,
                        mHeight);
                } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422) {
                    ALOGV("OAPV_CS_YUV422 10bit to YV12");
                copyBufferFromYUV42210bitToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
                                                srcUStride, srcVStride, dstYStride, dstUStride,
                                                dstVStride, mWidth, mHeight);
                    copyBufferFromYUV42210bitToYV12(
                        dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
                        srcVStride, dstYStride, dstUStride, dstVStride, mWidth,
                        mHeight);
                } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_PLANAR2) {
                    ALOGV("OAPV_CS_P210 to YV12");
                copyBufferFromP210ToYV12(dstY, dstU, dstV, srcY, srcV, srcYStride, srcVStride,
                                         dstYStride, dstUStride, dstVStride, mWidth, mHeight);
                    copyBufferFromP210ToYV12(dstY, dstU, dstV, srcY, srcV, srcYStride,
                                       srcVStride, dstYStride, dstUStride,
                                       dstVStride, mWidth, mHeight);
                } else {
                ALOGE("Not supported convert format : %d", OAPV_CS_GET_FORMAT(imgbOutput->cs));
                    ALOGE("Not supported convert format : %d",
                            OAPV_CS_GET_FORMAT(imgbOutput->cs));
                }
            } else if (OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs) == 8) {
                const uint8_t* srcY = (const uint8_t*)imgbOutput->a[0];
@@ -1403,30 +1414,39 @@ status_t C2SoftApvDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
                size_t srcUStride = imgbOutput->s[2];
                if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420) {
                    ALOGV("OAPV_CS_YUV420 to YV12");
                copyBufferFromYUV420ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
                                           srcUStride, srcVStride, dstYStride, dstUStride,
                                           dstVStride, mWidth, mHeight);
                    copyBufferFromYUV420ToYV12(dstY, dstU, dstV, srcY, srcU, srcV,
                                         srcYStride, srcUStride, srcVStride,
                                         dstYStride, dstUStride, dstVStride,
                                         mWidth, mHeight);
                } else if (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422) {
                    ALOGV("OAPV_CS_YUV422 to YV12");
                copyBufferFromYUV422ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
                                           srcUStride, srcVStride, dstYStride, dstUStride,
                                           dstVStride, mWidth, mHeight);
                    copyBufferFromYUV422ToYV12(dstY, dstU, dstV, srcY, srcU, srcV,
                                         srcYStride, srcUStride, srcVStride,
                                         dstYStride, dstUStride, dstVStride,
                                         mWidth, mHeight);
                } else {
                ALOGE("Not supported convert format : %d", OAPV_CS_GET_FORMAT(imgbOutput->cs));
                    ALOGE("Not supported convert format : %d",
                        OAPV_CS_GET_FORMAT(imgbOutput->cs));
                }
            } else {
            ALOGE("Not supported convert from bd:%d, format: %d(%s), to format: %d(%s)",
                  OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs), OAPV_CS_GET_FORMAT(imgbOutput->cs),
                ALOGE(
                "Not supported convert from bd:%d, format: %d(%s), to format: "
                    "%d(%s)",
                    OAPV_CS_GET_BIT_DEPTH(imgbOutput->cs),
                    OAPV_CS_GET_FORMAT(imgbOutput->cs),
                    OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR420
                        ? "YUV420"
                          : (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422 ? "YUV422"
                        : (OAPV_CS_GET_FORMAT(imgbOutput->cs) == OAPV_CF_YCBCR422
                           ? "YUV422"
                           : "UNKNOWN"),
                    format,
                    format == HAL_PIXEL_FORMAT_YCBCR_P010
                        ? "P010"
                        : (format == HAL_PIXEL_FORMAT_YCBCR_420_888
                           ? "YUV420"
                                     : (format == HAL_PIXEL_FORMAT_YV12 ? "YV12" : "UNKNOWN")));
                           : (format == HAL_PIXEL_FORMAT_YV12 ? "YV12"
                                                              : "UNKNOWN")));
            }
        }
    }

+17 −9
Original line number Diff line number Diff line
@@ -994,9 +994,6 @@ c2_status_t C2SoftApvEnc::setEncodeArgs(oapv_frms_t* inputFrames, const C2Graphi
    uint8_t* yPlane = const_cast<uint8_t*>(input->data()[C2PlanarLayout::PLANE_Y]);
    uint8_t* uPlane = const_cast<uint8_t*>(input->data()[C2PlanarLayout::PLANE_U]);
    uint8_t* vPlane = const_cast<uint8_t*>(input->data()[C2PlanarLayout::PLANE_V]);
    int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
    int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
    int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;

    uint32_t width = mSize->width;
    uint32_t height = mSize->height;
@@ -1033,6 +1030,7 @@ c2_status_t C2SoftApvEnc::setEncodeArgs(oapv_frms_t* inputFrames, const C2Graphi
        }
        case C2PlanarLayout::TYPE_YUV: {
            if (IsP010(*input)) {
                ALOGV("Convert from P010 to P210");
                if (mColorFormat == OAPV_CF_YCBCR422) {
                    ColorConvertP010ToYUV422P10le(input, inputFrames->frm[0].imgb);
                } else if (mColorFormat == OAPV_CF_PLANAR2) {
@@ -1040,33 +1038,43 @@ c2_status_t C2SoftApvEnc::setEncodeArgs(oapv_frms_t* inputFrames, const C2Graphi
                    uint16_t *srcUV = (uint16_t*)(input->data()[1]);
                    uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
                    uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
                    size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
                    size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
                    convertP010ToP210(dstY, dstUV, srcY, srcUV,
                                      input->width(), input->width(), input->width(),
                                      input->height());
                                      layout.planes[layout.PLANE_Y].rowInc / 2,
                                      layout.planes[layout.PLANE_U].rowInc / 2,
                                      dstYStride, dstUVStride, input->width(), input->height());
                } else {
                    ALOGE("Not supported color format. %d", mColorFormat);
                    return C2_BAD_VALUE;
                }
            } else if (IsNV12(*input)) {
                ALOGV("Convert from NV12 to P210");
                uint8_t  *srcY  = (uint8_t*)input->data()[0];
                uint8_t  *srcUV = (uint8_t*)input->data()[1];
                uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
                uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
                size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
                size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
                convertSemiPlanar8ToP210(dstY, dstUV, srcY, srcUV,
                                         input->width(), input->width(), input->width(),
                                         input->width(), input->width(), input->height(),
                                         CONV_FORMAT_I420);
                                         layout.planes[layout.PLANE_Y].rowInc,
                                         layout.planes[layout.PLANE_U].rowInc,
                                         dstYStride, dstUVStride,
                                         input->width(), input->height(), CONV_FORMAT_I420);
            } else if (IsI420(*input)) {
                ALOGV("Convert from I420 to P210");
                uint8_t  *srcY  = (uint8_t*)input->data()[0];
                uint8_t  *srcU  = (uint8_t*)input->data()[1];
                uint8_t  *srcV  = (uint8_t*)input->data()[2];
                uint16_t *dstY  = (uint16_t*)inputFrames->frm[0].imgb->a[0];
                uint16_t *dstUV = (uint16_t*)inputFrames->frm[0].imgb->a[1];
                size_t dstYStride = inputFrames->frm[0].imgb->s[0] / 2;
                size_t dstUVStride = inputFrames->frm[0].imgb->s[1] / 2;
                convertPlanar8ToP210(dstY, dstUV, srcY, srcU, srcV,
                                        layout.planes[C2PlanarLayout::PLANE_Y].rowInc,
                                        layout.planes[C2PlanarLayout::PLANE_U].rowInc,
                                        layout.planes[C2PlanarLayout::PLANE_V].rowInc,
                                        input->width(), input->width(),
                                        dstYStride, dstUVStride,
                                        input->width(), input->height(),
                                        CONV_FORMAT_I420);

+10 −7
Original line number Diff line number Diff line
@@ -464,15 +464,18 @@ void convertP010ToYUV420Planar16(uint16_t *dstY, uint16_t *dstU, uint16_t *dstV,
}

void convertP010ToP210(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY, const uint16_t *srcUV,
                       size_t srcUVStride, size_t dstUVStride, size_t width, size_t height) {
    std::memcpy(dstY, srcY, width * height * sizeof(uint16_t));
                       size_t srcYStride, size_t srcUVStride, size_t dstYStride, size_t dstUVStride,
                       size_t width, size_t height) {
    for (size_t y = 0; y < height; ++y) {
        std::memcpy(dstY + (y * dstYStride), srcY + (y * srcYStride), width * sizeof(uint16_t));
    }

    int32_t offsetTop, offsetBot;
    for (size_t y = 0; y < (height + 1) / 2; ++y) {
        offsetTop = (y * 2) * dstUVStride;
        offsetBot = (y * 2 + 1) * dstUVStride;
        std::memcpy(dstUV + offsetTop, srcUV + (y * srcUVStride), srcUVStride * sizeof(uint16_t));
        std::memcpy(dstUV + offsetBot, srcUV + (y * srcUVStride), srcUVStride * sizeof(uint16_t));
        std::memcpy(dstUV, srcUV, width * sizeof(uint16_t));
        std::memcpy(dstUV + dstUVStride, srcUV, width * sizeof(uint16_t));
        srcUV += srcUVStride;
        dstUV += dstUVStride << 1;
    }
}

@@ -703,7 +706,7 @@ void convertSemiPlanar8ToP210(uint16_t *dstY, uint16_t *dstUV,
    srcY += srcYStride;
  }

  for (int32_t y = 0; y < height / 2; ++y) {
  for (int32_t y = 0; y < (height + 1) / 2; ++y) {
    for (int32_t x = 0; x < width; ++x) {
      dstUV[x] = dstUV[dstUVStride + x] =
          ((uint16_t)((double)srcUV[x] * 1023 / 255 + 0.5) << 6) & 0xFFC0;
+2 −2
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ void convertP010ToYUV420Planar16(uint16_t *dstY, uint16_t *dstU, uint16_t *dstV,
                                 size_t dstUStride, size_t dstVStride, size_t width,
                                 size_t height, bool isMonochrome = false);

void convertP010ToP210(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY,
                       const uint16_t *srcUV, size_t srcUVStride, size_t dstUVStride,
void convertP010ToP210(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY, const uint16_t *srcUV,
                       size_t srcYStride, size_t srcUVStride, size_t dstYStride, size_t dstUVStride,
                       size_t width, size_t height);

void convertRGBA1010102ToYUV420Planar16(uint16_t* dstY, uint16_t* dstU, uint16_t* dstV,