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

Commit 89db299f authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera: Remove small JPEG sizes for performance class primary cameras

For Performance class 12 primary camers, the minimum supported JPEG
resolutions shoould be 1080p.

Filter out JPEG sizes smaller than 1080p from supported stream configurations.
This makes the change in behavior transparent to the camera HAL.

Test: Camera CTS
Bug: 186046918
Change-Id: Ica9cd5f4cdba2d18c7295f0ccb04e3eafd33f41d
parent bea13757
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -232,6 +232,10 @@ status_t CameraService::enumerateProviders() {
        }
    }

    //Derive primary rear/front cameras, and filter their charactierstics.
    //This needs to be done after all cameras are enumerated and camera ids are sorted.
    filterSPerfClassCharacteristics();

    return OK;
}

@@ -302,6 +306,45 @@ void CameraService::updateCameraNumAndIds() {
    filterAPI1SystemCameraLocked(mNormalDeviceIds);
}

void CameraService::filterSPerfClassCharacteristics() {
    static int32_t kPerformanceClassLevel =
            property_get_int32("ro.odm.build.media_performance_class", 0);
    static bool kIsSPerformanceClass = (kPerformanceClassLevel == 31);

    if (!kIsSPerformanceClass) return;

    // To claim to be S Performance primary cameras, the cameras must be
    // backward compatible. So performance class primary camera Ids must be API1
    // compatible.
    bool firstRearCameraSeen = false, firstFrontCameraSeen = false;
    for (const auto& cameraId : mNormalDeviceIdsWithoutSystemCamera) {
        int facing = -1;
        int orientation = 0;
        String8 cameraId8(cameraId.c_str());
        getDeviceVersion(cameraId8, /*out*/&facing, /*out*/&orientation);
        if (facing == -1) {
            ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
            return;
        }

        if ((facing == hardware::CAMERA_FACING_BACK && !firstRearCameraSeen) ||
                (facing == hardware::CAMERA_FACING_FRONT && !firstFrontCameraSeen)) {
            mCameraProviderManager->filterSmallJpegSizes(cameraId);

            if (facing == hardware::CAMERA_FACING_BACK) {
                firstRearCameraSeen = true;
            }
            if (facing == hardware::CAMERA_FACING_FRONT) {
                firstFrontCameraSeen = true;
            }
        }

        if (firstRearCameraSeen && firstFrontCameraSeen) {
            break;
        }
    }
}

void CameraService::addStates(const String8 id) {
    std::string cameraId(id.c_str());
    hardware::camera::common::V1_0::CameraResourceCost cost;
+5 −0
Original line number Diff line number Diff line
@@ -935,6 +935,11 @@ private:
     */
    void updateCameraNumAndIds();

    /**
     * Filter camera characteristics for S Performance class primary cameras
     */
    void filterSPerfClassCharacteristics();

    // Number of camera devices (excluding hidden secure cameras)
    int                 mNumberOfCameras;
    // Number of camera devices (excluding hidden secure cameras and
+75 −0
Original line number Diff line number Diff line
@@ -1186,6 +1186,17 @@ bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId)
    return isHiddenPhysicalCameraInternal(cameraId).first;
}

void CameraProviderManager::filterSmallJpegSizes(const std::string& cameraId) {
    for (auto& provider : mProviders) {
        for (auto& deviceInfo : provider->mDevices) {
            if (deviceInfo->mId == cameraId) {
                deviceInfo->filterSmallJpegSizes();
                return;
            }
        }
    }
}

std::pair<bool, CameraProviderManager::ProviderInfo::DeviceInfo *>
CameraProviderManager::isHiddenPhysicalCameraInternal(const std::string& cameraId) const {
    auto falseRet = std::make_pair(false, nullptr);
@@ -2562,6 +2573,70 @@ status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfiguratio
    return res;
}

void CameraProviderManager::ProviderInfo::DeviceInfo3::filterSmallJpegSizes() {
    static constexpr int FHD_W = 1920;
    static constexpr int FHD_H = 1080;

    // Remove small JPEG sizes from available stream configurations
    std::vector<int32_t> newStreamConfigs;
    camera_metadata_entry streamConfigs =
            mCameraCharacteristics.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
    for (size_t i = 0; i < streamConfigs.count; i += 4) {
        if ((streamConfigs.data.i32[i] == HAL_PIXEL_FORMAT_BLOB) && (streamConfigs.data.i32[i+3] ==
                ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) &&
                (streamConfigs.data.i32[i+1] < FHD_W || streamConfigs.data.i32[i+2] < FHD_H)) {
            continue;
        }
        newStreamConfigs.insert(newStreamConfigs.end(), streamConfigs.data.i32 + i,
                streamConfigs.data.i32 + i + 4);
    }
    if (newStreamConfigs.size() > 0) {
        mCameraCharacteristics.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                newStreamConfigs.data(), newStreamConfigs.size());
    }

    // Remove small JPEG sizes from available min frame durations
    std::vector<int64_t> newMinDurations;
    camera_metadata_entry minDurations =
            mCameraCharacteristics.find(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
    for (size_t i = 0; i < minDurations.count; i += 4) {
        if ((minDurations.data.i64[i] == HAL_PIXEL_FORMAT_BLOB) &&
                (minDurations.data.i64[i+1] < FHD_W || minDurations.data.i64[i+2] < FHD_H)) {
            continue;
        }
        newMinDurations.insert(newMinDurations.end(), minDurations.data.i64 + i,
                minDurations.data.i64 + i + 4);
    }
    if (newMinDurations.size() > 0) {
        mCameraCharacteristics.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
                newMinDurations.data(), newMinDurations.size());
    }

    // Remove small JPEG sizes from available stall durations
    std::vector<int64_t> newStallDurations;
    camera_metadata_entry stallDurations =
            mCameraCharacteristics.find(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
    for (size_t i = 0; i < stallDurations.count; i += 4) {
        if ((stallDurations.data.i64[i] == HAL_PIXEL_FORMAT_BLOB) &&
                (stallDurations.data.i64[i+1] < FHD_W || stallDurations.data.i64[i+2] < FHD_H)) {
            continue;
        }
        newStallDurations.insert(newStallDurations.end(), stallDurations.data.i64 + i,
                stallDurations.data.i64 + i + 4);
    }
    if (newStallDurations.size() > 0) {
        mCameraCharacteristics.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
                newStallDurations.data(), newStallDurations.size());
    }

    // Re-generate metadata tags that have dependencies on BLOB sizes
    auto res = addDynamicDepthTags();
    if (OK != res) {
        ALOGE("%s: Failed to append dynamic depth tags: %s (%d)", __FUNCTION__,
                strerror(-res), res);
    }
}

status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
        std::string *type, uint32_t *id) {
    // Format must be "<type>/<id>"
+4 −0
Original line number Diff line number Diff line
@@ -327,6 +327,8 @@ public:
    status_t getSystemCameraKind(const std::string& id, SystemCameraKind *kind) const;
    bool isHiddenPhysicalCamera(const std::string& cameraId) const;

    void filterSmallJpegSizes(const std::string& cameraId);

    static const float kDepthARTolerance;
private:
    // All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
@@ -486,6 +488,7 @@ private:
                    bool * /*status*/) {
                return INVALID_OPERATION;
            }
            virtual void filterSmallJpegSizes() = 0;

            template<class InterfaceT>
            sp<InterfaceT> startDeviceInterface();
@@ -544,6 +547,7 @@ private:
                    const hardware::camera::device::V3_7::StreamConfiguration &configuration,
                    bool *status /*out*/)
                    override;
            virtual void filterSmallJpegSizes() override;

            DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
                    const std::string &id, uint16_t minorVersion,