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

Commit 67360f44 authored by Chong Zhang's avatar Chong Zhang Committed by JP Sugarbroad
Browse files

heif: use width and height for decoder -- DO NOT MERGE

The display dimensions from MPEG4Extractor is applied on top
of width and height for scaling, it's not for cropping. For
bitmap uses we have to use width and height, the frame from
media server is not scaled.

This required porting over some fixes from master to fix the
display size vs. image size reporting, otherwise images with
grids may show a black border at the bottom or right.

bug: 73172046
Test: test app in bug; open folders with heif files in Photos
and Downloads; CTS MediaMetadataRetrieverTest.
Change-Id: I3d7f1492d08d48876836ccc05b6eb4de0d0c0f9a

(cherry picked from commit 49d4aa0a)
parent 57434d3e
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -321,8 +321,8 @@ bool HeifDecoderImpl::init(HeifStream* stream, HeifFrameInfo* frameInfo) {

    if (frameInfo != nullptr) {
        frameInfo->set(
                videoFrame->mDisplayWidth,
                videoFrame->mDisplayHeight,
                videoFrame->mWidth,
                videoFrame->mHeight,
                videoFrame->mRotationAngle,
                videoFrame->mBytesPerPixel,
                videoFrame->mIccSize,
@@ -393,8 +393,8 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {

    if (frameInfo != nullptr) {
        frameInfo->set(
                videoFrame->mDisplayWidth,
                videoFrame->mDisplayHeight,
                videoFrame->mWidth,
                videoFrame->mHeight,
                videoFrame->mRotationAngle,
                videoFrame->mBytesPerPixel,
                videoFrame->mIccSize,
@@ -413,12 +413,12 @@ bool HeifDecoderImpl::getScanline(uint8_t* dst) {
        return false;
    }
    VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer());
    if (mCurScanline >= videoFrame->mDisplayHeight) {
    if (mCurScanline >= videoFrame->mHeight) {
        ALOGE("no more scanline available");
        return false;
    }
    uint8_t* src = videoFrame->getFlattenedData() + videoFrame->mRowBytes * mCurScanline++;
    memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mDisplayWidth);
    memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mWidth);
    return true;
}

@@ -430,8 +430,8 @@ size_t HeifDecoderImpl::skipScanlines(size_t count) {

    uint32_t oldScanline = mCurScanline;
    mCurScanline += count;
    if (mCurScanline > videoFrame->mDisplayHeight) {
        mCurScanline = videoFrame->mDisplayHeight;
    if (mCurScanline > videoFrame->mHeight) {
        mCurScanline = videoFrame->mHeight;
    }
    return (mCurScanline > oldScanline) ? (mCurScanline - oldScanline) : 0;
}
+2 −7
Original line number Diff line number Diff line
@@ -1441,16 +1441,11 @@ sp<MetaData> ItemTable::getImageMeta() {
        if (tileIndex < 0) {
            return NULL;
        }
        // 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;
        meta->setInt32(kKeyGridRows, image->rows);
        meta->setInt32(kKeyGridCols, 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);
+34 −34
Original line number Diff line number Diff line
@@ -276,30 +276,27 @@ static VideoFrame *extractVideoFrame(
    int32_t gridRows = 1, gridCols = 1;
    if (overrideMeta == NULL) {
        // check if we're dealing with a tiled heif
        int32_t gridWidth, gridHeight;
        int32_t gridWidth, gridHeight, tmpRows, tmpCols;
        if (trackMeta->findInt32(kKeyGridWidth, &gridWidth) && gridWidth > 0
         && trackMeta->findInt32(kKeyGridHeight, &gridHeight) && gridHeight > 0) {
            int32_t width, height, displayWidth, displayHeight;
         && trackMeta->findInt32(kKeyGridHeight, &gridHeight) && gridHeight > 0
         && trackMeta->findInt32(kKeyGridRows, &tmpRows) && tmpRows > 0
         && trackMeta->findInt32(kKeyGridCols, &tmpCols) && tmpCols > 0) {
            int32_t width, height;
            CHECK(trackMeta->findInt32(kKeyWidth, &width));
            CHECK(trackMeta->findInt32(kKeyHeight, &height));
            CHECK(trackMeta->findInt32(kKeyDisplayWidth, &displayWidth));
            CHECK(trackMeta->findInt32(kKeyDisplayHeight, &displayHeight));

            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);
            if (width <= gridWidth * tmpCols && height <= gridHeight * tmpRows) {
                ALOGV("grid: %dx%d, size: %dx%d, picture size: %dx%d",
                        tmpCols, tmpRows, gridWidth, gridHeight, width, height);

                overrideMeta = new MetaData(*trackMeta);
                overrideMeta->remove(kKeyDisplayWidth);
                overrideMeta->remove(kKeyDisplayHeight);
                overrideMeta->setInt32(kKeyWidth, gridWidth);
                overrideMeta->setInt32(kKeyHeight, gridHeight);
                gridCols = width / gridWidth;
                gridRows = height / gridHeight;
                gridCols = tmpCols;
                gridRows = tmpRows;
            } else {
                ALOGE("Bad grid config: %dx%d, display %dx%d, grid %dx%d",
                        width, height, displayWidth, displayHeight, gridWidth, gridHeight);
                ALOGE("bad grid: %dx%d, size: %dx%d, picture size: %dx%d",
                        tmpCols, tmpRows, gridWidth, gridHeight, width, height);
            }
        }
        if (overrideMeta == NULL) {
@@ -541,6 +538,9 @@ static VideoFrame *extractVideoFrame(
                        dstBottom = dstTop + height - 1;
                    }

                    done = (targetTimeUs < 0ll) || (timeUs >= targetTimeUs);

                    if (done) {
                        if (converter.isValid()) {
                            err = converter.convert(
                                    (const uint8_t *)videoFrameBuffer->data(),
@@ -556,13 +556,13 @@ static VideoFrame *extractVideoFrame(

                            err = ERROR_UNSUPPORTED;
                        }

                    done = (targetTimeUs < 0ll) || (timeUs >= targetTimeUs);
                        if (numTiles > 1) {
                            tilesDecoded++;
                            done &= (tilesDecoded >= numTiles);
                        }
                    err = decoder->releaseOutputBuffer(index);
                    }

                    decoder->releaseOutputBuffer(index);
                } else {
                    ALOGW("Received error %d (%s) instead of output", err, asString(err));
                    done = true;
+2 −0
Original line number Diff line number Diff line
@@ -215,6 +215,8 @@ enum {

    kKeyGridWidth        = 'grdW', // int32_t, HEIF grid width
    kKeyGridHeight       = 'grdH', // int32_t, HEIF grid height
    kKeyGridRows         = 'grdR', // int32_t, HEIF grid rows
    kKeyGridCols         = 'grdC', // int32_t, HEIF grid columns
    kKeyIccProfile       = 'prof', // raw data, ICC prifile data
};