Merge "CCodec: handle stride/vstride for encoder input buffers"
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 3e83e42..729ba14 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -827,12 +827,14 @@
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 @@
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 @@
}
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 @@
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;
};
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index 8e59df1..bee6b7f 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -546,7 +546,19 @@
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 @@
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;