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

Commit 4df23d48 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "CCodec: handle stride/vstride for encoder input buffers" am: a667efe6

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1606898

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I97fb6dc499a85cfdb0de4c4570d8cc9d558fbec6
parents e6e1a8be a667efe6
Loading
Loading
Loading
Loading
+60 −6
Original line number Diff line number Diff line
@@ -827,12 +827,14 @@ void CCodec::configure(const sp<AMessage> &msg) {
                return BAD_VALUE;
            }
        }
        int32_t width = 0;
        int32_t height = 0;
        if (config->mDomain & (Config::IS_IMAGE | Config::IS_VIDEO)) {
            if (!msg->findInt32(KEY_WIDTH, &i32)) {
            if (!msg->findInt32(KEY_WIDTH, &width)) {
                ALOGD("width is missing, which is required for image/video components.");
                return BAD_VALUE;
            }
            if (!msg->findInt32(KEY_HEIGHT, &i32)) {
            if (!msg->findInt32(KEY_HEIGHT, &height)) {
                ALOGD("height is missing, which is required for image/video components.");
                return BAD_VALUE;
            }
@@ -1136,6 +1138,7 @@ void CCodec::configure(const sp<AMessage> &msg) {
            return BAD_VALUE;
        }

        int32_t componentColorFormat = 0;
        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
            // propagate HDR static info to output format for both encoders and decoders
            // if component supports this info, we will update from component, but only the raw port,
@@ -1153,8 +1156,8 @@ void CCodec::configure(const sp<AMessage> &msg) {
            }
            if (config->mDomain & Config::IS_ENCODER) {
                config->mInputFormat->setInt32(KEY_COLOR_FORMAT, format);
                if (msg->findInt32("android._color-format", &format)) {
                    config->mInputFormat->setInt32("android._color-format", format);
                if (msg->findInt32("android._color-format", &componentColorFormat)) {
                    config->mInputFormat->setInt32("android._color-format", componentColorFormat);
                }
            } else {
                config->mOutputFormat->setInt32(KEY_COLOR_FORMAT, format);
@@ -1212,8 +1215,59 @@ void CCodec::configure(const sp<AMessage> &msg) {
            config->mInputFormat->setInt32("color-transfer-request", colorTransferRequest);
        }

        ALOGD("setup formats input: %s and output: %s",
                config->mInputFormat->debugString().c_str(),
        if (componentColorFormat != 0 && componentColorFormat != COLOR_FormatSurface) {
            // Need to get stride/vstride
            uint32_t pixelFormat = PIXEL_FORMAT_UNKNOWN;
            if (C2Mapper::mapPixelFormatFrameworkToCodec(componentColorFormat, &pixelFormat)) {
                // TODO: retrieve these values without allocating a buffer.
                //       Currently allocating a buffer is necessary to retrieve the layout.
                int64_t blockUsage =
                    usage.value | C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE;
                std::shared_ptr<C2GraphicBlock> block = FetchGraphicBlock(
                        width, height, pixelFormat, blockUsage, {comp->getName()});
                sp<GraphicBlockBuffer> buffer;
                if (block) {
                    buffer = GraphicBlockBuffer::Allocate(
                            config->mInputFormat,
                            block,
                            [](size_t size) -> sp<ABuffer> { return new ABuffer(size); });
                } else {
                    ALOGD("Failed to allocate a graphic block "
                            "(width=%d height=%d pixelFormat=%u usage=%llx)",
                            width, height, pixelFormat, (long long)blockUsage);
                    // This means that byte buffer mode is not supported in this configuration
                    // anyway. Skip setting stride/vstride to input format.
                }
                if (buffer) {
                    sp<ABuffer> imageData = buffer->getImageData();
                    MediaImage2 *img = nullptr;
                    if (imageData && imageData->data()
                            && imageData->size() >= sizeof(MediaImage2)) {
                        img = (MediaImage2*)imageData->data();
                    }
                    if (img && img->mNumPlanes > 0 && img->mType != img->MEDIA_IMAGE_TYPE_UNKNOWN) {
                        int32_t stride = img->mPlane[0].mRowInc;
                        config->mInputFormat->setInt32(KEY_STRIDE, stride);
                        if (img->mNumPlanes > 1 && stride > 0) {
                            int64_t offsetDelta =
                                (int64_t)img->mPlane[1].mOffset - (int64_t)img->mPlane[0].mOffset;
                            if (offsetDelta % stride == 0) {
                                int32_t vstride = int32_t(offsetDelta / stride);
                                config->mInputFormat->setInt32(KEY_SLICE_HEIGHT, vstride);
                            } else {
                                ALOGD("Cannot report accurate slice height: "
                                        "offsetDelta = %lld stride = %d",
                                        (long long)offsetDelta, stride);
                            }
                        }
                    }
                }
            }
        }

        ALOGD("setup formats input: %s",
                config->mInputFormat->debugString().c_str());
        ALOGD("setup formats output: %s",
                config->mOutputFormat->debugString().c_str());
        return OK;
    };
+17 −2
Original line number Diff line number Diff line
@@ -546,7 +546,19 @@ c2_status_t C2AllocationGralloc::map(
            status_t err = GraphicBufferMapper::get().lockYCbCr(
                    const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
            if (err) {
                ALOGE("failed transaction: lockYCbCr");
                ALOGE("failed transaction: lockYCbCr (err=%d)", err);
                return C2_CORRUPTED;
            }
            if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
                    || ycbcrLayout.ystride == 0
                    || ycbcrLayout.cstride == 0
                    || ycbcrLayout.chroma_step == 0) {
                ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
                        "ystride=%zu cstride=%zu chroma_step=%zu)",
                        ycbcrLayout.y ? "(non-null)" : "(null)",
                        ycbcrLayout.cb ? "(non-null)" : "(null)",
                        ycbcrLayout.cr ? "(non-null)" : "(null)",
                        ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
                return C2_CORRUPTED;
            }

@@ -671,7 +683,10 @@ c2_status_t C2AllocationGralloc::map(

            status_t err = GraphicBufferMapper::get().lockYCbCr(
                    const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
            if (err == OK) {
            if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
                    && ycbcrLayout.ystride > 0
                    && ycbcrLayout.cstride > 0
                    && ycbcrLayout.chroma_step > 0) {
                addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
                addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
                addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;