heif: fix decoding of image size different from full tiled area
Bug: 64077740
Change-Id: I57ee7e1bc05e320be723d224b9328526543cad25
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 8b846be..080313c 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -216,8 +216,8 @@
if (frameInfo != nullptr) {
frameInfo->set(
- videoFrame->mWidth,
- videoFrame->mHeight,
+ videoFrame->mDisplayWidth,
+ videoFrame->mDisplayHeight,
videoFrame->mRotationAngle,
videoFrame->mBytesPerPixel,
videoFrame->mIccSize,
@@ -275,8 +275,8 @@
if (frameInfo != nullptr) {
frameInfo->set(
- videoFrame->mWidth,
- videoFrame->mHeight,
+ videoFrame->mDisplayWidth,
+ videoFrame->mDisplayHeight,
videoFrame->mRotationAngle,
videoFrame->mBytesPerPixel,
videoFrame->mIccSize,
@@ -290,11 +290,12 @@
return false;
}
VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer());
- if (mCurScanline >= videoFrame->mHeight) {
+ if (mCurScanline >= videoFrame->mDisplayHeight) {
+ ALOGE("no more scanline available");
return false;
}
uint8_t* src = videoFrame->getFlattenedData() + videoFrame->mRowBytes * mCurScanline++;
- memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mWidth);
+ memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mDisplayWidth);
return true;
}
@@ -306,8 +307,8 @@
uint32_t oldScanline = mCurScanline;
mCurScanline += count;
- if (mCurScanline >= videoFrame->mHeight) {
- mCurScanline = videoFrame->mHeight;
+ if (mCurScanline > videoFrame->mDisplayHeight) {
+ mCurScanline = videoFrame->mDisplayHeight;
}
return (mCurScanline > oldScanline) ? (mCurScanline - oldScanline) : 0;
}
diff --git a/media/libstagefright/ItemTable.cpp b/media/libstagefright/ItemTable.cpp
index b7ff21b..3ec416b 100644
--- a/media/libstagefright/ItemTable.cpp
+++ b/media/libstagefright/ItemTable.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#define LOG_TAG "ItemTable"
//#define LOG_NDEBUG 0
+#define LOG_TAG "ItemTable"
#include <include/ItemTable.h>
#include <media/MediaDefs.h>
@@ -1434,10 +1434,19 @@
if (tileIndex < 0) {
return NULL;
}
- meta->setInt32(kKeyGridRows, image->rows);
- meta->setInt32(kKeyGridCols, image->columns);
+ // when there are tiles, (kKeyWidth, kKeyHeight) is the full tiled area,
+ // and (kKeyDisplayWidth, kKeyDisplayHeight) may be smaller than that.
+ meta->setInt32(kKeyDisplayWidth, image->width);
+ meta->setInt32(kKeyDisplayHeight, image->height);
+ int32_t gridRows = image->rows, gridCols = image->columns;
+ // point image to the first tile for grid size and HVCC
image = &mItemIdToImageMap.editValueAt(tileIndex);
+ meta->setInt32(kKeyWidth, image->width * gridCols);
+ meta->setInt32(kKeyHeight, image->height * gridRows);
+ meta->setInt32(kKeyGridWidth, image->width);
+ meta->setInt32(kKeyGridHeight, image->height);
+ meta->setInt32(kKeyMaxInputSize, image->width * image->height * 1.5);
}
if (image->hvcc == NULL) {
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index f36ff97..a53897f 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -250,6 +250,8 @@
&& trackMeta->findInt32(kKeyThumbnailHeight, &thumbnailHeight)
&& trackMeta->findData(kKeyThumbnailHVCC, &type, &data, &size)){
overrideMeta = new MetaData(*trackMeta);
+ overrideMeta->remove(kKeyDisplayWidth);
+ overrideMeta->remove(kKeyDisplayHeight);
overrideMeta->setInt32(kKeyWidth, thumbnailWidth);
overrideMeta->setInt32(kKeyHeight, thumbnailHeight);
overrideMeta->setData(kKeyHVCC, type, data, size);
@@ -266,32 +268,39 @@
}
int32_t gridRows = 1, gridCols = 1;
- int32_t numTiles = 1, tilesDecoded = 0;
if (overrideMeta == NULL) {
// check if we're dealing with a tiled heif
- if (trackMeta->findInt32(kKeyGridRows, &gridRows) && gridRows > 0
- && trackMeta->findInt32(kKeyGridCols, &gridCols) && gridCols > 0) {
- int32_t width, height;
+ int32_t gridWidth, gridHeight;
+ if (trackMeta->findInt32(kKeyGridWidth, &gridWidth) && gridWidth > 0
+ && trackMeta->findInt32(kKeyGridHeight, &gridHeight) && gridHeight > 0) {
+ int32_t width, height, displayWidth, displayHeight;
CHECK(trackMeta->findInt32(kKeyWidth, &width));
CHECK(trackMeta->findInt32(kKeyHeight, &height));
+ CHECK(trackMeta->findInt32(kKeyDisplayWidth, &displayWidth));
+ CHECK(trackMeta->findInt32(kKeyDisplayHeight, &displayHeight));
- if ((width % gridCols == 0) && (height % gridRows == 0)) {
- width /= gridCols;
- height /= gridRows;
- numTiles = gridCols * gridRows;
-
- ALOGV("tile: %dx%d, numTiles %d", width, height, numTiles);
+ if (width >= displayWidth && height >= displayHeight
+ && (width % gridWidth == 0) && (height % gridHeight == 0)) {
+ ALOGV("grid config: %dx%d, display %dx%d, grid %dx%d",
+ width, height, displayWidth, displayHeight, gridWidth, gridHeight);
overrideMeta = new MetaData(*trackMeta);
- overrideMeta->setInt32(kKeyWidth, width);
- overrideMeta->setInt32(kKeyHeight, height);
+ overrideMeta->remove(kKeyDisplayWidth);
+ overrideMeta->remove(kKeyDisplayHeight);
+ overrideMeta->setInt32(kKeyWidth, gridWidth);
+ overrideMeta->setInt32(kKeyHeight, gridHeight);
+ gridCols = width / gridWidth;
+ gridRows = height / gridHeight;
+ } else {
+ ALOGE("Bad grid config: %dx%d, display %dx%d, grid %dx%d",
+ width, height, displayWidth, displayHeight, gridWidth, gridHeight);
}
}
if (overrideMeta == NULL) {
- gridRows = gridCols = numTiles = 1;
overrideMeta = trackMeta;
}
}
+ int32_t numTiles = gridRows * gridCols;
sp<AMessage> videoFormat;
if (convertMetaDataToMessage(overrideMeta, &videoFormat) != OK) {
@@ -383,6 +392,7 @@
int64_t targetTimeUs = -1ll;
VideoFrame *frame = NULL;
+ int32_t tilesDecoded = 0;
do {
size_t inputIndex = -1;
@@ -500,7 +510,7 @@
if (frame == NULL) {
frame = allocVideoFrame(
- overrideMeta,
+ trackMeta,
(crop_right - crop_left + 1) * gridCols,
(crop_bottom - crop_top + 1) * gridRows,
dstBpp,
diff --git a/media/libstagefright/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
index 65ad3e4..6cfde9c 100644
--- a/media/libstagefright/include/media/stagefright/MetaData.h
+++ b/media/libstagefright/include/media/stagefright/MetaData.h
@@ -213,9 +213,9 @@
kKeyTemporalLayerId = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer)
kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded
- kKeyGridRows = 'rows', // int32_t, HEIF grid rows
- kKeyGridCols = 'clms', // int32_t, HEIF grid columns
- kKeyIccProfile = 'prof', // raw data
+ kKeyGridWidth = 'grdW', // int32_t, HEIF grid width
+ kKeyGridHeight = 'grdH', // int32_t, HEIF grid height
+ kKeyIccProfile = 'prof', // raw data, ICC prifile data
};
enum {