Loading services/camera/libcameraservice/api2/HeicCompositeStream.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -330,9 +330,9 @@ status_t HeicCompositeStream::getCompositeStreamInfo(const OutputStreamInfo &str } bool HeicCompositeStream::isSizeSupportedByHeifEncoder(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall) { bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName) { static HeicEncoderInfoManager& heicManager = HeicEncoderInfoManager::getInstance(); return heicManager.isSizeSupported(width, height, useHeic, useGrid, stall); return heicManager.isSizeSupported(width, height, useHeic, useGrid, stall, hevcName); } bool HeicCompositeStream::isInMemoryTempFileSupported() { Loading Loading @@ -1115,8 +1115,9 @@ status_t HeicCompositeStream::initializeCodec(uint32_t width, uint32_t height, ALOGV("%s", __FUNCTION__); bool useGrid = false; AString hevcName; bool isSizeSupported = isSizeSupportedByHeifEncoder(width, height, &mUseHeic, &useGrid, nullptr); &mUseHeic, &useGrid, nullptr, &hevcName); if (!isSizeSupported) { ALOGE("%s: Encoder doesnt' support size %u x %u!", __FUNCTION__, width, height); Loading @@ -1138,7 +1139,11 @@ status_t HeicCompositeStream::initializeCodec(uint32_t width, uint32_t height, } // Create HEIC/HEVC codec. if (mUseHeic) { mCodec = MediaCodec::CreateByType(mCodecLooper, desiredMime, true /*encoder*/); } else { mCodec = MediaCodec::CreateByComponentName(mCodecLooper, hevcName); } if (mCodec == nullptr) { ALOGE("%s: Failed to create codec for %s", __FUNCTION__, desiredMime); return NO_INIT; Loading services/camera/libcameraservice/api2/HeicCompositeStream.h +1 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public: const CameraMetadata& ch, std::vector<OutputStreamInfo>* compositeOutput /*out*/); static bool isSizeSupportedByHeifEncoder(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall); bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName = nullptr); static bool isInMemoryTempFileSupported(); protected: Loading services/camera/libcameraservice/api2/HeicEncoderInfoManager.cpp +81 −32 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ HeicEncoderInfoManager::~HeicEncoderInfoManager() { } bool HeicEncoderInfoManager::isSizeSupported(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall) const { bool* useGrid, int64_t* stall, AString* hevcName) const { if (useHeic == nullptr || useGrid == nullptr) { ALOGE("%s: invalid parameters: useHeic %p, useGrid %p", __FUNCTION__, useHeic, useGrid); Loading @@ -72,6 +72,9 @@ bool HeicEncoderInfoManager::isSizeSupported(int32_t width, int32_t height, bool (width <= 1920 && height <= 1080))) { enableGrid = false; } if (hevcName != nullptr) { *hevcName = mHevcName; } } else { // No encoder available for the requested size. return false; Loading Loading @@ -113,9 +116,8 @@ status_t HeicEncoderInfoManager::initialize() { } sp<AMessage> heicDetails = getCodecDetails(codecsList, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC); sp<AMessage> hevcDetails = getCodecDetails(codecsList, MEDIA_MIMETYPE_VIDEO_HEVC); if (hevcDetails == nullptr) { if (!getHevcCodecDetails(codecsList, MEDIA_MIMETYPE_VIDEO_HEVC)) { if (heicDetails != nullptr) { ALOGE("%s: Device must support HEVC codec if HEIC codec is available!", __FUNCTION__); Loading @@ -123,22 +125,7 @@ status_t HeicEncoderInfoManager::initialize() { } return OK; } // Check CQ mode for HEVC codec { AString bitrateModes; auto hasItem = hevcDetails->findString("feature-bitrate-modes", &bitrateModes); if (!hasItem) { ALOGE("%s: Failed to query bitrate modes for HEVC codec", __FUNCTION__); return BAD_VALUE; } ALOGV("%s: HEVC codec's feature-bitrate-modes value is %d, %s", __FUNCTION__, hasItem, bitrateModes.c_str()); std::regex pattern("(^|,)CQ($|,)", std::regex_constants::icase); if (!std::regex_search(bitrateModes.c_str(), pattern)) { return OK; } } mHasHEVC = true; // HEIC size range if (heicDetails != nullptr) { Loading @@ -152,19 +139,6 @@ status_t HeicEncoderInfoManager::initialize() { mHasHEIC = true; } // HEVC size range { auto res = getCodecSizeRange(MEDIA_MIMETYPE_VIDEO_HEVC, hevcDetails, &mMinSizeHevc, &mMaxSizeHevc, &mHevcFrameRateMaps); if (res != OK) { ALOGE("%s: Failed to get HEVC codec size range: %s (%d)", __FUNCTION__, strerror(-res), res); return BAD_VALUE; } mHasHEVC = true; } return OK; } Loading Loading @@ -290,5 +264,80 @@ sp<AMessage> HeicEncoderInfoManager::getCodecDetails( return details; } bool HeicEncoderInfoManager::getHevcCodecDetails( sp<IMediaCodecList> codecsList, const char* mime) { bool found = false; ssize_t idx = 0; while ((idx = codecsList->findCodecByType(mime, true /*encoder*/, idx)) >= 0) { const sp<MediaCodecInfo> info = codecsList->getCodecInfo(idx++); if (info == nullptr) { ALOGE("%s: Failed to get codec info for %s", __FUNCTION__, mime); break; } // Filter out software ones as they may be too slow if (!(info->getAttributes() & MediaCodecInfo::kFlagIsHardwareAccelerated)) { continue; } const sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(mime); if (caps == nullptr) { ALOGE("%s: [%s] Failed to get capabilities", __FUNCTION__, info->getCodecName()); break; } const sp<AMessage> details = caps->getDetails(); if (details == nullptr) { ALOGE("%s: [%s] Failed to get details", __FUNCTION__, info->getCodecName()); break; } // Check CQ mode AString bitrateModes; auto hasItem = details->findString("feature-bitrate-modes", &bitrateModes); if (!hasItem) { ALOGE("%s: [%s] Failed to query bitrate modes", __FUNCTION__, info->getCodecName()); break; } ALOGV("%s: [%s] feature-bitrate-modes value is %d, %s", __FUNCTION__, info->getCodecName(), hasItem, bitrateModes.c_str()); std::regex pattern("(^|,)CQ($|,)", std::regex_constants::icase); if (!std::regex_search(bitrateModes.c_str(), pattern)) { continue; // move on to next encoder } std::pair<int32_t, int32_t> minSizeHevc, maxSizeHevc; FrameRateMaps hevcFrameRateMaps; auto res = getCodecSizeRange(MEDIA_MIMETYPE_VIDEO_HEVC, details, &minSizeHevc, &maxSizeHevc, &hevcFrameRateMaps); if (res != OK) { ALOGE("%s: [%s] Failed to get size range: %s (%d)", __FUNCTION__, info->getCodecName(), strerror(-res), res); break; } if (kGridWidth < minSizeHevc.first || kGridWidth > maxSizeHevc.first || kGridHeight < minSizeHevc.second || kGridHeight > maxSizeHevc.second) { continue; // move on to next encoder } // Found: save name, size, frame rate mHevcName = info->getCodecName(); mMinSizeHevc = minSizeHevc; mMaxSizeHevc = maxSizeHevc; mHevcFrameRateMaps = hevcFrameRateMaps; found = true; break; } return found; } } //namespace camera3 } // namespace android services/camera/libcameraservice/api2/HeicEncoderInfoManager.h +3 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public: } bool isSizeSupported(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall) const; bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName) const; static const auto kGridWidth = 512; static const auto kGridHeight = 512; Loading @@ -61,11 +61,13 @@ private: FrameRateMaps::const_iterator findClosestSize(const FrameRateMaps& maps, int32_t width, int32_t height) const; sp<AMessage> getCodecDetails(sp<IMediaCodecList> codecsList, const char* name); bool getHevcCodecDetails(sp<IMediaCodecList> codecsList, const char* mime); bool mIsInited; std::pair<int32_t, int32_t> mMinSizeHeic, mMaxSizeHeic; std::pair<int32_t, int32_t> mMinSizeHevc, mMaxSizeHevc; bool mHasHEVC, mHasHEIC; AString mHevcName; FrameRateMaps mHeicFrameRateMaps, mHevcFrameRateMaps; bool mDisableGrid; Loading Loading
services/camera/libcameraservice/api2/HeicCompositeStream.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -330,9 +330,9 @@ status_t HeicCompositeStream::getCompositeStreamInfo(const OutputStreamInfo &str } bool HeicCompositeStream::isSizeSupportedByHeifEncoder(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall) { bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName) { static HeicEncoderInfoManager& heicManager = HeicEncoderInfoManager::getInstance(); return heicManager.isSizeSupported(width, height, useHeic, useGrid, stall); return heicManager.isSizeSupported(width, height, useHeic, useGrid, stall, hevcName); } bool HeicCompositeStream::isInMemoryTempFileSupported() { Loading Loading @@ -1115,8 +1115,9 @@ status_t HeicCompositeStream::initializeCodec(uint32_t width, uint32_t height, ALOGV("%s", __FUNCTION__); bool useGrid = false; AString hevcName; bool isSizeSupported = isSizeSupportedByHeifEncoder(width, height, &mUseHeic, &useGrid, nullptr); &mUseHeic, &useGrid, nullptr, &hevcName); if (!isSizeSupported) { ALOGE("%s: Encoder doesnt' support size %u x %u!", __FUNCTION__, width, height); Loading @@ -1138,7 +1139,11 @@ status_t HeicCompositeStream::initializeCodec(uint32_t width, uint32_t height, } // Create HEIC/HEVC codec. if (mUseHeic) { mCodec = MediaCodec::CreateByType(mCodecLooper, desiredMime, true /*encoder*/); } else { mCodec = MediaCodec::CreateByComponentName(mCodecLooper, hevcName); } if (mCodec == nullptr) { ALOGE("%s: Failed to create codec for %s", __FUNCTION__, desiredMime); return NO_INIT; Loading
services/camera/libcameraservice/api2/HeicCompositeStream.h +1 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public: const CameraMetadata& ch, std::vector<OutputStreamInfo>* compositeOutput /*out*/); static bool isSizeSupportedByHeifEncoder(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall); bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName = nullptr); static bool isInMemoryTempFileSupported(); protected: Loading
services/camera/libcameraservice/api2/HeicEncoderInfoManager.cpp +81 −32 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ HeicEncoderInfoManager::~HeicEncoderInfoManager() { } bool HeicEncoderInfoManager::isSizeSupported(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall) const { bool* useGrid, int64_t* stall, AString* hevcName) const { if (useHeic == nullptr || useGrid == nullptr) { ALOGE("%s: invalid parameters: useHeic %p, useGrid %p", __FUNCTION__, useHeic, useGrid); Loading @@ -72,6 +72,9 @@ bool HeicEncoderInfoManager::isSizeSupported(int32_t width, int32_t height, bool (width <= 1920 && height <= 1080))) { enableGrid = false; } if (hevcName != nullptr) { *hevcName = mHevcName; } } else { // No encoder available for the requested size. return false; Loading Loading @@ -113,9 +116,8 @@ status_t HeicEncoderInfoManager::initialize() { } sp<AMessage> heicDetails = getCodecDetails(codecsList, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC); sp<AMessage> hevcDetails = getCodecDetails(codecsList, MEDIA_MIMETYPE_VIDEO_HEVC); if (hevcDetails == nullptr) { if (!getHevcCodecDetails(codecsList, MEDIA_MIMETYPE_VIDEO_HEVC)) { if (heicDetails != nullptr) { ALOGE("%s: Device must support HEVC codec if HEIC codec is available!", __FUNCTION__); Loading @@ -123,22 +125,7 @@ status_t HeicEncoderInfoManager::initialize() { } return OK; } // Check CQ mode for HEVC codec { AString bitrateModes; auto hasItem = hevcDetails->findString("feature-bitrate-modes", &bitrateModes); if (!hasItem) { ALOGE("%s: Failed to query bitrate modes for HEVC codec", __FUNCTION__); return BAD_VALUE; } ALOGV("%s: HEVC codec's feature-bitrate-modes value is %d, %s", __FUNCTION__, hasItem, bitrateModes.c_str()); std::regex pattern("(^|,)CQ($|,)", std::regex_constants::icase); if (!std::regex_search(bitrateModes.c_str(), pattern)) { return OK; } } mHasHEVC = true; // HEIC size range if (heicDetails != nullptr) { Loading @@ -152,19 +139,6 @@ status_t HeicEncoderInfoManager::initialize() { mHasHEIC = true; } // HEVC size range { auto res = getCodecSizeRange(MEDIA_MIMETYPE_VIDEO_HEVC, hevcDetails, &mMinSizeHevc, &mMaxSizeHevc, &mHevcFrameRateMaps); if (res != OK) { ALOGE("%s: Failed to get HEVC codec size range: %s (%d)", __FUNCTION__, strerror(-res), res); return BAD_VALUE; } mHasHEVC = true; } return OK; } Loading Loading @@ -290,5 +264,80 @@ sp<AMessage> HeicEncoderInfoManager::getCodecDetails( return details; } bool HeicEncoderInfoManager::getHevcCodecDetails( sp<IMediaCodecList> codecsList, const char* mime) { bool found = false; ssize_t idx = 0; while ((idx = codecsList->findCodecByType(mime, true /*encoder*/, idx)) >= 0) { const sp<MediaCodecInfo> info = codecsList->getCodecInfo(idx++); if (info == nullptr) { ALOGE("%s: Failed to get codec info for %s", __FUNCTION__, mime); break; } // Filter out software ones as they may be too slow if (!(info->getAttributes() & MediaCodecInfo::kFlagIsHardwareAccelerated)) { continue; } const sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(mime); if (caps == nullptr) { ALOGE("%s: [%s] Failed to get capabilities", __FUNCTION__, info->getCodecName()); break; } const sp<AMessage> details = caps->getDetails(); if (details == nullptr) { ALOGE("%s: [%s] Failed to get details", __FUNCTION__, info->getCodecName()); break; } // Check CQ mode AString bitrateModes; auto hasItem = details->findString("feature-bitrate-modes", &bitrateModes); if (!hasItem) { ALOGE("%s: [%s] Failed to query bitrate modes", __FUNCTION__, info->getCodecName()); break; } ALOGV("%s: [%s] feature-bitrate-modes value is %d, %s", __FUNCTION__, info->getCodecName(), hasItem, bitrateModes.c_str()); std::regex pattern("(^|,)CQ($|,)", std::regex_constants::icase); if (!std::regex_search(bitrateModes.c_str(), pattern)) { continue; // move on to next encoder } std::pair<int32_t, int32_t> minSizeHevc, maxSizeHevc; FrameRateMaps hevcFrameRateMaps; auto res = getCodecSizeRange(MEDIA_MIMETYPE_VIDEO_HEVC, details, &minSizeHevc, &maxSizeHevc, &hevcFrameRateMaps); if (res != OK) { ALOGE("%s: [%s] Failed to get size range: %s (%d)", __FUNCTION__, info->getCodecName(), strerror(-res), res); break; } if (kGridWidth < minSizeHevc.first || kGridWidth > maxSizeHevc.first || kGridHeight < minSizeHevc.second || kGridHeight > maxSizeHevc.second) { continue; // move on to next encoder } // Found: save name, size, frame rate mHevcName = info->getCodecName(); mMinSizeHevc = minSizeHevc; mMaxSizeHevc = maxSizeHevc; mHevcFrameRateMaps = hevcFrameRateMaps; found = true; break; } return found; } } //namespace camera3 } // namespace android
services/camera/libcameraservice/api2/HeicEncoderInfoManager.h +3 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public: } bool isSizeSupported(int32_t width, int32_t height, bool* useHeic, bool* useGrid, int64_t* stall) const; bool* useHeic, bool* useGrid, int64_t* stall, AString* hevcName) const; static const auto kGridWidth = 512; static const auto kGridHeight = 512; Loading @@ -61,11 +61,13 @@ private: FrameRateMaps::const_iterator findClosestSize(const FrameRateMaps& maps, int32_t width, int32_t height) const; sp<AMessage> getCodecDetails(sp<IMediaCodecList> codecsList, const char* name); bool getHevcCodecDetails(sp<IMediaCodecList> codecsList, const char* mime); bool mIsInited; std::pair<int32_t, int32_t> mMinSizeHeic, mMaxSizeHeic; std::pair<int32_t, int32_t> mMinSizeHevc, mMaxSizeHevc; bool mHasHEVC, mHasHEIC; AString mHevcName; FrameRateMaps mHeicFrameRateMaps, mHevcFrameRateMaps; bool mDisableGrid; Loading