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

Commit c926d1b3 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Extend the HEIF UltraHDR format muxing

- Insert 'tmap' within ftyp in case a gainmap
  is present
- Avoid adding prefixes when writing the gainmap
  metadata
- Switch to using the HEIF UltraHDR dataspace AIDL definition

Flag: com.android.internal.camera.flags.camera_heif_gainmap
Bug: 362608343
Test: atest -c -d cts/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java#testHeicUltraHdr

Change-Id: I99ae2cf553923e4a1b9994a6c2148959786db359
parent f19a87d4
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -580,6 +580,7 @@ void MPEG4Writer::initInternal(int fd, bool isFirstSession) {
    mTimeScale = -1;
    mHasFileLevelMeta = false;
    mIsAvif = false;
    mHasGainmap = false;
    mFileLevelMetaDataSize = 0;
    mPrimaryItemId = 0;
    mAssociationEntryCount = 0;
@@ -737,6 +738,13 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
        mIsBackgroundMode |= isBackgroundMode;
    }

    if (flags_camera::camera_heif_gainmap()) {
        int32_t gainmap = 0;
        if (meta && meta->findInt32(kKeyGainmap, &gainmap)) {
            mHasGainmap |= gainmap;
        }
    }

    if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        // For MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
        // getFourCCForMime() requires profile information
@@ -1600,6 +1608,9 @@ void MPEG4Writer::writeFtypBox(MetaData *param) {
            } else {
                writeFourcc("mif1");
                writeFourcc("heic");
                if (flags_camera::camera_heif_gainmap() && mHasGainmap) {
                    writeFourcc("tmap");
                }
            }
        }
        if (mHasMoovBox) {
@@ -3919,7 +3930,7 @@ status_t MPEG4Writer::Track::threadEntry() {
        if (isExif) {
            copy->meta_data().setInt32(kKeyExifTiffOffset, tiffHdrOffset);
        }
        bool usePrefix = this->usePrefix() && !isExif;
        bool usePrefix = this->usePrefix() && !isExif && !isGainmapMeta;
        if (sampleFileOffset == -1 && usePrefix) {
            StripStartcode(copy);
        }
+5 −0
Original line number Diff line number Diff line
@@ -2052,6 +2052,11 @@ status_t convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
        meta->setInt32(kKeyMaxHeight, maxHeight);
    }

    int32_t gainmap;
    if (msg->findInt32("gainmap", &gainmap)) {
        meta->setInt32(kKeyGainmap, gainmap);
    }

    int32_t fps;
    float fpsFloat;
    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
+1 −0
Original line number Diff line number Diff line
@@ -240,6 +240,7 @@ private:

    bool mHasFileLevelMeta;
    bool mIsAvif; // used to differentiate HEIC and AVIF under the same OUTPUT_FORMAT_HEIF
    bool mHasGainmap;
    uint64_t mFileLevelMetaDataSize;
    bool mHasMoovBox;
    uint32_t mPrimaryItemId;
+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ enum {
    kKeyPixelFormat       = 'pixf',  // int32_t
    kKeyColorFormat       = 'colf',  // int32_t
    kKeyColorSpace        = 'cols',  // int32_t
    kKeyGainmap           = 'gmap',  // int32_t
    kKeyPlatformPrivate   = 'priv',  // pointer
    kKeyDecoderComponent  = 'decC',  // cstring
    kKeyBufferID          = 'bfID',
+8 −2
Original line number Diff line number Diff line
@@ -1054,6 +1054,7 @@ bool HeicCompositeStream::getNextReadyInputLocked(int64_t *frameNumber /*out*/)
            }
            if (it.second.gainmapFormat == nullptr && mGainmapFormat != nullptr){
                it.second.gainmapFormat = mGainmapFormat->dup();
                it.second.gainmapFormat->setInt32("gainmap", 1);
            }
            newInputAvailable = true;
            break;
@@ -1410,10 +1411,12 @@ status_t HeicCompositeStream::generateBaseImageAndGainmap(InputFrame &inputFrame
        ALOGE("%s: Failed HDR gainmap: %d", __FUNCTION__, res.error_code);
        return BAD_VALUE;
    }
    // Ensure the gaimap U/V planes are all 0
    // We can only generate a single channel gainmap at the moment. However only
    // multi channel HEVC encoding (like YUV420) is required. Set the extra U/V
    // planes to 128 to avoid encoding any actual color data.
    inputFrame.gainmapChroma = std::make_unique<uint8_t[]>(
            inputFrame.gainmap->w * inputFrame.gainmap->h / 2);
    memset(inputFrame.gainmapChroma.get(), 0, inputFrame.gainmap->w * inputFrame.gainmap->h / 2);
    memset(inputFrame.gainmapChroma.get(), 128, inputFrame.gainmap->w * inputFrame.gainmap->h / 2);

    ultrahdr::uhdr_gainmap_metadata_frac iso_secondary_metadata;
    res = ultrahdr::uhdr_gainmap_metadata_frac::gainmapMetadataFloatToFraction(
@@ -1435,6 +1438,9 @@ status_t HeicCompositeStream::generateBaseImageAndGainmap(InputFrame &inputFrame
                res.error_code);
        return BAD_VALUE;
    }
    // 6.6.2.4.2 of ISO/IEC 23008-12:2024 expects the ISO 21496-1 gainmap to be
    // preceded by an u8 version equal to 0
    inputFrame.isoGainmapMetadata.insert(inputFrame.isoGainmapMetadata.begin(), 0);

    inputFrame.gainmapImage = std::make_unique<CpuConsumer::LockedBuffer>();
    *inputFrame.gainmapImage = inputFrame.yuvBuffer;
Loading