codec2: fix graphic buffer copy
Bug: 134498476
Test: atest CtsMediaTestCases:ImageReaderDecoderTest
Change-Id: I4de9f5f0410c308bd87b59124d536a671a5d2b61
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index c20ca73..702ad6f 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -201,9 +201,10 @@
* \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
* an attempt is made to simply represent the graphic view as a flexible SDK format
* without a memcpy)
+ * \param copy whether the converter is used for copy or not
*/
GraphicView2MediaImageConverter(
- const C2GraphicView &view, int32_t colorFormat)
+ const C2GraphicView &view, int32_t colorFormat, bool copy)
: mInitCheck(NO_INIT),
mView(view),
mWidth(view.width()),
@@ -255,41 +256,44 @@
}
switch (mColorFormat) {
case COLOR_FormatYUV420Flexible:
- { // try to map directly. check if the planes are near one another
- const uint8_t *minPtr = mView.data()[0];
- const uint8_t *maxPtr = mView.data()[0];
- int32_t planeSize = 0;
- for (uint32_t i = 0; i < layout.numPlanes; ++i) {
- const C2PlaneInfo &plane = layout.planes[i];
- ssize_t minOffset = plane.minOffset(mWidth, mHeight);
- ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
- if (minPtr > mView.data()[i] + minOffset) {
- minPtr = mView.data()[i] + minOffset;
- }
- if (maxPtr < mView.data()[i] + maxOffset) {
- maxPtr = mView.data()[i] + maxOffset;
- }
- planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
- / plane.rowSampling / plane.colSampling * divUp(mAllocatedDepth, 8u);
- }
-
- if ((maxPtr - minPtr + 1) <= planeSize) {
- // FIXME: this is risky as reading/writing data out of bound results in
- // an undefined behavior, but gralloc does assume a contiguous
- // mapping
+ if (!copy) {
+ // try to map directly. check if the planes are near one another
+ const uint8_t *minPtr = mView.data()[0];
+ const uint8_t *maxPtr = mView.data()[0];
+ int32_t planeSize = 0;
for (uint32_t i = 0; i < layout.numPlanes; ++i) {
const C2PlaneInfo &plane = layout.planes[i];
- mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
- mediaImage->mPlane[i].mColInc = plane.colInc;
- mediaImage->mPlane[i].mRowInc = plane.rowInc;
- mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
- mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+ ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+ ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+ if (minPtr > mView.data()[i] + minOffset) {
+ minPtr = mView.data()[i] + minOffset;
+ }
+ if (maxPtr < mView.data()[i] + maxOffset) {
+ maxPtr = mView.data()[i] + maxOffset;
+ }
+ planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
+ / plane.rowSampling / plane.colSampling
+ * divUp(mAllocatedDepth, 8u);
}
- mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
- break;
+
+ if ((maxPtr - minPtr + 1) <= planeSize) {
+ // FIXME: this is risky as reading/writing data out of bound results
+ // in an undefined behavior, but gralloc does assume a
+ // contiguous mapping
+ for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+ const C2PlaneInfo &plane = layout.planes[i];
+ mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+ mediaImage->mPlane[i].mColInc = plane.colInc;
+ mediaImage->mPlane[i].mRowInc = plane.rowInc;
+ mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+ mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+ }
+ mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr),
+ maxPtr - minPtr + 1);
+ break;
+ }
}
- }
- [[fallthrough]];
+ [[fallthrough]];
case COLOR_FormatYUV420Planar:
case COLOR_FormatYUV420PackedPlanar:
@@ -503,7 +507,7 @@
int32_t colorFormat = COLOR_FormatYUV420Flexible;
(void)format->findInt32("color-format", &colorFormat);
- GraphicView2MediaImageConverter converter(view, colorFormat);
+ GraphicView2MediaImageConverter converter(view, colorFormat, false /* copy */);
if (converter.initCheck() != OK) {
ALOGD("Converter init failed: %d", converter.initCheck());
return nullptr;
@@ -615,7 +619,7 @@
int32_t colorFormat = COLOR_FormatYUV420Flexible;
(void)format->findInt32("color-format", &colorFormat);
- GraphicView2MediaImageConverter converter(*view, colorFormat);
+ GraphicView2MediaImageConverter converter(*view, colorFormat, false /* copy */);
if (converter.initCheck() != OK) {
ALOGD("Converter init failed: %d", converter.initCheck());
return nullptr;
@@ -708,7 +712,7 @@
const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+ buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
return false;
@@ -730,7 +734,7 @@
format()->findInt32("color-format", &colorFormat);
GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+ buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
return false;
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index 1e884ef..bf2a07e 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -137,14 +137,14 @@
int32_t dst_stride_v = img->mPlane[2].mRowInc;
if (IsNV12(view) && IsI420(img)) {
if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
- dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
- view.height())) {
+ dst_u, dst_stride_u, dst_v, dst_stride_v, view.crop().width,
+ view.crop().height)) {
return OK;
}
} else {
if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
- dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
- view.height())) {
+ dst_y, dst_stride_y, dst_u, dst_stride_u, view.crop().width,
+ view.crop().height)) {
return OK;
}
}