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

Commit d8c24890 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "heif: fix rotation info writing" into pi-dev

parents a6709b41 56eab8ec
Loading
Loading
Loading
Loading
+93 −34
Original line number Diff line number Diff line
@@ -1959,6 +1959,17 @@ void MPEG4Writer::Track::addItemOffsetAndSize(off64_t offset, size_t size) {
        return;
    }

    // Rotation angle in HEIF is CCW, framework angle is CW.
    int32_t heifRotation = 0;
    switch(mRotation) {
        case 90: heifRotation = 3; break;
        case 180: heifRotation = 2; break;
        case 270: heifRotation = 1; break;
        default: break; // don't set if invalid
    }

    bool hasGrid = (mNumTiles > 1);

    if (mProperties.empty()) {
        mProperties.push_back(mOwner->addProperty_l({
            .type = FOURCC('h', 'v', 'c', 'C'),
@@ -1967,22 +1978,29 @@ void MPEG4Writer::Track::addItemOffsetAndSize(off64_t offset, size_t size) {

        mProperties.push_back(mOwner->addProperty_l({
            .type = FOURCC('i', 's', 'p', 'e'),
            .width = (mNumTiles > 1) ? mGridWidth : mWidth,
            .height = (mNumTiles > 1) ? mGridHeight : mHeight,
            .width = hasGrid ? mGridWidth : mWidth,
            .height = hasGrid ? mGridHeight : mHeight,
        }));

        if (!hasGrid && heifRotation > 0) {
            mProperties.push_back(mOwner->addProperty_l({
                .type = FOURCC('i', 'r', 'o', 't'),
                .rotation = heifRotation,
            }));
        }
    }

    uint16_t itemId = mOwner->addItem_l({
        .itemType = "hvc1",
        .isPrimary = (mNumTiles > 1) ? false : (mIsPrimary != 0),
        .isHidden = (mNumTiles > 1),
        .isPrimary = hasGrid ? false : (mIsPrimary != 0),
        .isHidden = hasGrid,
        .offset = (uint32_t)offset,
        .size = (uint32_t)size,
        .properties = mProperties,
    });

    mTileIndex++;
    if (mNumTiles > 1) {
    if (hasGrid) {
        mDimgRefs.push_back(itemId);

        if (mTileIndex == mNumTiles) {
@@ -1992,6 +2010,12 @@ void MPEG4Writer::Track::addItemOffsetAndSize(off64_t offset, size_t size) {
                .width = mWidth,
                .height = mHeight,
            }));
            if (heifRotation > 0) {
                mProperties.push_back(mOwner->addProperty_l({
                    .type = FOURCC('i', 'r', 'o', 't'),
                    .rotation = heifRotation,
                }));
            }
            mOwner->addItem_l({
                .itemType = "grid",
                .isPrimary = (mIsPrimary != 0),
@@ -2302,7 +2326,8 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
    mStartTimeRealUs = startTimeUs;

    int32_t rotationDegrees;
    if (mIsVideo && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
    if ((mIsVideo || mIsHeic) && params &&
            params->findInt32(kKeyRotation, &rotationDegrees)) {
        mRotation = rotationDegrees;
    }

@@ -3427,16 +3452,36 @@ int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {

int32_t MPEG4Writer::Track::getMetaSizeIncrease() const {
    CHECK(mIsHeic);
    return    20                           // 1. 'ispe' property
            + (8 + mCodecSpecificDataSize) // 2. 'hvcC' property
            + (20                          // 3. extra 'ispe'
            + (8 + 2 + 2 + mNumTiles * 2)  // 4. 'dimg' ref
            + 12)                          // 5. ImageGrid in 'idat' (worst case)
            * (mNumTiles > 1)              // -  (3~5: applicable only if grid)
            + (16                          // 6. increase to 'iloc'
            + 21                           // 7. increase to 'iinf'
            + (3 + 2 * 2))                 // 8. increase to 'ipma' (worst case)
            * (mNumTiles + 1);             // -  (6~8: are per-item)

    int32_t grid = (mNumTiles > 1);

    // Note that the rotation angle is in the file meta, and we don't have
    // it until start, so here the calculation has to assume rotation.

    // increase to ipco
    int32_t increase = 20 * (grid + 1)              // 'ispe' property
                     + (8 + mCodecSpecificDataSize) // 'hvcC' property
                     + 9;                           // 'irot' property (worst case)

    // increase to iref and idat
    if (grid) {
        increase += (8 + 2 + 2 + mNumTiles * 2)  // 'dimg' in iref
                  + 12;                          // ImageGrid in 'idat' (worst case)
    }

    // increase to iloc, iinf and ipma
    increase += (16             // increase to 'iloc'
              + 21              // increase to 'iinf'
              + (3 + 2 * 2))    // increase to 'ipma' (worst case, 2 props x 2 bytes)
              * (mNumTiles + grid);

    // adjust to ipma:
    // if rotation is present and only one tile, it could ref 3 properties
    if (!grid) {
        increase += 2;
    }

    return increase;
}

status_t MPEG4Writer::Track::checkCodecSpecificData() const {
@@ -4264,7 +4309,9 @@ void MPEG4Writer::writeIpcoBox() {
        numProperties = 32767;
    }
    for (size_t propIndex = 0; propIndex < numProperties; propIndex++) {
        if (mProperties[propIndex].type == FOURCC('h', 'v', 'c', 'C')) {
        switch (mProperties[propIndex].type) {
            case FOURCC('h', 'v', 'c', 'C'):
            {
                beginBox("hvcC");
                sp<ABuffer> hvcc = mProperties[propIndex].hvcc;
                // Patch avcc's lengthSize field to match the number
@@ -4273,13 +4320,25 @@ void MPEG4Writer::writeIpcoBox() {
                ptr[21] = (ptr[21] & 0xfc) | (useNalLengthFour() ? 3 : 1);
                write(hvcc->data(), hvcc->size());
                endBox();
        } else if (mProperties[propIndex].type == FOURCC('i', 's', 'p', 'e')) {
                break;
            }
            case FOURCC('i', 's', 'p', 'e'):
            {
                beginBox("ispe");
                writeInt32(0); // Version = 0, Flags = 0
                writeInt32(mProperties[propIndex].width);
                writeInt32(mProperties[propIndex].height);
                endBox();
        } else {
                break;
            }
            case FOURCC('i', 'r', 'o', 't'):
            {
                beginBox("irot");
                writeInt8(mProperties[propIndex].rotation);
                endBox();
                break;
            }
            default:
                ALOGW("Skipping unrecognized property: type 0x%08x",
                        mProperties[propIndex].type);
        }
+1 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ private:
        uint32_t type;
        int32_t width;
        int32_t height;
        int32_t rotation;
        sp<ABuffer> hvcc;
    } ItemProperty;