From ab44e977cc9508f9e86ca419c264ba4ffa11b131 Mon Sep 17 00:00:00 2001 From: caochuan Date: Tue, 26 Aug 2025 15:11:48 +0800 Subject: [PATCH] slow motion Signed-off-by: caochuan --- .../include/mdk_record_photos_data.h | 4 + .../cloud_file_data_convert.cpp | 4 + .../src/mdk_record_photos_data.cpp | 18 ++ .../include/medialibrary_operation.h | 1 + .../media_library_helper/src/fetch_result.cpp | 2 + .../media_library_helper/src/file_asset.cpp | 20 +++ .../media_library_helper/src/media_column.cpp | 50 ++---- .../src/medialibrary_operation.cpp | 2 + .../medialibrary_data_extension/BUILD.gn | 1 + .../include/medialibrary_asset_operations.h | 2 + .../include/medialibrary_photo_operations.h | 1 + .../operation/photo_slow_motion_operation.h | 42 +++++ .../include/orm/media_column_type.h | 2 + .../include/orm/photos_po_writer.h | 14 ++ .../include/orm/po/photos_po.h | 4 + .../src/medialibrary_album_fusion_utils.cpp | 2 + .../src/medialibrary_asset_operations.cpp | 2 + .../src/medialibrary_photo_operations.cpp | 46 ++++++ .../src/medialibrary_rdbstore.cpp | 21 +++ .../src/medialibrary_subscriber.cpp | 2 + .../photo_custom_restore_operation.cpp | 2 + .../operation/photo_slow_motion_operation.cpp | 156 ++++++++++++++++++ .../medialibraryrefresh_fuzzer.h | 5 +- .../include/accurate_refresh_test_util.h | 5 +- .../medialibrary_meta_recovery_test_utils.cpp | 2 + .../src/media_asset_change_request_napi.cpp | 69 ++++++++ .../include/backup_const.h | 2 + .../src/base_restore.cpp | 2 + .../src/clone_restore.cpp | 4 + .../src/cloud_backup_restore.cpp | 2 + .../media_scanner/include/scanner/metadata.h | 10 ++ .../include/scanner/scanner_utils.h | 1 + .../src/scanner/media_scanner_db.cpp | 4 + .../media_scanner/src/scanner/metadata.cpp | 27 ++- .../src/scanner/metadata_extractor.cpp | 30 ++++ .../media_library_helper/include/file_asset.h | 6 + .../include/media_column.h | 3 + .../include/medialibrary_db_const.h | 3 +- .../include/set_slow_motion_range_uri.h | 31 ++++ .../include/userfile_manager_types.h | 6 + .../include/media_asset_change_request_napi.h | 2 + .../napi/medialibrary_napi_enum_comm.h | 2 + .../include/cloud_media_sync_const.h | 2 + .../include/dto/cloud_media_pull_data_dto.h | 2 + .../include/po/cloud_media_photo_po.h | 2 + .../include/po/cloud_media_pull_data.h | 2 + .../include/utils/cloud_sync_convert.h | 2 + .../include/vo/cloud_mdkrecord_photos_vo.h | 2 + .../include/vo/on_fetch_photos_vo.h | 2 + ...cloud_media_photo_controller_processor.cpp | 4 + .../src/dto/cloud_media_pull_data_dto.cpp | 2 + .../src/utils/cloud_sync_convert.cpp | 22 +++ .../src/vo/cloud_mdkrecord_photos_vo.cpp | 6 + .../src/vo/on_fetch_photos_vo.cpp | 6 + 54 files changed, 627 insertions(+), 41 deletions(-) create mode 100644 frameworks/innerkitsimpl/medialibrary_data_extension/include/operation/photo_slow_motion_operation.h create mode 100644 frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_slow_motion_operation.cpp create mode 100644 interfaces/inner_api/media_library_helper/include/set_slow_motion_range_uri.h diff --git a/frameworks/innerkitsimpl/media_library_cloud_sync/include/mdk_record_photos_data.h b/frameworks/innerkitsimpl/media_library_cloud_sync/include/mdk_record_photos_data.h index b5cf6d8382..56ad8d86a4 100644 --- a/frameworks/innerkitsimpl/media_library_cloud_sync/include/mdk_record_photos_data.h +++ b/frameworks/innerkitsimpl/media_library_cloud_sync/include/mdk_record_photos_data.h @@ -127,6 +127,10 @@ public: // attributes getter & setter MDKRecordPhotosData &SetDynamicRangeType(const int32_t dynamicRangeType); std::optional GetFrontCamera() const; MDKRecordPhotosData &SetFrontCamera(const std::string &frontCamera); + std::optional GetSlowMotionFlag() const; + MDKRecordPhotosData &SetSlowMotionFlag(const int32_t flag); + std::optional GetSlowMotionRange() const; + MDKRecordPhotosData &SetSlowMotionRange(const std::string &range); std::optional GetEditTime() const; MDKRecordPhotosData &SetEditTime(const int64_t editTime); std::optional GetOriginalSubType() const; diff --git a/frameworks/innerkitsimpl/media_library_cloud_sync/src/cloud_sync_data_convert/cloud_file_data_convert.cpp b/frameworks/innerkitsimpl/media_library_cloud_sync/src/cloud_sync_data_convert/cloud_file_data_convert.cpp index b21e8ac6d6..bbf163f2c6 100644 --- a/frameworks/innerkitsimpl/media_library_cloud_sync/src/cloud_sync_data_convert/cloud_file_data_convert.cpp +++ b/frameworks/innerkitsimpl/media_library_cloud_sync/src/cloud_sync_data_convert/cloud_file_data_convert.cpp @@ -209,6 +209,8 @@ int32_t CloudFileDataConvert::HandleUniqueFileds( map[PhotoColumn::PHOTO_SHOOTING_MODE_TAG] = MDKRecordField(upLoadRecord.shootingModeTag); map[PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE] = MDKRecordField(upLoadRecord.dynamicRangeType); map[PhotoColumn::PHOTO_FRONT_CAMERA] = MDKRecordField(upLoadRecord.frontCamera); + map[PhotoColumn::PHOTO_SLOW_MOTION_FLAG] = MDKRecordField(upLoadRecord.slowMotionFlag); + map[PhotoColumn::PHOTO_SLOW_MOTION_RANGE] = MDKRecordField(upLoadRecord.slowMotionRange); map[PhotoColumn::PHOTO_EDIT_TIME] = MDKRecordField(upLoadRecord.editTime); map[PhotoColumn::PHOTO_ORIGINAL_SUBTYPE] = MDKRecordField(upLoadRecord.originalSubtype); map[PhotoColumn::PHOTO_COVER_POSITION] = MDKRecordField(upLoadRecord.coverPosition); @@ -988,6 +990,8 @@ void CloudFileDataConvert::ConvertAttributes(MDKRecordPhotosData &data, OnFetchP onFetchPhotoVo.exifRotate = data.GetExifRotate().value_or(0); onFetchPhotoVo.supportedWatermarkType = data.GetSupportedWatermarkType().value_or(0); onFetchPhotoVo.strongAssociation = data.GetStrongAssociation().value_or(0); + onFetchPhotoVo.slowMotionFlag = data.GetSlowMotionFlag().value_or(-1); + onFetchPhotoVo.slowMotionRange = data.GetSlowMotionRange().value_or(""); } void CloudFileDataConvert::ConvertSourceAlbumIds(const MDKRecord &mdkRecord, OnFetchPhotosVo &onFetchPhotoVo) diff --git a/frameworks/innerkitsimpl/media_library_cloud_sync/src/mdk_record_photos_data.cpp b/frameworks/innerkitsimpl/media_library_cloud_sync/src/mdk_record_photos_data.cpp index e4902a6ec7..069a2d1b68 100644 --- a/frameworks/innerkitsimpl/media_library_cloud_sync/src/mdk_record_photos_data.cpp +++ b/frameworks/innerkitsimpl/media_library_cloud_sync/src/mdk_record_photos_data.cpp @@ -381,6 +381,24 @@ MDKRecordPhotosData &MDKRecordPhotosData::SetFrontCamera(const std::string &fron this->attributes_[PhotoColumn::PHOTO_FRONT_CAMERA] = MDKRecordField(frontCamera); return *this; } +std::optional MDKRecordPhotosData::GetSlowMotionFlag() const +{ + return this->recordReader_.GetIntValue(this->attributes_, PhotoColumn::PHOTO_SLOW_MOTION_FLAG); +} +MDKRecordPhotosData &MDKRecordPhotosData::SetSlowMotionFlag(const int32_t flag) +{ + this->attributes_[PhotoColumn::PHOTO_SLOW_MOTION_FLAG] = MDKRecordField(flag); + return *this; +} +std::optional MDKRecordPhotosData::GetSlowMotionRange() const +{ + return this->recordReader_.GetStringValue(this->attributes_, PhotoColumn::PHOTO_SLOW_MOTION_RANGE); +} +MDKRecordPhotosData &MDKRecordPhotosData::SetSlowMotionRange(const std::string &range) +{ + this->attributes_[PhotoColumn::PHOTO_SLOW_MOTION_RANGE] = MDKRecordField(range); + return *this; +} std::optional MDKRecordPhotosData::GetEditTime() const { return this->recordReader_.GetLongValue(this->attributes_, PhotoColumn::PHOTO_EDIT_TIME); diff --git a/frameworks/innerkitsimpl/media_library_helper/include/medialibrary_operation.h b/frameworks/innerkitsimpl/media_library_helper/include/medialibrary_operation.h index dffb553db4..2a05979034 100644 --- a/frameworks/innerkitsimpl/media_library_helper/include/medialibrary_operation.h +++ b/frameworks/innerkitsimpl/media_library_helper/include/medialibrary_operation.h @@ -219,6 +219,7 @@ enum class EXPORT OperationType : uint32_t { UPDATE_SUPPORTED_WATERMARK_TYPE, QUERY_HIGHLIGHT_DIRECTORY_SIZE, LS_MEDIA_FILES, + SET_SLOW_MOTION_RANGE, QUERY_ACTIVE_USER_ID, SET_USER_ALBUM_COVER_URI, SET_SOURCE_ALBUM_COVER_URI, diff --git a/frameworks/innerkitsimpl/media_library_helper/src/fetch_result.cpp b/frameworks/innerkitsimpl/media_library_helper/src/fetch_result.cpp index 26ba4d1fb1..d38684b1f9 100644 --- a/frameworks/innerkitsimpl/media_library_helper/src/fetch_result.cpp +++ b/frameworks/innerkitsimpl/media_library_helper/src/fetch_result.cpp @@ -100,6 +100,8 @@ static const ResultTypeMap &GetResultTypeMap() { PhotoColumn::PHOTO_IS_AUTO, TYPE_INT32 }, { PhotoColumn::PHOTO_MEDIA_SUFFIX, TYPE_STRING }, { PhotoColumn::PHOTO_IS_RECENT_SHOW, TYPE_INT32 }, + { PhotoColumn::PHOTO_SLOW_MOTION_FLAG, TYPE_INT32 }, + { PhotoColumn::PHOTO_SLOW_MOTION_RANGE, TYPE_STRING }, { MEDIA_SUM_SIZE, TYPE_INT64 }, { CustomRecordsColumns::FILE_ID, TYPE_INT32 }, { CustomRecordsColumns::BUNDLE_NAME, TYPE_STRING }, diff --git a/frameworks/innerkitsimpl/media_library_helper/src/file_asset.cpp b/frameworks/innerkitsimpl/media_library_helper/src/file_asset.cpp index f2909c1b92..8a24605032 100644 --- a/frameworks/innerkitsimpl/media_library_helper/src/file_asset.cpp +++ b/frameworks/innerkitsimpl/media_library_helper/src/file_asset.cpp @@ -645,6 +645,26 @@ void FileAsset::SetIsAuto(int32_t isAuto) member_[PhotoColumn::PHOTO_IS_AUTO] = isAuto; } +int32_t FileAsset::GetSlowMotionFlag() const +{ + return GetInt32Member(PhotoColumn::PHOTO_SLOW_MOTION_FLAG); +} + +void FileAsset::SetSlowMotionFlag(int32_t flag) +{ + member_[PhotoColumn::PHOTO_SLOW_MOTION_FLAG] = flag; +} + +const std::string &FileAsset::GetSlowMotionRange() const +{ + return GetStrMember(PhotoColumn::PHOTO_SLOW_MOTION_RANGE); +} + +void FileAsset::SetSlowMotionRange(const string &slowMotionRange) +{ + member_[PhotoColumn::PHOTO_SLOW_MOTION_RANGE] = slowMotionRange; +} + void FileAsset::SetOpenStatus(int32_t fd, int32_t openStatus) { lock_guard lock(openStatusMapMutex_); diff --git a/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp b/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp index 1cc50dcd49..b737b331a3 100644 --- a/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp +++ b/frameworks/innerkitsimpl/media_library_helper/src/media_column.cpp @@ -124,6 +124,8 @@ const std::string PhotoColumn::PHOTO_MEDIA_SUFFIX = "media_suffix"; const std::string PhotoColumn::PHOTO_REAL_LCD_VISIT_TIME = "real_lcd_visit_time"; const std::string PhotoColumn::PHOTO_VISIT_COUNT = "visit_count"; const std::string PhotoColumn::PHOTO_LCD_VISIT_COUNT = "lcd_visit_count"; +const std::string PhotoColumn::PHOTO_SLOW_MOTION_FLAG = "slow_motion_flag"; +const std::string PhotoColumn::PHOTO_SLOW_MOTION_RANGE = "slow_motion_range"; const std::string PhotoColumn::PHOTO_IS_RECENT_SHOW = "is_recent_show"; const std::string PhotoColumn::PHOTO_CLOUD_ID_INDEX = "cloud_id_index"; @@ -288,7 +290,9 @@ const std::string PhotoColumn::CREATE_PHOTO_TABLE = "CREATE TABLE IF NOT EXISTS PHOTO_IS_RECENT_SHOW + " INT NOT NULL DEFAULT 1, " + PHOTO_REAL_LCD_VISIT_TIME + " BIGINT NOT NULL DEFAULT 0, " + PHOTO_VISIT_COUNT + " INT NOT NULL DEFAULT 0, " + - PHOTO_LCD_VISIT_COUNT + " INT NOT NULL DEFAULT 0" + + PHOTO_LCD_VISIT_COUNT + " INT NOT NULL DEFAULT 0, " + + PHOTO_SLOW_MOTION_FLAG + " INT NOT NULL DEFAULT -1, " + + PHOTO_SLOW_MOTION_RANGE + " TEXT " + ") "; const std::string PhotoColumn::CREATE_CLOUD_ID_INDEX = BaseColumn::CreateIndex() + @@ -602,7 +606,7 @@ const std::set PhotoColumn::PHOTO_COLUMNS = { PhotoColumn::PHOTO_CE_AVAILABLE, PhotoColumn::PHOTO_OWNER_ALBUM_ID, PhotoColumn::SUPPORTED_WATERMARK_TYPE, PhotoColumn::PHOTO_THUMBNAIL_VISIBLE, PhotoColumn::PHOTO_QUALITY, PhotoColumn::PHOTO_IS_AUTO, PhotoColumn::PHOTO_MEDIA_SUFFIX, PhotoColumn::PHOTO_IS_RECENT_SHOW, PhotoColumn::PHOTO_IS_RECTIFICATION_COVER, - PhotoColumn::PHOTO_EXIF_ROTATE, + PhotoColumn::PHOTO_EXIF_ROTATE, PhotoColumn::PHOTO_SLOW_MOTION_FLAG, PhotoColumn::PHOTO_SLOW_MOTION_RANGE, }; bool PhotoColumn::IsPhotoColumn(const std::string &columnName) @@ -618,41 +622,13 @@ std::string PhotoColumn::CheckUploadPhotoColumns() { // Since date_modified has been checked in mdirty and fdirty, omit it here. const std::vector uploadPhotoColumns = { - MEDIA_FILE_PATH, - MEDIA_SIZE, - MEDIA_NAME, - MEDIA_TYPE, - MEDIA_MIME_TYPE, - MEDIA_OWNER_PACKAGE, - MEDIA_OWNER_APPID, - MEDIA_DEVICE_NAME, - MEDIA_DATE_ADDED, - MEDIA_DATE_TAKEN, - MEDIA_DURATION, - MEDIA_IS_FAV, - MEDIA_DATE_TRASHED, - MEDIA_DATE_DELETED, - MEDIA_HIDDEN, - PHOTO_META_DATE_MODIFIED, - PHOTO_ORIENTATION, - PHOTO_LATITUDE, - PHOTO_LONGITUDE, - PHOTO_HEIGHT, - PHOTO_WIDTH, - PHOTO_SUBTYPE, - PHOTO_USER_COMMENT, - PHOTO_DATE_YEAR, - PHOTO_DATE_MONTH, - PHOTO_DATE_DAY, - PHOTO_DETAIL_TIME, - PHOTO_SHOOTING_MODE, - PHOTO_SHOOTING_MODE_TAG, - PHOTO_OWNER_ALBUM_ID, - PHOTO_SOURCE_PATH, - MOVING_PHOTO_EFFECT_MODE, - PHOTO_COVER_POSITION, - PHOTO_ORIGINAL_SUBTYPE, - PHOTO_IS_RECTIFICATION_COVER, + MEDIA_FILE_PATH, MEDIA_SIZE, MEDIA_NAME, MEDIA_TYPE, MEDIA_MIME_TYPE, MEDIA_OWNER_PACKAGE, + MEDIA_OWNER_APPID, MEDIA_DEVICE_NAME, MEDIA_DATE_ADDED, MEDIA_DATE_TAKEN, MEDIA_DURATION, + MEDIA_IS_FAV, MEDIA_DATE_TRASHED, MEDIA_DATE_DELETED, MEDIA_HIDDEN, PHOTO_META_DATE_MODIFIED, + PHOTO_ORIENTATION, PHOTO_LATITUDE, PHOTO_LONGITUDE, PHOTO_HEIGHT, PHOTO_WIDTH, PHOTO_SUBTYPE, + PHOTO_USER_COMMENT, PHOTO_DATE_YEAR, PHOTO_DATE_MONTH, PHOTO_DATE_DAY, PHOTO_DETAIL_TIME, PHOTO_SHOOTING_MODE, + PHOTO_SHOOTING_MODE_TAG, PHOTO_OWNER_ALBUM_ID, PHOTO_SOURCE_PATH, MOVING_PHOTO_EFFECT_MODE, + PHOTO_COVER_POSITION, PHOTO_ORIGINAL_SUBTYPE, PHOTO_IS_RECTIFICATION_COVER, PHOTO_SLOW_MOTION_FLAG, }; std::string result = "("; diff --git a/frameworks/innerkitsimpl/media_library_helper/src/medialibrary_operation.cpp b/frameworks/innerkitsimpl/media_library_helper/src/medialibrary_operation.cpp index c1cff81100..e7cc10b4db 100644 --- a/frameworks/innerkitsimpl/media_library_helper/src/medialibrary_operation.cpp +++ b/frameworks/innerkitsimpl/media_library_helper/src/medialibrary_operation.cpp @@ -30,6 +30,7 @@ #include "ptp_medialibrary_manager_uri.h" #include "delete_permanently_operations_uri.h" #include "search_column.h" +#include "set_slow_motion_range_uri.h" #include "story_album_column.h" #include "story_cover_info_column.h" #include "story_play_info_column.h" @@ -382,6 +383,7 @@ const std::map& GetOprnTypeMap() { OPRN_SYSTEM_ALBUM_COVER_URI, OperationType::SET_SYSTEM_ALBUM_COVER_URI}, { OPRN_RESET_COVER_URI, OperationType::RESET_COVER_URI}, { MEDIA_QUERY_OPRN_MOVING_PHOTO_VIDEO_READY, OperationType::MOVING_PHOTO_VIDEO_READY }, + { OPRN_SET_SLOW_MOTION_RANGE, OperationType::SET_SLOW_MOTION_RANGE }, }; return oprnTypeMap; } diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn b/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn index 5c62577fa3..676eade55d 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/BUILD.gn @@ -647,6 +647,7 @@ ohos_shared_library("medialibrary_data_extension") { "src/operation/photo_file_operation.cpp", "src/operation/photo_mimetype_operation.cpp", "src/operation/photo_owner_album_id_operation.cpp", + "src/operation/photo_slow_motion_operation.cpp", "src/operation/photo_source_path_operation.cpp", "src/operation/photo_storage_operation.cpp", "src/photo_album_operation/photo_album_lpath_operation.cpp", diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_asset_operations.h b/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_asset_operations.h index 79718460f2..c4e63dbc6f 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_asset_operations.h +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_asset_operations.h @@ -121,6 +121,8 @@ EXPORT const std::unordered_map FILEASSET_MEMBER_MAP = { { PhotoColumn::PHOTO_IS_AUTO, MEMBER_TYPE_INT32 }, { PhotoColumn::PHOTO_MEDIA_SUFFIX, MEMBER_TYPE_STRING }, { PhotoColumn::STAGE_VIDEO_TASK_STATUS, MEMBER_TYPE_INT32 }, + { PhotoColumn::PHOTO_SLOW_MOTION_FLAG, MEMBER_TYPE_INT32 }, + { PhotoColumn::PHOTO_SLOW_MOTION_RANGE, MEMBER_TYPE_STRING }, }; typedef struct { diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_photo_operations.h b/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_photo_operations.h index 54f53edbb2..67b1b5e83b 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_photo_operations.h +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/include/medialibrary_photo_operations.h @@ -103,6 +103,7 @@ public: EXPORT static int32_t CancelCustomRestore(MediaLibraryCommand &cmd); EXPORT static int32_t UpdateSupportedWatermarkType(MediaLibraryCommand &cmd); EXPORT static int32_t BatchSetOwnerAlbumId(MediaLibraryCommand &cmd); + EXPORT static int32_t SetSlowMotionRange(MediaLibraryCommand &cmd); static int32_t UpdateExtension(const int32_t &fileId, const int32_t &fileType, PhotoExtInfo &photoExtInfo, NativeRdb::ValuesBucket &updateValues); static int32_t LSMediaFiles(MediaLibraryCommand& cmd); diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/include/operation/photo_slow_motion_operation.h b/frameworks/innerkitsimpl/medialibrary_data_extension/include/operation/photo_slow_motion_operation.h new file mode 100644 index 0000000000..b260822c2b --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/include/operation/photo_slow_motion_operation.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEDIA_PHOTO_SLOW_MOTION_OPERATION_H +#define OHOS_MEDIA_PHOTO_SLOW_MOTION_OPERATION_H + +#include +#include + +#include "medialibrary_rdbstore.h" + +namespace OHOS::Media { + +struct SlowMotionRangeSet { + std::string fileId = ""; + int32_t slowMotionFlag = -1; + std::string slowMotionRange = ""; +}; + +class PhotoSlowMotionOperation { +public: + static int32_t UpdateDefaultSlowMotionRange(); + static int32_t GetFpsByfilePath(std::string filePath, int32_t &flag); + +private: + static int32_t HandleUpdateDefaultSlowMotionRange(const std::shared_ptr rdbStore, + const std::vector &updateSlowMotionMap); +}; +} // namespace OHOS::Media +#endif // OHOS_MEDIA_PHOTO_SLOW_MOTION_OPERATION_H diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/media_column_type.h b/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/media_column_type.h index 4d2c014391..35e8affd71 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/media_column_type.h +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/media_column_type.h @@ -108,6 +108,8 @@ static const std::map PHOTOS_COLUMNS = { {PhotoColumn::PHOTO_CHECK_FLAG, DataType::INT}, {PhotoColumn::STAGE_VIDEO_TASK_STATUS, DataType::INT}, {PhotoColumn::PHOTO_IS_AUTO, DataType::INT}, + {PhotoColumn::PHOTO_SLOW_MOTION_FLAG, DataType::INT}, + {PhotoColumn::PHOTO_SLOW_MOTION_RANGE, DataType::STRING}, {MediaColumn::MEDIA_ID, DataType::INT}, {"album_cloud_id", DataType::STRING}, {"lpath", DataType::STRING}, diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/photos_po_writer.h b/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/photos_po_writer.h index 66e19710b9..00ac09d2c4 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/photos_po_writer.h +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/photos_po_writer.h @@ -106,6 +106,8 @@ private: {PhotoColumn::PHOTO_DIRTY, &PhotosPoWriter::SetDirty}, {PhotoColumn::PHOTO_POSITION, &PhotosPoWriter::SetPosition}, {PhotoColumn::PHOTO_CLOUD_VERSION, &PhotosPoWriter::SetCloudVersion}, + {PhotoColumn::PHOTO_SLOW_MOTION_FLAG, &PhotosPoWriter::SetSlowMotionFlag}, + {PhotoColumn::PHOTO_SLOW_MOTION_RANGE, &PhotosPoWriter::SetSlowMotionRange}, {"album_cloud_id", &PhotosPoWriter::SetAlbumCloudId}, {"lpath", &PhotosPoWriter::SetlPath}, }; @@ -441,6 +443,18 @@ private: CHECK_AND_RETURN(!errConn); this->photosPo_.albumLPath = std::get(val); } + void SetSlowMotionFlag(std::variant &val) + { + bool errConn = !std::holds_alternative(val); + CHECK_AND_RETURN(!errConn); + this->photosPo_.slowMotionFlag = std::get(val); + } + void SetSlowMotionRange(std::variant &val) + { + bool errConn = !std::holds_alternative(val); + CHECK_AND_RETURN(!errConn); + this->photosPo_.slowMotionRange = std::get(val); + } }; } // namespace OHOS::Media::ORM #endif // OHOS_MEDIA_ORM_PHOTOS_PO_WRITER_H diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/po/photos_po.h b/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/po/photos_po.h index 5e1dce2b0d..a215e47b1a 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/po/photos_po.h +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/include/orm/po/photos_po.h @@ -77,6 +77,8 @@ public: std::optional baseVersion; // PhotoColumn::PHOTO_CLOUD_VERSION std::optional recordType; // PhotoColumn::PHOTO_CLOUD_ID std::optional recordId; // PhotoColumn::PHOTO_CLOUD_ID + std::optional slowMotionFlag; // PhotoColumn::PHOTO_SLOW_MOTION_FLAG + std::optional slowMotionRange; // PhotoColumn::PHOTO_SLOW_MOTION_RANGE std::optional isNew; /* keep cloud_id at the last; so RecordToValueBucket can skip it*/ @@ -145,6 +147,8 @@ private: << "\"shootingModeTag\": \"" << shootingModeTag.value_or("") << "\", " << "\"dynamicRangeType\": " << dynamicRangeType.value_or(0) << ", " << "\"frontCamera\": \"" << frontCamera.value_or("") << "\", " + << "\"slowMotionFlag\": " << slowMotionFlag.value_or(0) << ", " + << "\"slowMotionRange\": " << slowMotionRange.value_or("") << ", " << "\"coverPosition\": " << coverPosition.value_or(0) << ", " << "\"isRectificationCover\": " << isRectificationCover.value_or(0) << ", " << "\"movingPhotoEffectMode\": " << movingPhotoEffectMode.value_or(0) << ", " diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_album_fusion_utils.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_album_fusion_utils.cpp index d63c4f267c..6b38293c51 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_album_fusion_utils.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_album_fusion_utils.cpp @@ -143,6 +143,8 @@ static unordered_map commonColumnTypeMap = { {PhotoColumn::PHOTO_BURST_COVER_LEVEL, ResultSetDataType::TYPE_INT32}, {PhotoColumn::SUPPORTED_WATERMARK_TYPE, ResultSetDataType::TYPE_INT32}, {PhotoColumn::PHOTO_MEDIA_SUFFIX, ResultSetDataType::TYPE_STRING}, + {PhotoColumn::PHOTO_SLOW_MOTION_FLAG, ResultSetDataType::TYPE_INT32}, + {PhotoColumn::PHOTO_SLOW_MOTION_RANGE, ResultSetDataType::TYPE_STRING}, {PhotoColumn::PHOTO_IS_RECENT_SHOW, ResultSetDataType::TYPE_INT32} }; diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_asset_operations.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_asset_operations.cpp index 512b3f6e3b..5918d366f5 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_asset_operations.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_asset_operations.cpp @@ -2345,6 +2345,8 @@ const std::unordered_map> { PhotoColumn::PHOTO_IS_TEMP, { IsBool } }, { PhotoColumn::PHOTO_DIRTY, { IsInt32 } }, { PhotoColumn::PHOTO_DETAIL_TIME, { IsStringNotNull } }, + { PhotoColumn::PHOTO_SLOW_MOTION_FLAG, { Forbidden } }, + { PhotoColumn::PHOTO_SLOW_MOTION_RANGE, { IsStringNotNull } }, { PhotoColumn::PHOTO_OWNER_ALBUM_ID, { IsInt32 } }, { PhotoColumn::PHOTO_CE_AVAILABLE, { IsInt32 } }, { PhotoColumn::SUPPORTED_WATERMARK_TYPE, { IsInt32 } }, diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_photo_operations.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_photo_operations.cpp index 577a33d987..0793f18fa9 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_photo_operations.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_photo_operations.cpp @@ -2180,6 +2180,8 @@ int32_t MediaLibraryPhotoOperations::UpdateV10(MediaLibraryCommand &cmd) return UpdateOwnerAlbumId(cmd); case OperationType::UPDATE_SUPPORTED_WATERMARK_TYPE: return UpdateSupportedWatermarkType(cmd); + case OperationType::SET_SLOW_MOTION_RANGE: + return SetSlowMotionRange(cmd); default: return UpdateFileAsset(cmd); } @@ -2292,6 +2294,7 @@ const static vector EDITED_COLUMN_VECTOR = { PhotoColumn::MOVING_PHOTO_EFFECT_MODE, PhotoColumn::PHOTO_ORIGINAL_SUBTYPE, PhotoColumn::PHOTO_OWNER_ALBUM_ID, + PhotoColumn::PHOTO_SLOW_MOTION_RANGE, }; static int32_t CheckFileAssetStatus(const shared_ptr& fileAsset, bool checkMovingPhoto = false) @@ -2490,6 +2493,23 @@ static int32_t RevertMetadata(int32_t fileId, int64_t time, int32_t effectMode, return E_OK; } +static int32_t RevertSlowMotionRange(int32_t fileId) +{ + MEDIA_INFO_LOG("MediaLibraryPhotoOperations RevertSlowMotionRange begin fileId: %{public}d", fileId); + auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore(); + CHECK_AND_RETURN_RET(rdbStore != nullptr, E_HAS_DB_ERROR); + MediaLibraryCommand cmd(OperationObject::FILESYSTEM_PHOTO, OperationType::UPDATE); + cmd.GetAbsRdbPredicates()->EqualTo(MediaColumn::MEDIA_ID, to_string(fileId)); + ValuesBucket updateValues; + updateValues.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, ""); + cmd.SetValueBucket(updateValues); + int32_t rowId = 0; + int32_t result = rdbStore->Update(cmd, rowId); + CHECK_AND_RETURN_RET_LOG(result == NativeRdb::E_OK && rowId > 0, E_HAS_DB_ERROR, + "Failed to revert slow motion range. Result %{public}d.", result); + return E_OK; +} + static int32_t UpdateEffectMode(int32_t fileId, int32_t effectMode) { auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore(); @@ -2862,6 +2882,7 @@ int32_t MediaLibraryPhotoOperations::DoRevertEdit(const std::shared_ptrUpdateWithDateTime(values, predicates); + CHECK_AND_RETURN_RET_LOG(updatedRows >= 0, E_HAS_DB_ERROR, "Failed to set SlowMotionRange, err: %{public}d", + updatedRows); + + return updatedRows; +} } // namespace Media } // namespace OHOS diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp index 3283690077..02e13424e1 100755 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/medialibrary_rdbstore.cpp @@ -4735,6 +4735,17 @@ static void UpgradeAPI18(RdbStore &store, unordered_map &photoColu MEDIA_INFO_LOG("End VERSION_ADD_FOREGROUND_ANALYSIS"); } +static void AddSlowMotionColumns(RdbStore &store) +{ + const vector sqls = { + "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_SLOW_MOTION_FLAG + + " INT NOT NULL DEFAULT -1", + "ALTER TABLE " + PhotoColumn::PHOTOS_TABLE + " ADD COLUMN " + PhotoColumn::PHOTO_SLOW_MOTION_RANGE + " TEXT" + }; + MEDIA_INFO_LOG("Start add SLOW_MOTION column"); + ExecSqls(sqls, store); +} + static void AddAssetAlbumOperationTable(RdbStore &store) { const vector executeSqlStrs = { @@ -5110,6 +5121,14 @@ static void UpgradeFromAllVersionFourthPart(RdbStore &store, unordered_mapHandleTwoDayMissions(); DfxManager::GetInstance()->HandleOneWeekMissions(); PhotoDayMonthYearOperation::RepairDateTime(); diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_custom_restore_operation.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_custom_restore_operation.cpp index 518d897cc2..9e002b2e60 100644 --- a/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_custom_restore_operation.cpp +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_custom_restore_operation.cpp @@ -798,6 +798,8 @@ NativeRdb::ValuesBucket PhotoCustomRestoreOperation::GetInsertValue( value.PutInt(PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, data->GetDynamicRangeType()); value.PutString(PhotoColumn::PHOTO_USER_COMMENT, data->GetUserComment()); value.PutInt(PhotoColumn::PHOTO_QUALITY, 0); + value.PutInt(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, data->GetSlowMotionFlag()); + value.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, data->GetSlowMotionRange()); FillFileInfo(fileInfo, data); return value; } diff --git a/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_slow_motion_operation.cpp b/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_slow_motion_operation.cpp new file mode 100644 index 0000000000..c288f33355 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_data_extension/src/operation/photo_slow_motion_operation.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define MLOG_TAG "PhotoSlowMotionOperation" + +#include +#include + +#include "photo_slow_motion_operation.h" + +#include "directory_ex.h" + +#include "abs_rdb_predicates.h" +#include "media_column.h" +#include "media_file_utils.h" +#include "media_log.h" +#include "medialibrary_subscriber.h" +#include "medialibrary_unistore_manager.h" +#include "metadata_extractor.h" +#include "result_set_utils.h" +#include "scanner_utils.h" +#include "values_bucket.h" + +using namespace OHOS::NativeRdb; + +namespace OHOS::Media { +const double DEFAULT_SLOW_MOTION_RANGE_RATIO_START = 0.2; +const double DEFAULT_SLOW_MOTION_RANGE_RATIO_END = 0.8; +const int32_t BATCH_QUERY_NUMBER = 200; +const std::string COLUMN_COUNT = "count(*)"; + +static int32_t GetNeedUpdateCount(int32_t &count) +{ + count = 0; + auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore(); + CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "GetRdbStore failed. rdbStore is null."); + AbsRdbPredicates predicates = AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE); + predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO)) + ->And() + ->EqualTo(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, to_string(static_cast(SlowMotionType::INVALID))) + ->Limit(BATCH_QUERY_NUMBER); + std::vector columns = { COLUMN_COUNT }; + auto resultSet = rdbStore->Query(predicates, columns); + CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, "GetNeedUpdateCount failed. rdbStore is null."); + while (resultSet->GoToNextRow() == NativeRdb::E_OK) { + count = GetInt32Val(COLUMN_COUNT, resultSet); + return E_OK; + } + resultSet->Close(); + return E_ERR; +} + +int32_t PhotoSlowMotionOperation::UpdateDefaultSlowMotionRange() +{ + MEDIA_DEBUG_LOG("enter UpdateDefaultSlowMotionRange."); + int32_t updateCount = 0; + CHECK_AND_RETURN_RET_LOG(GetNeedUpdateCount(updateCount) == E_OK, E_ERR, "Failed to GetNeedUpdateCount."); + auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore(); + CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "GetRdbStore failed. rdbStore is null."); + AbsRdbPredicates predicates = AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE); + predicates.EqualTo(MediaColumn::MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO)) + ->And() + ->EqualTo(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, to_string(static_cast(SlowMotionType::INVALID))) + ->Limit(BATCH_QUERY_NUMBER); + const std::vector columns = { MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH, + MediaColumn::MEDIA_DURATION }; + + int32_t processCount = 0; + while (MedialibrarySubscriber::IsCurrentStatusOn() && processCount < updateCount) { + auto resultSet = rdbStore->Query(predicates, columns); + CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, + "UpdateDefaultSlowMotionRange failed. resultSet is null."); + std::vector updateSlowMotionMap; + while (resultSet->GoToNextRow() == NativeRdb::E_OK) { + std::string fileId = GetStringVal(MediaColumn::MEDIA_ID, resultSet); + std::string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet); + int32_t duration = GetInt32Val(MediaColumn::MEDIA_DURATION, resultSet); + int32_t slowMotionFlag = -1; + std::string defaultSlowMotionRange = ""; + if (GetFpsByfilePath(filePath, slowMotionFlag) != E_OK) { + MEDIA_ERR_LOG("get slowMotionFlag by path failed"); + continue; + } + if (slowMotionFlag == static_cast(SlowMotionType::SLOW_MOTION)) { + defaultSlowMotionRange = + std::to_string(static_cast(duration * DEFAULT_SLOW_MOTION_RANGE_RATIO_START)) + + "," + + std::to_string(static_cast(duration * DEFAULT_SLOW_MOTION_RANGE_RATIO_END)); + } + updateSlowMotionMap.push_back(SlowMotionRangeSet { fileId, slowMotionFlag, defaultSlowMotionRange }); + } + resultSet->Close(); + if (!updateSlowMotionMap.empty()) { + CHECK_AND_RETURN_RET_LOG(HandleUpdateDefaultSlowMotionRange(rdbStore, updateSlowMotionMap) == E_OK, E_ERR, + "Failed to HandleUpdateDefaultSlowMotionRange."); + } + processCount += BATCH_QUERY_NUMBER; + } + MEDIA_DEBUG_LOG("end UpdateDefaultSlowMotionRange."); + return E_OK; +} + +int32_t PhotoSlowMotionOperation::GetFpsByfilePath(std::string filePath, int32_t &flag) +{ + + std::unique_ptr data = make_unique(); + data->SetFilePath(filePath); + data->SetFileName(MediaFileUtils::GetFileName(filePath)); + data->SetFileMediaType(MEDIA_TYPE_VIDEO); + int32_t err = MetadataExtractor::ExtractAVMetadata(data); + MEDIA_INFO_LOG("Extract av metadata end"); + CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "failed to extension data"); + flag = data->GetSlowMotionFlag(); + return E_OK; +} + +int32_t PhotoSlowMotionOperation::HandleUpdateDefaultSlowMotionRange( + const std::shared_ptr rdbStore, + const std::vector &updateSlowMotionMap) +{ + CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "rdbStore is nullptr."); + MEDIA_DEBUG_LOG("start to update default slow_motion_range."); + for (const auto &item : updateSlowMotionMap) { + ValuesBucket values; + std::string fileId = item.fileId; + int32_t slowMotionFlag = item.slowMotionFlag; + std::string slowMotionRange = item.slowMotionRange; + values.Put(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, slowMotionFlag); + values.Put(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, slowMotionRange); + AbsRdbPredicates predicates = AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE); + predicates.EqualTo(MediaColumn::MEDIA_ID, fileId); + int32_t changedRows = -1; + int32_t ret = rdbStore->Update(changedRows, values, predicates); + if (ret != E_OK) { + MEDIA_ERR_LOG("update failed, file_id: %{public}s, slowMotionFlag: %{public}d, + slow_motion_range: %{public}s.", fileId.c_str(), slowMotionFlag, slowMotionRange.c_str()); + continue; + } + MEDIA_INFO_LOG("update success, file_id: %{public}s, slowMotionFlag: %{public}d, slow_motion_range: %{public}s.", + fileId.c_str(), slowMotionFlag, slowMotionRange.c_str()); + } + MEDIA_DEBUG_LOG("end to update default slow_motion_range."); + return E_OK; +} +} // namespace OHOS::Media diff --git a/frameworks/innerkitsimpl/test/fuzztest/medialibraryrefresh_fuzzer/medialibraryrefresh_fuzzer.h b/frameworks/innerkitsimpl/test/fuzztest/medialibraryrefresh_fuzzer/medialibraryrefresh_fuzzer.h index ff4b757fd8..bf869413ef 100644 --- a/frameworks/innerkitsimpl/test/fuzztest/medialibraryrefresh_fuzzer/medialibraryrefresh_fuzzer.h +++ b/frameworks/innerkitsimpl/test/fuzztest/medialibraryrefresh_fuzzer/medialibraryrefresh_fuzzer.h @@ -159,7 +159,10 @@ const std::string CREATE_PHOTO_TABLE = "CREATE TABLE IF NOT EXISTS " + PhotoColumn::STAGE_VIDEO_TASK_STATUS + " INT NOT NULL DEFAULT 0, " + PhotoColumn::PHOTO_IS_AUTO + " INT NOT NULL DEFAULT 0, " + PhotoColumn::PHOTO_MEDIA_SUFFIX + " TEXT, " + - PhotoColumn::PHOTO_IS_RECENT_SHOW + " INT NOT NULL DEFAULT 1)"; + PhotoColumn::PHOTO_IS_RECENT_SHOW + " INT NOT NULL DEFAULT 1, " + + PhotoColumn::PHOTO_SLOW_MOTION_FLAG + " INT NOT NULL DEFAULT -1, " + + PhotoColumn::PHOTO_SLOW_MOTION_RANGE + " TEXT ," + + ")"; const AccurateRefresh::PhotoAssetChangeInfo NORMAL_ASSET = { ASSET_FILE_ID, ASSET_URI, ASSET_DATE_DAY, "uri", // owner album uri diff --git a/frameworks/innerkitsimpl/test/unittest/media_refresh/include/accurate_refresh_test_util.h b/frameworks/innerkitsimpl/test/unittest/media_refresh/include/accurate_refresh_test_util.h index 6486a2a506..fd87fed9f2 100644 --- a/frameworks/innerkitsimpl/test/unittest/media_refresh/include/accurate_refresh_test_util.h +++ b/frameworks/innerkitsimpl/test/unittest/media_refresh/include/accurate_refresh_test_util.h @@ -145,7 +145,10 @@ const std::string CREATE_PHOTO_TABLE = "CREATE TABLE IF NOT EXISTS " + PhotoColumn::STAGE_VIDEO_TASK_STATUS + " INT NOT NULL DEFAULT 0, " + PhotoColumn::PHOTO_IS_AUTO + " INT NOT NULL DEFAULT 0, " + PhotoColumn::PHOTO_MEDIA_SUFFIX + " TEXT, " + - PhotoColumn::PHOTO_IS_RECENT_SHOW + " INT NOT NULL DEFAULT 1)"; + PhotoColumn::PHOTO_IS_RECENT_SHOW + " INT NOT NULL DEFAULT 1, " + + PhotoColumn::PHOTO_SLOW_MOTION_FLAG + " INT NOT NULL DEFAULT -1, " + + PhotoColumn::PHOTO_SLOW_MOTION_RANGE + " TEXT ," + + ")"; const int32_t FAVORITE_ALBUM_ID = 1; const int32_t FAVORITE_ALBUM_ID_TOW = 101; diff --git a/frameworks/innerkitsimpl/test/unittest/medialibrary_meta_recovery_test/src/medialibrary_meta_recovery_test_utils.cpp b/frameworks/innerkitsimpl/test/unittest/medialibrary_meta_recovery_test/src/medialibrary_meta_recovery_test_utils.cpp index f71f6564f3..28df1c9726 100644 --- a/frameworks/innerkitsimpl/test/unittest/medialibrary_meta_recovery_test/src/medialibrary_meta_recovery_test_utils.cpp +++ b/frameworks/innerkitsimpl/test/unittest/medialibrary_meta_recovery_test/src/medialibrary_meta_recovery_test_utils.cpp @@ -99,6 +99,8 @@ static const std::unordered_map RESULT_TYPE_MAP { PhotoColumn::PHOTO_OWNER_ALBUM_ID, TYPE_INT32 }, { PhotoColumn::PHOTO_ORIGINAL_ASSET_CLOUD_ID, TYPE_STRING }, { PhotoColumn::PHOTO_SOURCE_PATH, TYPE_STRING }, + { PhotoColumn::PHOTO_SLOW_MOTION_FLAG, TYPE_INT32 }, + { PhotoColumn::PHOTO_SLOW_MOTION_RANGE, TYPE_STRING }, }; } diff --git a/frameworks/js/src/media_asset_change_request_napi.cpp b/frameworks/js/src/media_asset_change_request_napi.cpp index 39cf012e7d..4aa4709021 100644 --- a/frameworks/js/src/media_asset_change_request_napi.cpp +++ b/frameworks/js/src/media_asset_change_request_napi.cpp @@ -46,6 +46,7 @@ #include "permission_utils.h" #include "photo_proxy_napi.h" #include "securec.h" +#include "set_slow_motion_range_uri.h" #ifdef HAS_ACE_ENGINE_PART #include "ui_content.h" #endif @@ -174,6 +175,7 @@ napi_value MediaAssetChangeRequestNapi::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("setOrientation", JSSetOrientation), DECLARE_NAPI_FUNCTION("setSupportedWatermarkType", JSSetSupportedWatermarkType), DECLARE_NAPI_FUNCTION("setVideoEnhancementAttr", JSSetVideoEnhancementAttr), + DECLARE_NAPI_FUNCTION("setSlowMotionRange", JSSetSlowMotionRange), } }; MediaLibraryNapiUtils::NapiDefineClass(env, exports, info); return exports; @@ -2621,6 +2623,29 @@ static bool SetSupportedWatermarkTypeExecute(MediaAssetChangeRequestAsyncContext return true; } +static bool SetSlowMotionRangeExecute(MediaAssetChangeRequestAsyncContext& context) +{ + MediaLibraryTracer tracer; + tracer.Start("SetSlowMotionRange"); + + if (context.objectInfo == nullptr) { + NAPI_ERR_LOG("context.objectInfo is nullptr"); + return false; + } + + DataShare::DataSharePredicates predicates; + auto fileAsset = context.objectInfo->GetFileAssetInstance(); + if (fileAsset == nullptr) { + NAPI_ERR_LOG("fileAsset is nullptr"); + return false; + } + predicates.EqualTo(PhotoColumn::MEDIA_ID, std::to_string(fileAsset->GetId())); + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, fileAsset->GetSlowMotionRange()); + + return UpdateAssetProperty(context, PAH_SET_SLOW_MOTION_RANGE, predicates, valuesBucket); +} + static const unordered_map EXECUTE_MAP = { { AssetChangeOperation::CREATE_FROM_URI, CreateFromFileUriExecute }, { AssetChangeOperation::GET_WRITE_CACHE_HANDLER, SubmitCacheExecute }, @@ -2639,6 +2664,7 @@ static const unordered_map(); + MediaLibraryNapiUtils::AsyncContextSetObjectInfo(env, info, asyncContext, ARGS_TWO, ARGS_TWO); + + CHECK_COND(env, asyncContext != nullptr, JS_INNER_FAIL); + CHECK_COND(env, asyncContext->objectInfo != nullptr, JS_INNER_FAIL); + CHECK_COND(env, asyncContext->objectInfo->fileAsset_ != nullptr, JS_INNER_FAIL); + if (asyncContext->objectInfo->fileAsset_->GetMediaType() != MEDIA_TYPE_VIDEO) { + NapiError::ThrowError(env, JS_E_OPERATION_NOT_SUPPORT, "Operation not support: the asset is not video"); + return nullptr; + } + auto slowMotionFlag = asyncContext->objectInfo->fileAsset_->GetSlowMotionFlag(); + if (slowMotionFlag != static_cast(SlowMotionType::SLOW_MOTION)) { + NapiError::ThrowError(env, JS_E_OPERATION_NOT_SUPPORT, "Operation not support: type is not slow motion"); + return nullptr; + } + int32_t rangeBegin; + int32_t rangeEnd; + CHECK_COND_WITH_MESSAGE(env, MediaLibraryNapiUtils::GetInt32(env, asyncContext->argv[PARAM0], + rangeBegin) == napi_ok, "Failed to get rangeBegin"); + CHECK_COND_WITH_MESSAGE(env, MediaLibraryNapiUtils::GetInt32(env, asyncContext->argv[PARAM1], + rangeEnd) == napi_ok, "Failed to get rangeEnd"); + CHECK_COND_WITH_MESSAGE(env, rangeBegin >= 0, "rangeBegin is not valid"); + CHECK_COND_WITH_MESSAGE(env, rangeEnd > 0 && rangeEnd > rangeBegin, "rangeEnd is not valid"); + int32_t duration = asyncContext->objectInfo->fileAsset_->GetDuration(); + CHECK_COND_WITH_MESSAGE(env, rangeBegin < duration && rangeEnd <= duration, "range is not valid"); + + std::string range = std::to_string(rangeBegin) + "," + std::to_string(rangeEnd); + asyncContext->objectInfo->fileAsset_->SetSlowMotionRange(range); + + asyncContext->objectInfo->assetChangeOperations_.push_back(AssetChangeOperation::SET_SLOW_MOTION_RANGE); + napi_value result = nullptr; + CHECK_ARGS(env, napi_get_undefined(env, &result), JS_INNER_FAIL); + return result; +} } // namespace OHOS::Media \ No newline at end of file diff --git a/frameworks/services/media_backup_extension/include/backup_const.h b/frameworks/services/media_backup_extension/include/backup_const.h index 971d0a3493..d7712d1353 100644 --- a/frameworks/services/media_backup_extension/include/backup_const.h +++ b/frameworks/services/media_backup_extension/include/backup_const.h @@ -461,6 +461,8 @@ struct FileInfo { bool needUpdate {false}; int32_t storyChosen {0}; bool isLivePhoto {false}; + int32_t slowMotionFlag {-1}; + std::string slowMotionRange; }; struct AlbumInfo { diff --git a/frameworks/services/media_backup_extension/src/base_restore.cpp b/frameworks/services/media_backup_extension/src/base_restore.cpp index 18428b5fc9..b44a6a8b87 100644 --- a/frameworks/services/media_backup_extension/src/base_restore.cpp +++ b/frameworks/services/media_backup_extension/src/base_restore.cpp @@ -677,6 +677,8 @@ void BaseRestore::SetValueFromMetaData(FileInfo &fileInfo, NativeRdb::ValuesBuck value.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, data->GetLastVisitTime()); value.PutString(PhotoColumn::PHOTO_FRONT_CAMERA, data->GetFrontCamera()); value.PutInt(PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, data->GetDynamicRangeType()); + value.PutInt(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, data->GetSlowMotionFlag()); + value.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, data->GetSlowMotionRange()); InsertDateAdded(data, value); SetOrientationAndExifRotate(fileInfo, value, data); InsertUserComment(data, value, fileInfo); diff --git a/frameworks/services/media_backup_extension/src/clone_restore.cpp b/frameworks/services/media_backup_extension/src/clone_restore.cpp index bdf72f6c0c..a31bd4a1af 100644 --- a/frameworks/services/media_backup_extension/src/clone_restore.cpp +++ b/frameworks/services/media_backup_extension/src/clone_restore.cpp @@ -1208,6 +1208,8 @@ NativeRdb::ValuesBucket CloneRestore::GetInsertValue(const FileInfo &fileInfo, c values.PutInt(MediaColumn::MEDIA_HIDDEN, fileInfo.hidden); values.PutString(PhotoColumn::PHOTO_SOURCE_PATH, fileInfo.sourcePath); values.PutInt(PhotoColumn::PHOTO_SYNC_STATUS, static_cast(SyncStatusType::TYPE_BACKUP)); + values.PutInt(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, fileInfo.slowMotionFlag); + values.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, fileInfo.slowMotionRange); GetThumbnailInsertValue(fileInfo, values); GetInsertValueFromValMap(fileInfo, values); return values; @@ -2277,6 +2279,8 @@ void CloneRestore::SetSpecialAttributes(const string &tableName, const shared_pt fileInfo.sourcePath = this->photosClone_.FindSourcePath(fileInfo); fileInfo.latitude = GetDoubleVal("latitude", resultSet); fileInfo.longitude = GetDoubleVal("longitude", resultSet); + fileInfo.slowMotionFlag = GetInt32Val(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, resultSet); + fileInfo.slowMotionRange = GetStringVal(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, resultSet); GetOrientationAndExifRotateValue(resultSet, fileInfo); } diff --git a/frameworks/services/media_backup_extension/src/cloud_backup_restore.cpp b/frameworks/services/media_backup_extension/src/cloud_backup_restore.cpp index 0b779138dd..5478857738 100644 --- a/frameworks/services/media_backup_extension/src/cloud_backup_restore.cpp +++ b/frameworks/services/media_backup_extension/src/cloud_backup_restore.cpp @@ -146,6 +146,8 @@ void CloudBackupRestore::SetValueFromMetaData(FileInfo &fileInfo, NativeRdb::Val value.PutString(PhotoColumn::PHOTO_FRONT_CAMERA, data->GetFrontCamera()); value.PutInt(PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, data->GetDynamicRangeType()); value.PutString(PhotoColumn::PHOTO_USER_COMMENT, data->GetUserComment()); + value.PutInt(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, data->GetSlowMotionFlag()); + value.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, data->GetSlowMotionRange()); BaseRestore::SetOrientationAndExifRotate(fileInfo, value, data); // [special type]live photo diff --git a/frameworks/services/media_scanner/include/scanner/metadata.h b/frameworks/services/media_scanner/include/scanner/metadata.h index 4c16187cfd..e207425086 100644 --- a/frameworks/services/media_scanner/include/scanner/metadata.h +++ b/frameworks/services/media_scanner/include/scanner/metadata.h @@ -169,6 +169,12 @@ public: EXPORT void SetDetailTime(const VariantData &detailTime); EXPORT std::string GetDetailTime() const; + EXPORT void SetSlowMotionFlag(const VariantData &type); + EXPORT int32_t GetSlowMotionFlag() const; + + EXPORT void SetSlowMotionRange(const VariantData &slowMotionRange); + EXPORT std::string GetSlowMotionRange() const; + EXPORT void SetForAdd(bool forAdd); EXPORT bool GetForAdd() const; EXPORT void SetTableName(const std::string &tableName); @@ -275,6 +281,10 @@ private: int32_t burstCoverLevel_; int32_t stageVideoTaskStatus_; + + // slow motion + int32_t slowMotionFlag_ = -1; + std::string slowMotionRange_; }; } // namespace Media } // namespace OHOS diff --git a/frameworks/services/media_scanner/include/scanner/scanner_utils.h b/frameworks/services/media_scanner/include/scanner/scanner_utils.h index 4ca5c85d99..4fbbc1abdb 100644 --- a/frameworks/services/media_scanner/include/scanner/scanner_utils.h +++ b/frameworks/services/media_scanner/include/scanner/scanner_utils.h @@ -72,6 +72,7 @@ const int32_t FILE_DYNAMIC_RANGE_TYPE_DEFAULT = 0; const int32_t FILE_IS_TEMP_DEFAULT = 0; const std::string FILE_FRONT_CAMERA_DEFAULT = ""; const std::string FILE_DETAIL_TIME_DEFAULT = ""; +const std::string FILE_SLOW_MOTION_RANGE_DEFAULT = ""; const int32_t COVER = 1; const int32_t BURST_COVER_LEVEL_DEFAULT = COVER; const int32_t STAGE_VIDEO_TASK_STATUS = 0; diff --git a/frameworks/services/media_scanner/src/scanner/media_scanner_db.cpp b/frameworks/services/media_scanner/src/scanner/media_scanner_db.cpp index 474cb4e6fb..d6ae171b62 100644 --- a/frameworks/services/media_scanner/src/scanner/media_scanner_db.cpp +++ b/frameworks/services/media_scanner/src/scanner/media_scanner_db.cpp @@ -280,6 +280,10 @@ static void SetValuesFromMetaDataApi10(const Metadata &metadata, ValuesBucket &v values.PutInt(MediaColumn::MEDIA_DURATION, metadata.GetFileDuration()); values.PutLong(MediaColumn::MEDIA_DATE_TAKEN, metadata.GetDateTaken()); values.PutLong(MediaColumn::MEDIA_TIME_PENDING, 0); + if (mediaType == MEDIA_TYPE_VIDEO) { + values.PutInt(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, metadata.GetSlowMotionFlag()); + values.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, metadata.GetSlowMotionRange()); + } if (mediaType == MediaType::MEDIA_TYPE_IMAGE || mediaType == MEDIA_TYPE_VIDEO) { SetImageVideoValuesFromMetaDataApi10(metadata, values, isInsert, skipPhoto); diff --git a/frameworks/services/media_scanner/src/scanner/metadata.cpp b/frameworks/services/media_scanner/src/scanner/metadata.cpp index 925f7d6ecb..e2084eef7c 100644 --- a/frameworks/services/media_scanner/src/scanner/metadata.cpp +++ b/frameworks/services/media_scanner/src/scanner/metadata.cpp @@ -57,7 +57,8 @@ Metadata::Metadata() isTemp_(FILE_IS_TEMP_DEFAULT), frontcamera_(FILE_FRONT_CAMERA_DEFAULT), detailTime_(FILE_DETAIL_TIME_DEFAULT), burstCoverLevel_(BURST_COVER_LEVEL_DEFAULT), - stageVideoTaskStatus_(STAGE_VIDEO_TASK_STATUS) + stageVideoTaskStatus_(STAGE_VIDEO_TASK_STATUS), + slowMotionRange_(FILE_SLOW_MOTION_RANGE_DEFAULT) { Init(); } @@ -74,6 +75,10 @@ void Metadata::InitV2() &Metadata::SetAlbumId); memberFuncMap_[PhotoColumn::STAGE_VIDEO_TASK_STATUS] = make_pair(ResultSetDataType::TYPE_INT32, &Metadata::SetStageVideoTaskStatus); + memberFuncMap_[PhotoColumn::PHOTO_SLOW_MOTION_FLAG] = make_pair(ResultSetDataType::TYPE_INT32, + &Metadata::SetSlowMotionFlag); + memberFuncMap_[PhotoColumn::PHOTO_SLOW_MOTION_RANGE] = make_pair(ResultSetDataType::TYPE_STRING, + &Metadata::SetSlowMotionRange); } void Metadata::Init() @@ -633,5 +638,25 @@ int32_t Metadata::GetStageVideoTaskStatus() const { return stageVideoTaskStatus_; } + +void Metadata::SetSlowMotionFlag(const VariantData &flag) +{ + slowMotionFlag_ = std::get(flag); +} + +int32_t Metadata::GetSlowMotionFlag() const +{ + return slowMotionFlag_; +} + +void Metadata::SetSlowMotionRange(const VariantData &slowMotionRange) +{ + slowMotionRange_ = std::get(slowMotionRange); +} + +std::string Metadata::GetSlowMotionRange() const +{ + return slowMotionRange_; +} } // namespace Media } // namespace OHOS diff --git a/frameworks/services/media_scanner/src/scanner/metadata_extractor.cpp b/frameworks/services/media_scanner/src/scanner/metadata_extractor.cpp index 0864a9fc49..40bbe82499 100644 --- a/frameworks/services/media_scanner/src/scanner/metadata_extractor.cpp +++ b/frameworks/services/media_scanner/src/scanner/metadata_extractor.cpp @@ -41,6 +41,8 @@ using namespace std; const double DEGREES2MINUTES = 60.0; const double DEGREES2SECONDS = 3600.0; +const double DEFAULT_SLOW_MOTION_RANGE_RATIO_START = 0.2; +const double DEFAULT_SLOW_MOTION_RANGE_RATIO_END = 0.8; constexpr int32_t OFFSET_NUM = 2; constexpr int32_t HOURSTOSECOND = 60 * 60; constexpr int32_t MINUTESTOSECOND = 60; @@ -431,6 +433,30 @@ int32_t MetadataExtractor::ExtractImageMetadata(std::unique_ptr &data) return E_OK; } +static void FillSlowMotionMetadata(std::unique_ptr &data, const std::string &videoShootingMode, + const std::unordered_map &resultMap) +{ + if (videoShootingMode != "TypeSlowMotion") { + MEDIA_DEBUG_LOG("shoot mode type is not SlowMotion"); + data->SetSlowMotionFlag(static_cast(SlowMotionType::NORMAL)); + data->SetSlowMotionRange(""); + return; + } + + MEDIA_DEBUG_LOG("shoot mode type is SlowMotion"); + data->SetSlowMotionFlag(static_cast(SlowMotionType::SLOW_MOTION)); + if (data->GetSlowMotionRange().empty()) { + std::string durationTemp = resultMap.at(AV_KEY_DURATION); + if (!durationTemp.empty()) { + int32_t duration = stringToNum(durationTemp); + std::string slowMotionRange = + std::to_string(static_cast(duration * DEFAULT_SLOW_MOTION_RANGE_RATIO_START)) + + "," + std::to_string(static_cast(duration * DEFAULT_SLOW_MOTION_RANGE_RATIO_END)); + data->SetSlowMotionRange(slowMotionRange); + } + } +} + static std::string ExtractVideoShootingMode(const std::string &genreJson) { if (genreJson.empty()) { @@ -589,8 +615,12 @@ void PopulateExtractedAVMetadataTwo( strTemp = resultMap.at(AV_KEY_GENRE); if (!strTemp.empty()) { std::string videoShootingMode = ExtractVideoShootingMode(strTemp); + FillSlowMotionMetadata(data, videoShootingMode, resultMap); data->SetShootingModeTag(videoShootingMode); data->SetShootingMode(ShootingModeAlbum::MapShootingModeTagToShootingMode(videoShootingMode)); + } else { + data->SetSlowMotionFlag(static_cast(SlowMotionType::NORMAL)); + data->SetSlowMotionRange(""); } strTemp = resultMap.at(AV_KEY_VIDEO_IS_HDR_VIVID); const string isHdr = "yes"; diff --git a/interfaces/inner_api/media_library_helper/include/file_asset.h b/interfaces/inner_api/media_library_helper/include/file_asset.h index afa4389bd0..967eeb717f 100644 --- a/interfaces/inner_api/media_library_helper/include/file_asset.h +++ b/interfaces/inner_api/media_library_helper/include/file_asset.h @@ -177,6 +177,12 @@ public: EXPORT bool IsHidden() const; EXPORT void SetHidden(bool isHidden); + EXPORT int32_t GetSlowMotionFlag() const; + EXPORT void SetSlowMotionFlag(int32_t flag); + + EXPORT const std::string &GetSlowMotionRange() const; + EXPORT void SetSlowMotionRange(const std::string &slowMotionRange); + EXPORT void SetOpenStatus(int32_t fd, int32_t openStatus); EXPORT void RemoveOpenStatus(int32_t fd); EXPORT int32_t GetOpenStatus(int32_t fd); diff --git a/interfaces/inner_api/media_library_helper/include/media_column.h b/interfaces/inner_api/media_library_helper/include/media_column.h index ff01f282e3..dd5ab0a5c6 100644 --- a/interfaces/inner_api/media_library_helper/include/media_column.h +++ b/interfaces/inner_api/media_library_helper/include/media_column.h @@ -201,6 +201,9 @@ public: static const std::string PHOTO_HAS_CLOUD_WATERMARK EXPORT; // format in PhotoTable detail time static const std::string PHOTO_DETAIL_TIME_FORMAT EXPORT; + // slow motion + static const std::string PHOTO_SLOW_MOTION_FLAG EXPORT; + static const std::string PHOTO_SLOW_MOTION_RANGE EXPORT; // table name static const std::string PHOTOS_TABLE EXPORT; diff --git a/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h b/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h index c3e441f426..ee16d8b3ec 100644 --- a/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h +++ b/interfaces/inner_api/media_library_helper/include/medialibrary_db_const.h @@ -24,7 +24,7 @@ namespace OHOS { namespace Media { -const int32_t MEDIA_RDB_VERSION = 352; +const int32_t MEDIA_RDB_VERSION = 353; enum { VERSION_ADD_CLOUD = 2, @@ -242,6 +242,7 @@ enum { VERSION_FIX_DB_UPGRADE_TO_API20 = 350, VERSION_UPDATE_PHOTO_ALBUM_DATEMODIFIED_TIGGER = 351, VERSION_ADD_RELATIONSHIP_AND_UPDATE_TRIGGER = 352, + VERSION_ADD_SLOW_MOTION = 353, }; enum { MEDIA_API_VERSION_DEFAULT = 8, diff --git a/interfaces/inner_api/media_library_helper/include/set_slow_motion_range_uri.h b/interfaces/inner_api/media_library_helper/include/set_slow_motion_range_uri.h new file mode 100644 index 0000000000..58fa968a25 --- /dev/null +++ b/interfaces/inner_api/media_library_helper/include/set_slow_motion_range_uri.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_INNERAPI_MEDIA_LIBRARY_HELPER_INCLUDE_SET_SLOW_MOTION_RANGE_URI_H_ +#define INTERFACES_INNERAPI_MEDIA_LIBRARY_HELPER_INCLUDE_SET_SLOW_MOTION_RANGE_URI_H_ + +#include + +#include "base_data_uri.h" + +namespace OHOS { +namespace Media { +const std::string OPRN_SET_SLOW_MOTION_RANGE = "set_slow_motion_range"; +const std::string PAH_SET_SLOW_MOTION_RANGE = + MEDIALIBRARY_DATA_URI + "/"+ PAH_PHOTO + "/" + OPRN_SET_SLOW_MOTION_RANGE; +} // namespace Media +} // namespace OHOS + +#endif // INTERFACES_INNERAPI_MEDIA_LIBRARY_HELPER_INCLUDE_SET_SLOW_MOTION_RANGE_URI_H_ diff --git a/interfaces/inner_api/media_library_helper/include/userfile_manager_types.h b/interfaces/inner_api/media_library_helper/include/userfile_manager_types.h index 30c5e04c7f..313c1ac068 100644 --- a/interfaces/inner_api/media_library_helper/include/userfile_manager_types.h +++ b/interfaces/inner_api/media_library_helper/include/userfile_manager_types.h @@ -151,6 +151,12 @@ enum class DynamicRangeType : int32_t { HDR }; +enum class SlowMotionType : int32_t { + INVALID = -1, + NORMAL = 0, + SLOW_MOTION +}; + enum class MovingPhotoEffectMode : int32_t { EFFECT_MODE_START = 0, DEFAULT = EFFECT_MODE_START, diff --git a/interfaces/kits/js/include/media_asset_change_request_napi.h b/interfaces/kits/js/include/media_asset_change_request_napi.h index 08a338298e..647b43f14e 100644 --- a/interfaces/kits/js/include/media_asset_change_request_napi.h +++ b/interfaces/kits/js/include/media_asset_change_request_napi.h @@ -52,6 +52,7 @@ enum class AssetChangeOperation { DISCARD_CAMERA_PHOTO, SET_ORIENTATION, SET_SUPPORTED_WATERMARK_TYPE, + SET_SLOW_MOTION_RANGE, SET_VIDEO_ENHANCEMENT_ATTR, }; @@ -146,6 +147,7 @@ private: EXPORT static napi_value JSSetVideoEnhancementAttr(napi_env env, napi_callback_info info); EXPORT static napi_value JSDeleteLocalAssetsPermanently(napi_env env, napi_callback_info info); EXPORT static napi_value JSDeleteLocalAssetsPermanentlyWithUri(napi_env env, napi_callback_info info); + EXPORT static napi_value JSSetSlowMotionRange(napi_env env, napi_callback_info info); bool CheckChangeOperations(napi_env env); bool CheckMovingPhotoWriteOperation(); diff --git a/interfaces/kits/js/include/napi/medialibrary_napi_enum_comm.h b/interfaces/kits/js/include/napi/medialibrary_napi_enum_comm.h index b54ea60b03..94533c8be1 100644 --- a/interfaces/kits/js/include/napi/medialibrary_napi_enum_comm.h +++ b/interfaces/kits/js/include/napi/medialibrary_napi_enum_comm.h @@ -269,6 +269,8 @@ const std::vector> IMAGEVIDEOKEY_ENUM_PROPER std::make_pair("MEDIA_SUFFIX", PhotoColumn::PHOTO_MEDIA_SUFFIX), std::make_pair("IS_RECENT_SHOW", PhotoColumn::PHOTO_IS_RECENT_SHOW), std::make_pair("SUM_SIZE", MEDIA_SUM_SIZE), + std::make_pair("SLOW_MOTION_FLAG", PhotoColumn::PHOTO_SLOW_MOTION_FLAG), + std::make_pair("SLOW_MOTION_RANGE", PhotoColumn::PHOTO_SLOW_MOTION_RANGE), }; const std::vector> ALBUMKEY_ENUM_PROPERTIES = { diff --git a/services/media_cloud_sync_service/include/cloud_media_sync_const.h b/services/media_cloud_sync_service/include/cloud_media_sync_const.h index e3aa2406ce..4d0273bc81 100644 --- a/services/media_cloud_sync_service/include/cloud_media_sync_const.h +++ b/services/media_cloud_sync_service/include/cloud_media_sync_const.h @@ -208,6 +208,8 @@ const std::vector MEDIA_CLOUD_SYNC_COLUMNS = { PhotoColumn::PHOTO_SOURCE_PATH, PhotoColumn::SUPPORTED_WATERMARK_TYPE, PhotoColumn::PHOTO_STRONG_ASSOCIATION, + PhotoColumn::PHOTO_SLOW_MOTION_FLAG, + PhotoColumn::PHOTO_SLOW_MOTION_RANGE, /* keep cloud_id at the last, so RecordToValueBucket can skip it*/ MediaColumn::MEDIA_ID, PhotoColumn::PHOTO_CLOUD_ID, diff --git a/services/media_cloud_sync_service/include/dto/cloud_media_pull_data_dto.h b/services/media_cloud_sync_service/include/dto/cloud_media_pull_data_dto.h index 10452513b3..04e59d5e6a 100644 --- a/services/media_cloud_sync_service/include/dto/cloud_media_pull_data_dto.h +++ b/services/media_cloud_sync_service/include/dto/cloud_media_pull_data_dto.h @@ -64,6 +64,8 @@ public: std::string attributesShootingModeTag; /* shooting_mode_tag */ int32_t attributesDynamicRangeType{-1}; /* dynamic_range_type */ std::string attributesFrontCamera; /* front_camera */ + int32_t attributesSlowMotionFlag{-2}; /* slow_motion_flag */ + std::string attributesSlowMotionRange; /* slow_motion_Range */ int64_t attributesEditTime{-1}; /* edit_time */ int32_t attributesOriginalSubtype{-1}; /* original_subtype */ int64_t attributesCoverPosition{-1}; /* cover_position */ diff --git a/services/media_cloud_sync_service/include/po/cloud_media_photo_po.h b/services/media_cloud_sync_service/include/po/cloud_media_photo_po.h index 07d581b7de..fec5904d2e 100644 --- a/services/media_cloud_sync_service/include/po/cloud_media_photo_po.h +++ b/services/media_cloud_sync_service/include/po/cloud_media_photo_po.h @@ -79,6 +79,8 @@ public: std::string recordId; // PhotoColumn::PHOTO_CLOUD_ID std::string fileName; bool isNew; + int32_t slowMotionFlag; // PhotoColumn::PHOTO_SLOW_MOTION_FLAG + std::string slowMotionRange; // PhotoColumn::PHOTO_SLOW_MOTION_RANGE /* keep cloud_id at the last; so RecordToValueBucket can skip it*/ int32_t fileId; // MediaColumn::MEDIA_ID; diff --git a/services/media_cloud_sync_service/include/po/cloud_media_pull_data.h b/services/media_cloud_sync_service/include/po/cloud_media_pull_data.h index c9f91a8f60..f69cb896bd 100644 --- a/services/media_cloud_sync_service/include/po/cloud_media_pull_data.h +++ b/services/media_cloud_sync_service/include/po/cloud_media_pull_data.h @@ -79,6 +79,8 @@ public: std::string recordId; // PhotoColumn::PHOTO_CLOUD_ID std::string fileName; bool isNew; + int32_t slowMotionFlag; // PhotoColumn::PHOTO_SLOW_MOTION_FLAG + std::string slowMotionRange; // PhotoColumn::PHOTO_SLOW_MOTION_RANGE /* keep cloud_id at the last; so RecordToValueBucket can skip it*/ int32_t fileId; // MediaColumn::MEDIA_ID; diff --git a/services/media_cloud_sync_service/include/utils/cloud_sync_convert.h b/services/media_cloud_sync_service/include/utils/cloud_sync_convert.h index 6184c00487..b313d708c5 100644 --- a/services/media_cloud_sync_service/include/utils/cloud_sync_convert.h +++ b/services/media_cloud_sync_service/include/utils/cloud_sync_convert.h @@ -49,6 +49,8 @@ public: static int32_t CompensateAttShootingModeTag(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); static int32_t CompensateAttDynamicRangeType(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); static int32_t CompensateAttFrontCamera(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); + static int32_t CompensateAttSlowMotionFlag(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); + static int32_t CompensateAttSlowMotionRange(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); static int32_t CompensateAttEditTime(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); static int32_t CompensateAttOriginalSubtype(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); static int32_t CompensateAttCoverPosition(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values); diff --git a/services/media_cloud_sync_service/include/vo/cloud_mdkrecord_photos_vo.h b/services/media_cloud_sync_service/include/vo/cloud_mdkrecord_photos_vo.h index 49d8c00c85..c2342032f5 100644 --- a/services/media_cloud_sync_service/include/vo/cloud_mdkrecord_photos_vo.h +++ b/services/media_cloud_sync_service/include/vo/cloud_mdkrecord_photos_vo.h @@ -45,6 +45,8 @@ public: std::string shootingModeTag; int32_t dynamicRangeType; std::string frontCamera; + int32_t slowMotionFlag; + std::string slowMotionRange; int64_t editTime; int32_t originalSubtype; int64_t coverPosition; diff --git a/services/media_cloud_sync_service/include/vo/on_fetch_photos_vo.h b/services/media_cloud_sync_service/include/vo/on_fetch_photos_vo.h index 71ce5feb9c..9685e92597 100644 --- a/services/media_cloud_sync_service/include/vo/on_fetch_photos_vo.h +++ b/services/media_cloud_sync_service/include/vo/on_fetch_photos_vo.h @@ -35,6 +35,7 @@ public: std::string firstVisitTime; // MDKRecord first_update_time std::string detailTime; std::string frontCamera; + std::string slowMotionRange; std::string editDataCamera; std::string title; std::string relativePath; @@ -62,6 +63,7 @@ public: int32_t subtype; int32_t originalSubtype; int32_t dynamicRangeType; + int32_t slowMotionFlag; int32_t movingPhotoEffectMode; int32_t supportedWatermarkType; int32_t strongAssociation; diff --git a/services/media_cloud_sync_service/src/controller/processor/cloud_media_photo_controller_processor.cpp b/services/media_cloud_sync_service/src/controller/processor/cloud_media_photo_controller_processor.cpp index 317418f153..a1a76514f3 100644 --- a/services/media_cloud_sync_service/src/controller/processor/cloud_media_photo_controller_processor.cpp +++ b/services/media_cloud_sync_service/src/controller/processor/cloud_media_photo_controller_processor.cpp @@ -141,6 +141,8 @@ bool CloudMediaPhotoControllerProcessor::GetAttributesInfo(const PhotosPo &recor photosVo.shootingModeTag = record.shootingModeTag.value_or(""); photosVo.dynamicRangeType = record.dynamicRangeType.value_or(0); photosVo.frontCamera = record.frontCamera.value_or(""); + photosVo.slowMotionFlag = record.slowMotionFlag.value_or(-1); + photosVo.slowMotionRange = record.slowMotionRange.value_or(""); photosVo.originalSubtype = record.originalSubtype.value_or(0); photosVo.coverPosition = record.coverPosition.value_or(0); photosVo.isRectificationCover = record.isRectificationCover.value_or(0); @@ -238,6 +240,8 @@ bool CloudMediaPhotoControllerProcessor::GetAttributesInfo(const OnFetchPhotosVo data.attributesOriginalSubtype = photosVo.originalSubtype; data.attributesDynamicRangeType = photosVo.dynamicRangeType; data.attributesFrontCamera = photosVo.frontCamera; + data.attributesSlowMotionFlag = photosVo.slowMotionFlag; + data.attributesSlowMotionRange = photosVo.slowMotionRange; data.attributesMovingPhotoEffectMode = photosVo.movingPhotoEffectMode; data.attributesCoverPosition = photosVo.coverPosition; data.attributesIsRectificationCover = photosVo.isRectificationCover; diff --git a/services/media_cloud_sync_service/src/dto/cloud_media_pull_data_dto.cpp b/services/media_cloud_sync_service/src/dto/cloud_media_pull_data_dto.cpp index baed611b2f..e109e9aff0 100644 --- a/services/media_cloud_sync_service/src/dto/cloud_media_pull_data_dto.cpp +++ b/services/media_cloud_sync_service/src/dto/cloud_media_pull_data_dto.cpp @@ -57,6 +57,8 @@ void CloudMediaPullDataDto::GetAttributesInfo(std::stringstream &ss) const << "\"attributesShootingModeTag\": \"" << attributesShootingModeTag << "\"," << "\"attributesDynamicRangeType\": " << attributesDynamicRangeType << "," << "\"attributesFrontCamera\": " << attributesFrontCamera << "," + << "\"attributesSlowMotionFlag\": " << attributesSlowMotionFlag << "," + << "\"attributesSlowMotionRange\": " << attributesSlowMotionRange << "," << "\"attributesEditTime\": " << attributesEditTime << "," << "\"attributesOriginalSubtype\": " << attributesOriginalSubtype << "," << "\"attributesCoverPosition\": " << attributesCoverPosition << "," diff --git a/services/media_cloud_sync_service/src/utils/cloud_sync_convert.cpp b/services/media_cloud_sync_service/src/utils/cloud_sync_convert.cpp index df9d69f1f7..695ca66215 100644 --- a/services/media_cloud_sync_service/src/utils/cloud_sync_convert.cpp +++ b/services/media_cloud_sync_service/src/utils/cloud_sync_convert.cpp @@ -204,6 +204,26 @@ int32_t CloudSyncConvert::CompensateAttFrontCamera(const CloudMediaPullDataDto & return E_OK; } +int32_t CloudSyncConvert::CompensateAttSlowMotionFlag( + const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values) +{ + int32_t slowMotionFlag = data.attributesSlowMotionFlag; + CHECK_AND_RETURN_RET_WARN_LOG( + slowMotionFlag != -2, E_CLOUDSYNC_INVAL_ARG, "Cannot find attributes::slowMotionFlag."); + values.PutInt(PhotoColumn::PHOTO_SLOW_MOTION_FLAG, slowMotionFlag); + return E_OK; +} + +int32_t CloudSyncConvert::CompensateAttSlowMotionRange( + const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values) +{ + std::string slowMotionRange = data.attributesSlowMotionRange; + CHECK_AND_RETURN_RET_WARN_LOG(!slowMotionRange.empty(), E_CLOUDSYNC_INVAL_ARG, + "Cannot find attributes::slowMotionRange."); + values.PutString(PhotoColumn::PHOTO_SLOW_MOTION_RANGE, slowMotionRange); + return E_OK; +} + int32_t CloudSyncConvert::CompensateAttEditTime(const CloudMediaPullDataDto &data, NativeRdb::ValuesBucket &values) { int64_t editTime = data.attributesEditTime; @@ -579,6 +599,8 @@ int32_t CloudSyncConvert::ExtractAttributeValue(const CloudMediaPullDataDto &dat CompensateAttShootingModeTag(data, values); CompensateAttDynamicRangeType(data, values); CompensateAttFrontCamera(data, values); + CompensateAttSlowMotionFlag(data, values); + CompensateAttSlowMotionRange(data, values); CompensateAttEditTime(data, values); CompensateAttOriginalSubtype(data, values); CompensateAttCoverPosition(data, values); diff --git a/services/media_cloud_sync_service/src/vo/cloud_mdkrecord_photos_vo.cpp b/services/media_cloud_sync_service/src/vo/cloud_mdkrecord_photos_vo.cpp index d15c8ae152..a97785814e 100644 --- a/services/media_cloud_sync_service/src/vo/cloud_mdkrecord_photos_vo.cpp +++ b/services/media_cloud_sync_service/src/vo/cloud_mdkrecord_photos_vo.cpp @@ -43,6 +43,8 @@ bool CloudMdkRecordPhotosVo::MarshallingBasicInfo(Parcel &parcel) const parcel.WriteString(shootingModeTag); parcel.WriteInt32(dynamicRangeType); parcel.WriteString(frontCamera); + parcel.WriteInt32(slowMotionFlag); + parcel.WriteString(slowMotionRange); parcel.WriteInt64(editTime); parcel.WriteInt32(originalSubtype); // parcel.WriteInt64(coverPosition); @@ -105,6 +107,8 @@ bool CloudMdkRecordPhotosVo::ReadBasicInfo(Parcel &parcel) parcel.ReadString(shootingModeTag); parcel.ReadInt32(dynamicRangeType); parcel.ReadString(frontCamera); + parcel.ReadInt32(slowMotionFlag); + parcel.ReadString(slowMotionRange); parcel.ReadInt64(editTime); parcel.ReadInt32(originalSubtype); parcel.ReadInt64(coverPosition); @@ -219,6 +223,8 @@ void CloudMdkRecordPhotosVo::GetAttributesInfo(std::stringstream &ss) const << "\"shootingModeTag\": \"" << shootingModeTag << "\"," << "\"dynamicRangeType\": " << dynamicRangeType << "," << "\"frontCamera\": \"" << frontCamera << "\"," + << "\"slowMotionFlag\": " << slowMotionFlag << "," + << "\"slowMotionRange\": \"" << slowMotionRange << "\"," << "\"coverPosition\": " << coverPosition << "," << "\"isRectificationCover\": " << isRectificationCover << "," << "\"exifRotate\": " << exifRotate << "," diff --git a/services/media_cloud_sync_service/src/vo/on_fetch_photos_vo.cpp b/services/media_cloud_sync_service/src/vo/on_fetch_photos_vo.cpp index 974a46b826..2f26c94912 100644 --- a/services/media_cloud_sync_service/src/vo/on_fetch_photos_vo.cpp +++ b/services/media_cloud_sync_service/src/vo/on_fetch_photos_vo.cpp @@ -31,6 +31,7 @@ bool OnFetchPhotosVo::MarshallingBasicInfo(Parcel &parcel) const parcel.WriteString(this->firstVisitTime); parcel.WriteString(this->detailTime); parcel.WriteString(this->frontCamera); + parcel.WriteString(this->slowMotionRange); parcel.WriteString(this->editDataCamera); parcel.WriteString(this->title); parcel.WriteString(this->relativePath); @@ -63,6 +64,7 @@ bool OnFetchPhotosVo::MarshallingAttributesInfo(Parcel &parcel) const parcel.WriteInt32(this->subtype); parcel.WriteInt32(this->originalSubtype); parcel.WriteInt32(this->dynamicRangeType); + parcel.WriteInt32(this->slowMotionFlag); parcel.WriteInt32(this->movingPhotoEffectMode); parcel.WriteInt32(this->supportedWatermarkType); parcel.WriteInt32(this->strongAssociation); @@ -94,6 +96,7 @@ bool OnFetchPhotosVo::ReadBasicInfo(Parcel &parcel) parcel.ReadString(this->firstVisitTime); parcel.ReadString(this->detailTime); parcel.ReadString(this->frontCamera); + parcel.ReadString(this->slowMotionRange); parcel.ReadString(this->editDataCamera); parcel.ReadString(this->title); parcel.ReadString(this->relativePath); @@ -126,6 +129,7 @@ bool OnFetchPhotosVo::ReadAttributesInfo(Parcel &parcel) parcel.ReadInt32(this->subtype); parcel.ReadInt32(this->originalSubtype); parcel.ReadInt32(this->dynamicRangeType); + parcel.ReadInt32(this->slowMotionFlag); parcel.ReadInt32(this->movingPhotoEffectMode); parcel.ReadInt32(this->supportedWatermarkType); parcel.ReadInt32(this->strongAssociation); @@ -179,6 +183,7 @@ void OnFetchPhotosVo::GetBasicInfo(std::stringstream &ss) const << "\"firstVisitTime\": \"" << firstVisitTime << "\"," << "\"detailTime\": \"" << detailTime << "\"," << "\"frontCamera\": \"" << frontCamera << "\"," + << "\"slowMotionRange\": \"" << slowMotionRange << "\"," << "\"editDataCamera\": \"" << editDataCamera << "\"," << "\"relativePath\": \"" << relativePath << "\"," << "\"virtualPath\": \"" << virtualPath << "\"," @@ -206,6 +211,7 @@ void OnFetchPhotosVo::GetAttributesInfo(std::stringstream &ss) const << "\"subtype\": \"" << subtype << "\"," << "\"originalSubtype\": \"" << originalSubtype << "\"," << "\"dynamicRangeType\": \"" << dynamicRangeType << "\"," + << "\"slowMotionFlag\": \"" << slowMotionFlag << "\"," << "\"movingPhotoEffectMode\": \"" << movingPhotoEffectMode << "\"," << "\"version\": \"" << version << "\"," << "\"size\": \"" << size << "\"," -- Gitee