diff --git a/frameworks/js/avrecorder/avrecorder_napi.cpp b/frameworks/js/avrecorder/avrecorder_napi.cpp index 2cbec543dee39f202452521dc5a286df865ad07a..8d247d99aaeecece715473d74875a9f4fdcaf0e9 100644 --- a/frameworks/js/avrecorder/avrecorder_napi.cpp +++ b/frameworks/js/avrecorder/avrecorder_napi.cpp @@ -71,6 +71,7 @@ napi_value AVRecorderNapi::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("SetOrientationHint", JsSetOrientationHint), DECLARE_NAPI_FUNCTION("updateRotation", JsSetOrientationHint), DECLARE_NAPI_FUNCTION("getInputSurface", JsGetInputSurface), + DECLARE_NAPI_FUNCTION("getInputMetaSurface", JsGetInputMetaSurface), DECLARE_NAPI_FUNCTION("start", JsStart), DECLARE_NAPI_FUNCTION("pause", JsPause), DECLARE_NAPI_FUNCTION("resume", JsResume), @@ -434,6 +435,59 @@ napi_value AVRecorderNapi::JsGetInputSurface(napi_env env, napi_callback_info in return ExecuteByPromise(env, info, AVRecordergOpt::GETINPUTSURFACE); } +napi_value AVRecorderNapi::JsGetInputMetaSurface(napi_env env, napi_callback_info info) +{ + MediaTrace trace("AVRecorder::JsGetInputMetaSurface"); + const std::string &opt = AVRecordergOpt::GETINPUTMETASURFACE; + MEDIA_LOGI("Js %{public}s Start", opt.c_str()); + + napi_value args[1] = { nullptr }; + size_t argCount = 1; + + napi_value result = nullptr; + napi_get_undefined(env, &result); + + auto asyncCtx = std::make_unique(env); + CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get AsyncContext"); + asyncCtx->napi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args); + CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs"); + CHECK_AND_RETURN_RET_LOG(asyncCtx->napi->taskQue_ != nullptr, result, "taskQue is nullptr!"); + + asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[0]); + asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result); + + if (asyncCtx->napi->CheckStateMachine(opt) == MSERR_OK) { + if (asyncCtx->napi->GetMetaType(asyncCtx, env, args[0]) == MSERR_OK) { + asyncCtx->task_ = AVRecorderNapi::GetInputMetaSurface(asyncCtx); + (void)asyncCtx->napi->taskQue_->EnqueueTask(asyncCtx->task_); + } + } else { + asyncCtx->AVRecorderSignError(MSERR_INVALID_OPERATION, opt, ""); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, opt.c_str(), NAPI_AUTO_LENGTH, &resource); + NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) { + AVRecorderAsyncContext* asyncCtx = reinterpret_cast(data); + CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!"); + + if (asyncCtx->task_) { + auto result = asyncCtx->task_->GetResult(); + if (result.Value().first != MSERR_EXT_API9_OK) { + asyncCtx->SignError(result.Value().first, result.Value().second); + } else { + asyncCtx->JsResult = std::make_unique(result.Value().second); + } + } + MEDIA_LOGI("The js thread of getInputMetaSurface finishes execution and returns"); + }, MediaAsyncContext::CompleteCallback, static_cast(asyncCtx.get()), &asyncCtx->work)); + NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated)); + asyncCtx.release(); + + MEDIA_LOGI("Js %{public}s End", opt.c_str()); + return result; +} + napi_value AVRecorderNapi::JsStart(napi_env env, napi_callback_info info) { MediaTrace trace("AVRecorder::JsStart"); @@ -1277,6 +1331,41 @@ RetInfo AVRecorderNapi::GetInputSurface() return RetInfo(MSERR_EXT_API9_OK, surfaceId); } +std::shared_ptr> AVRecorderNapi::GetInputMetaSurface( + const std::unique_ptr &asyncCtx) +{ + return std::make_shared>( + [napi = asyncCtx->napi, config = asyncCtx->config_, type = asyncCtx->metaType_]() { + const std::string &option = AVRecordergOpt::GETINPUTMETASURFACE; + MEDIA_LOGI("%{public}s Start", option.c_str()); + CHECK_AND_RETURN_RET(napi != nullptr && napi->recorder_ != nullptr && config != nullptr, + GetRetInfo(MSERR_INVALID_OPERATION, option, "")); + + CHECK_AND_RETURN_RET(napi->CheckStateMachine(option) == MSERR_OK, + GetRetInfo(MSERR_INVALID_OPERATION, option, "")); + CHECK_AND_RETURN_RET_LOG(napi->metaSourceIDMap_.find(type) != napi->metaSourceIDMap_.end(), + GetRetInfo(MSERR_INVALID_OPERATION, "GetInputMetaSurface", "no meta source type"), + "failed to find meta type"); + if (napi->metaSurface_ == nullptr) { + MEDIA_LOGI("The meta source type is %{public}d", static_cast(type)); + napi->metaSurface_ = napi->recorder_->GetMetaSurface(napi->metaSourceIDMap_.at(type)); + CHECK_AND_RETURN_RET_LOG(napi->metaSurface_ != nullptr, + GetRetInfo(MSERR_INVALID_OPERATION, "GetInputMetaSurface", ""), "failed to GetInputMetaSurface"); + + SurfaceError error = + SurfaceUtils::GetInstance()->Add(napi->metaSurface_->GetUniqueId(), napi->metaSurface_); + CHECK_AND_RETURN_RET_LOG(error == SURFACE_ERROR_OK, + GetRetInfo(MSERR_INVALID_OPERATION, "GetInputMetaSurface", "add surface failed"), + "failed to AddSurface"); + } + + auto surfaceId = std::to_string(napi->metaSurface_->GetUniqueId()); + MEDIA_LOGI("surfaceId:%{public}s", surfaceId.c_str()); + MEDIA_LOGI("%{public}s End", option.c_str()); + return RetInfo(MSERR_EXT_API9_OK, surfaceId); + }); +} + RetInfo AVRecorderNapi::Start() { if (withVideo_ && !getVideoInputSurface_) { @@ -1594,6 +1683,7 @@ int32_t AVRecorderNapi::GetSourceType(std::unique_ptr &a std::shared_ptr config = asyncCtx->config_; int32_t audioSource = AUDIO_SOURCE_INVALID; int32_t videoSource = VIDEO_SOURCE_BUTT; + std::vector metaSource {}; bool getValue = false; int32_t ret = AVRecorderNapi::GetPropertyInt32(env, args, "audioSourceType", audioSource, getValue); @@ -1614,6 +1704,15 @@ int32_t AVRecorderNapi::GetSourceType(std::unique_ptr &a MEDIA_LOGI("videoSource Type %{public}d!", videoSource); } + ret = AVRecorderNapi::GetPropertyInt32Vec(env, args, "metaSourceTypes", metaSource, getValue); + CHECK_AND_RETURN_RET(ret == MSERR_OK, + (asyncCtx->AVRecorderSignError(ret, "getMetaSourceTypes", "metaSourceTypes"), ret)); + if (getValue) { + for (auto item : metaSource) { + config->metaSourceTypeVec.push_back(static_cast(item)); + } + } + CHECK_AND_RETURN_RET(config->withAudio || config->withVideo, (asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "getsourcetype", "SourceType"), MSERR_INVALID_VAL)); @@ -1796,6 +1895,31 @@ int32_t AVRecorderNapi::GetRotation(std::unique_ptr &asy return MSERR_OK; } +int32_t AVRecorderNapi::GetMetaType(std::unique_ptr &asyncCtx, napi_env env, napi_value args) +{ + napi_valuetype valueType = napi_undefined; + if (args == nullptr || napi_typeof(env, args, &valueType) != napi_ok || + (valueType != napi_object && valueType != napi_number)) { + asyncCtx->AVRecorderSignError(MSERR_INCORRECT_PARAMETER_TYPE, "GetConfig", "AVRecorderConfig", + "meta type should be number."); + return MSERR_INCORRECT_PARAMETER_TYPE; + } + + asyncCtx->config_ = std::make_shared(); + CHECK_AND_RETURN_RET(asyncCtx->config_, + (asyncCtx->AVRecorderSignError(MSERR_NO_MEMORY, "AVRecorderConfig", "AVRecorderConfig"), MSERR_NO_MEMORY)); + + int32_t metaSourceType = VIDEO_META_SOURCE_INVALID; + if (napi_get_value_int32(env, args, &metaSourceType) != napi_ok) { + std::string string = CommonNapi::GetStringArgument(env, args); + CHECK_AND_RETURN_RET(string == "", + (asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "getMetaType", "metaSourceType"), MSERR_INVALID_VAL)); + } + asyncCtx->metaType_ = static_cast(metaSourceType); + MEDIA_LOGI("metaSource Type %{public}d!", metaSourceType); + return MSERR_OK; +} + int32_t AVRecorderNapi::GetAVMetaData(std::unique_ptr &asyncCtx, napi_env env, napi_value args) { @@ -1945,6 +2069,13 @@ RetInfo AVRecorderNapi::SetProfile(std::shared_ptr config) CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoEnableTemporalScale", "enableTemporalScale")); } + if (config->metaSourceTypeVec.size() != 0 && + std::find(config->metaSourceTypeVec.cbegin(), config->metaSourceTypeVec.cend(), + MetaSourceType::VIDEO_META_MAKER_INFO) != config->metaSourceTypeVec.cend()) { + ret = recorder_->SetMetaConfigs(metaSourceID_); + CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetMetaConfigs", "metaSourceType")); + } + return RetInfo(MSERR_EXT_API9_OK, ""); } @@ -1969,6 +2100,14 @@ RetInfo AVRecorderNapi::Configure(std::shared_ptr config) CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoSource", "videoSourceType")); } + if (config->metaSourceTypeVec.size() != 0 && + std::find(config->metaSourceTypeVec.cbegin(), config->metaSourceTypeVec.cend(), + MetaSourceType::VIDEO_META_MAKER_INFO) != config->metaSourceTypeVec.cend()) { + ret = recorder_->SetMetaSource(MetaSourceType::VIDEO_META_MAKER_INFO, metaSourceID_); + CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetMetaSource", "metaSourceType")); + metaSourceIDMap_.emplace(std::make_pair(MetaSourceType::VIDEO_META_MAKER_INFO, metaSourceID_)); + } + RetInfo retInfo = SetProfile(config); CHECK_AND_RETURN_RET_LOG(retInfo.first == MSERR_OK, retInfo, "Fail to set videoBitrate"); @@ -2140,6 +2279,49 @@ int32_t AVRecorderNapi::GetPropertyInt32(napi_env env, napi_value configObj, con return MSERR_OK; } +int32_t AVRecorderNapi::GetPropertyInt32Vec(napi_env env, napi_value configObj, const std::string &type, + std::vector &result, bool &getValue) +{ + napi_value item = nullptr; + bool exist = false; + getValue = false; + napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist); + if (status != napi_ok || !exist) { + MEDIA_LOGI("can not find %{public}s property", type.c_str()); + return MSERR_OK; + } + + if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) { + MEDIA_LOGI("get %{public}s property fail", type.c_str()); + return MSERR_UNKNOWN; + } + bool isArray = false; + status = napi_is_array(env, item, &isArray); + if (status != napi_ok || !isArray) { + MEDIA_LOGE("get property fail: not array"); + } + uint32_t arrayLen = 0; + napi_get_array_length(env, item, &arrayLen); + for (uint32_t i = 0; i < arrayLen; i++) { + napi_value element = nullptr; + napi_get_element(env, item, i, &element); + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, element, &valueType); + if (valueType != napi_number) { + MEDIA_LOGE("get int32 vector failed, not number!"); + return MSERR_UNKNOWN; + } + + int32_t int32Value = 0; + napi_get_value_int32(env, element, &int32Value); + result.push_back(int32Value); + } + + getValue = true; + return MSERR_OK; +} + napi_status MediaJsAVRecorderProfile::GetJsResult(napi_env env, napi_value &result) { napi_status ret = napi_ok; diff --git a/frameworks/js/avrecorder/avrecorder_napi.h b/frameworks/js/avrecorder/avrecorder_napi.h index 9814915634a06ef98211d0850e243c009ed02c19..4ce7c69df52c916d18dbd24c47e5458fff5fa123 100644 --- a/frameworks/js/avrecorder/avrecorder_napi.h +++ b/frameworks/js/avrecorder/avrecorder_napi.h @@ -44,6 +44,7 @@ namespace AVRecordergOpt { const std::string PREPARE = "Prepare"; const std::string SET_ORIENTATION_HINT = "SetOrientationHint"; const std::string GETINPUTSURFACE = "GetInputSurface"; +const std::string GETINPUTMETASURFACE = "GetInputMetaSurface"; const std::string START = "Start"; const std::string PAUSE = "Pause"; const std::string RESUME = "Resume"; @@ -80,6 +81,7 @@ const std::map> stateCtrlList = { {AVRecorderState::STATE_PREPARED, { AVRecordergOpt::SET_ORIENTATION_HINT, AVRecordergOpt::GETINPUTSURFACE, + AVRecordergOpt::GETINPUTMETASURFACE, AVRecordergOpt::START, AVRecordergOpt::RESET, AVRecordergOpt::RELEASE, @@ -164,6 +166,7 @@ struct AVRecorderProfile { struct AVRecorderConfig { AudioSourceType audioSourceType; // source type; VideoSourceType videoSourceType; + std::vector metaSourceTypeVec; AVRecorderProfile profile; std::string url; int32_t rotation = 0; // Optional @@ -214,6 +217,11 @@ private: * getInputSurface(): Promise */ static napi_value JsGetInputSurface(napi_env env, napi_callback_info info); + /** + * getInputMetaSurface(callback: AsyncCallback): void + * getInputMetaSurface(): Promise + */ + static napi_value JsGetInputMetaSurface(napi_env env, napi_callback_info info); /** * start(callback: AsyncCallback): void; * start(): Promise; @@ -301,6 +309,8 @@ private: static std::shared_ptr> GetPrepareTask(std::unique_ptr &asyncCtx); static std::shared_ptr> GetSetOrientationHintTask( const std::unique_ptr &asyncCtx); + static std::shared_ptr> GetInputMetaSurface( + const std::unique_ptr &asyncCtx); static std::shared_ptr> GetPromiseTask(AVRecorderNapi *avnapi, const std::string &opt); static std::shared_ptr> GetAVRecorderProfileTask( const std::unique_ptr &asyncCtx); @@ -325,6 +335,8 @@ private: static int32_t GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result, bool &getValue); + static int32_t GetPropertyInt32Vec(napi_env env, napi_value configObj, const std::string &type, + std::vector &result, bool &getValue); static int32_t GetAVRecorderProfile(std::shared_ptr &profile, const int32_t sourceId, const int32_t qualityLevel); @@ -366,6 +378,7 @@ private: int32_t GetProfile(std::unique_ptr &asyncCtx, napi_env env, napi_value args); int32_t GetConfig(std::unique_ptr &asyncCtx, napi_env env, napi_value args); int32_t GetRotation(std::unique_ptr &asyncCtx, napi_env env, napi_value args); + int32_t GetMetaType(std::unique_ptr &asyncCtx, napi_env env, napi_value args); int32_t GetAVMetaData(std::unique_ptr &asyncCtx, napi_env env, napi_value args); int32_t GetWatermarkParameter(std::unique_ptr &asyncCtx, napi_env env, napi_value *args); int32_t GetWatermark(std::unique_ptr &asyncCtx, napi_env env, napi_value args); @@ -386,11 +399,15 @@ private: std::map> eventCbMap_; std::unique_ptr taskQue_; static std::map taskQFuncs_; + std::map metaSourceIDMap_; sptr surface_ = nullptr; + sptr metaSurface_ = nullptr; int32_t videoSourceID_ = -1; int32_t audioSourceID_ = -1; + int32_t metaSourceID_ = -1; bool withVideo_ = false; bool getVideoInputSurface_ = false; + bool getMetaInputSurface_ = false; int32_t sourceId_ = -1; int32_t qualityLevel_ = -1; bool hasConfiged_ = false; @@ -414,6 +431,7 @@ struct AVRecorderAsyncContext : public MediaAsyncContext { AudioRecorderChangeInfo changeInfo_; int32_t maxAmplitude_ = 0; std::vector encoderInfo_; + MetaSourceType metaType_ = MetaSourceType::VIDEO_META_SOURCE_INVALID; std::shared_ptr pixelMap_ = nullptr; std::shared_ptr watermarkConfig_ = nullptr; bool isWatermarkSupported_ = false; diff --git a/frameworks/native/recorder/recorder_impl.cpp b/frameworks/native/recorder/recorder_impl.cpp index 6ea90c9fdf59eac4773b636935206a875405a32e..8f1451e30020afa65bd9515755fa42332417570e 100644 --- a/frameworks/native/recorder/recorder_impl.cpp +++ b/frameworks/native/recorder/recorder_impl.cpp @@ -145,6 +145,15 @@ sptr RecorderImpl::GetSurface(int32_t sourceId) return surface_; } +sptr RecorderImpl::GetMetaSurface(int32_t sourceId) +{ + MEDIA_LOGI("RecorderImpl:0x%{public}06" PRIXPTR " GetMetaSurface in, sourceId is %{public}d", + FAKE_POINTER(this), sourceId); + CHECK_AND_RETURN_RET_LOG(recorderService_ != nullptr, nullptr, "recorder service does not exist.."); + metaSurface_ = recorderService_->GetMetaSurface(sourceId); + return metaSurface_; +} + int32_t RecorderImpl::SetAudioSource(AudioSourceType source, int32_t &sourceId) { MEDIA_LOGI("RecorderImpl:0x%{public}06" PRIXPTR " SetAudioSource in, source is %{public}d, sourceId is %{public}d", @@ -185,6 +194,22 @@ int32_t RecorderImpl::SetAudioEncodingBitRate(int32_t sourceId, int32_t bitRate) return recorderService_->SetAudioEncodingBitRate(sourceId, bitRate); } +int32_t RecorderImpl::SetMetaSource(MetaSourceType source, int32_t &sourceId) +{ + MEDIA_LOGI("RecorderImpl:0x%{public}06" PRIXPTR " SetMetaSource in, source is %{public}d, sourceId is %{public}d", + FAKE_POINTER(this), source, sourceId); + CHECK_AND_RETURN_RET_LOG(recorderService_ != nullptr, MSERR_INVALID_OPERATION, "recorder service does not exist.."); + return recorderService_->SetMetaSource(source, sourceId); +} + +int32_t RecorderImpl::SetMetaConfigs(int32_t sourceId) +{ + MEDIA_LOGI("RecorderImpl:0x%{public}06" PRIXPTR " SetMetaConfigs in, sourceId is %{public}d", + FAKE_POINTER(this), sourceId); + CHECK_AND_RETURN_RET_LOG(recorderService_ != nullptr, MSERR_INVALID_OPERATION, "recorder service does not exist.."); + return recorderService_->SetMetaConfigs(sourceId); +} + int32_t RecorderImpl::SetDataSource(DataSourceType dataType, int32_t &sourceId) { CHECK_AND_RETURN_RET_LOG(recorderService_ != nullptr, MSERR_INVALID_OPERATION, "recorder service does not exist.."); diff --git a/frameworks/native/recorder/recorder_impl.h b/frameworks/native/recorder/recorder_impl.h index 69a15678184428ae08045d60a09f0057f7ffbc67..06c0d832e4860c3555d50362db3ad637ad23710e 100644 --- a/frameworks/native/recorder/recorder_impl.h +++ b/frameworks/native/recorder/recorder_impl.h @@ -38,11 +38,14 @@ public: int32_t SetVideoEnableTemporalScale(int32_t sourceId, bool enableTemporalScale) override; int32_t SetCaptureRate(int32_t sourceId, double fps) override; sptr GetSurface(int32_t sourceId) override; + sptr GetMetaSurface(int32_t sourceId) override; int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) override; int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) override; int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate) override; int32_t SetAudioChannels(int32_t sourceId, int32_t num) override; int32_t SetAudioEncodingBitRate(int32_t sourceId, int32_t bitRate) override; + int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) override; + int32_t SetMetaConfigs(int32_t sourceId) override; int32_t SetDataSource(DataSourceType dataType, int32_t &sourceId) override; int32_t SetUserCustomInfo(Meta &userCustomInfo) override; int32_t SetGenre(std::string &genre) override; @@ -74,6 +77,7 @@ public: private: std::shared_ptr recorderService_ = nullptr; sptr surface_ = nullptr; + sptr metaSurface_ = nullptr; HiTraceId traceId_; }; } // namespace Media diff --git a/frameworks/native/recorder/test/unittest/include/recorder_mock.h b/frameworks/native/recorder/test/unittest/include/recorder_mock.h index 6a5111d209cc67a2e5f552ec6964e42db5653c99..e54c2cf417de12cddcbb95cdd4d7c5f02f134933 100644 --- a/frameworks/native/recorder/test/unittest/include/recorder_mock.h +++ b/frameworks/native/recorder/test/unittest/include/recorder_mock.h @@ -82,6 +82,7 @@ namespace RecorderTestParam { struct VideoRecorderConfig { int32_t audioSourceId = 0; int32_t videoSourceId = 0; + int32_t metaSourceId = 0; int32_t audioEncodingBitRate = 48000; int32_t channelCount = 2; int32_t duration = 60; @@ -97,6 +98,7 @@ namespace RecorderTestParam { OutputFormatType outPutFormat = FORMAT_MPEG_4; VideoSourceType vSource = VIDEO_SOURCE_SURFACE_ES; VideoCodecFormat videoFormat = H264; + MetaSourceType metaSourceType = MetaSourceType::VIDEO_META_SOURCE_INVALID; bool enableTemporalScale = false; float latitude = 30.0; float longitude = 60.0; @@ -129,6 +131,7 @@ public: int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate); int32_t SetCaptureRate(int32_t sourceId, double fps); OHOS::sptr GetSurface(int32_t sourceId); + OHOS::sptr GetMetaSurface(int32_t sourceId); int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder); int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate); int32_t SetAudioChannels(int32_t sourceId, int32_t num); @@ -165,6 +168,8 @@ public: int32_t GetCurrentCapturerChangeInfo(AudioRecorderChangeInfo &changeInfo); private: + int32_t SetAudVidFormat( + const std::string &recorderType, RecorderTestParam::VideoRecorderConfig &recorderConfig) const; std::shared_ptr recorder_ = nullptr; OHOS::sptr producerSurface_ = nullptr; std::shared_ptr file_ = nullptr; diff --git a/frameworks/native/recorder/test/unittest/src/recorder_mock.cpp b/frameworks/native/recorder/test/unittest/src/recorder_mock.cpp index e345d4126c533d1a4e6e9274d3bae522f5e66ea5..93a112cce218981eeaabc6b8170d8b7f9acef13a 100644 --- a/frameworks/native/recorder/test/unittest/src/recorder_mock.cpp +++ b/frameworks/native/recorder/test/unittest/src/recorder_mock.cpp @@ -160,6 +160,12 @@ OHOS::sptr RecorderMock::GetSurface(int32_t sourceId) return recorder_->GetSurface(sourceId); } +OHOS::sptr RecorderMock::GetMetaSurface(int32_t sourceId) +{ + UNITTEST_CHECK_AND_RETURN_RET_LOG(recorder_ != nullptr, nullptr, "recorder_ == nullptr"); + return recorder_->GetMetaSurface(sourceId); +} + int32_t RecorderMock::SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) { UNITTEST_CHECK_AND_RETURN_RET_LOG(recorder_ != nullptr, MSERR_INVALID_OPERATION, "recorder_ == nullptr"); @@ -550,6 +556,34 @@ int32_t RecorderMock::CameraServicesForAudio(VideoRecorderConfig &recorderConfig return MSERR_OK; } +int32_t RecorderMock::SetAudVidFormat(const std::string &recorderType, VideoRecorderConfig &recorderConfig) const +{ + UNITTEST_CHECK_AND_RETURN_RET_LOG(recorder_ != nullptr, MSERR_INVALID_OPERATION, "recorder_ == nullptr"); + int32_t ret = 0; + ret = recorder_->SetVideoSource(recorderConfig.vSource, recorderConfig.videoSourceId); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoSource failed "); + ret = recorder_->SetAudioSource(recorderConfig.aSource, recorderConfig.audioSourceId); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioSource failed "); + if (recorderConfig.metaSourceType == MetaSourceType::VIDEO_META_MAKER_INFO) { + ret = recorder_->SetMetaSource(recorderConfig.metaSourceType, recorderConfig.metaSourceId); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_UNKNOWN, "SetMetaSource failed "); + } + ret = recorder_->SetOutputFormat(recorderConfig.outPutFormat); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetOutputFormat failed "); + ret = recorder_->SetVideoEnableTemporalScale(recorderConfig.videoSourceId, recorderConfig.enableTemporalScale); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, + "SetVideoEnableTemporalScale failed "); + ret = CameraServicesForVideo(recorderConfig); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForVideo failed "); + ret = CameraServicesForAudio(recorderConfig); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForAudio failed "); + if (recorderConfig.metaSourceType == MetaSourceType::VIDEO_META_MAKER_INFO) { + ret = recorder_->SetMetaConfigs(recorderConfig.metaSourceId); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_UNKNOWN, "SetMetaConfigs failed "); + } + return ret; +} + int32_t RecorderMock::SetFormat(const std::string &recorderType, VideoRecorderConfig &recorderConfig) const { UNITTEST_CHECK_AND_RETURN_RET_LOG(recorder_ != nullptr, MSERR_INVALID_OPERATION, "recorder_ == nullptr"); @@ -572,19 +606,8 @@ int32_t RecorderMock::SetFormat(const std::string &recorderType, VideoRecorderCo ret = CameraServicesForAudio(recorderConfig); UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForAudio failed "); } else if (recorderType == AUDIO_VIDEO) { - ret = recorder_->SetVideoSource(recorderConfig.vSource, recorderConfig.videoSourceId); - UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoSource failed "); - ret = recorder_->SetAudioSource(recorderConfig.aSource, recorderConfig.audioSourceId); - UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioSource failed "); - ret = recorder_->SetOutputFormat(recorderConfig.outPutFormat); - UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetOutputFormat failed "); - ret = recorder_->SetVideoEnableTemporalScale(recorderConfig.videoSourceId, recorderConfig.enableTemporalScale); - UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, - "SetVideoEnableTemporalScale failed "); - ret = CameraServicesForVideo(recorderConfig); - UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForVideo failed "); - ret = CameraServicesForAudio(recorderConfig); - UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForAudio failed "); + ret = SetAudVidFormat(recorderType, recorderConfig); + UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudVidFormat failed "); } ret = recorder_->SetMaxDuration(recorderConfig.duration); diff --git a/frameworks/native/recorder/test/unittest/src/recorder_unit_test.cpp b/frameworks/native/recorder/test/unittest/src/recorder_unit_test.cpp index 0022d32a3b547a303e0c1fd08c5e9322aeec452b..527b44c7d1c3875d5c257b635f0f2fbd3bcee301 100644 --- a/frameworks/native/recorder/test/unittest/src/recorder_unit_test.cpp +++ b/frameworks/native/recorder/test/unittest/src/recorder_unit_test.cpp @@ -1572,5 +1572,34 @@ HWTEST_F(RecorderUnitTest, recorder_video_SetCustomInfo_002, TestSize.Level0) EXPECT_EQ(MSERR_OK, recorder_->Release()); close(videoRecorderConfig.outputFd); } + +/** + * @tc.name: recorder_video_GetMetaSurface + * @tc.desc: record video with meta data + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RecorderUnitTest, recorder_video_GetMetaSurface, TestSize.Level0) +{ + g_videoRecorderConfig.vSource = VIDEO_SOURCE_SURFACE_YUV; + g_videoRecorderConfig.videoFormat = H264; + g_videoRecorderConfig.metaSourceType = VIDEO_META_MAKER_INFO; + g_videoRecorderConfig.outputFd = open((RECORDER_ROOT + "recorder_video_GetMetaSurface.mp4").c_str(), O_RDWR); + ASSERT_TRUE(g_videoRecorderConfig.outputFd >= 0); + + EXPECT_EQ(MSERR_OK, recorder_->SetFormat(AUDIO_VIDEO, g_videoRecorderConfig)); + EXPECT_EQ(MSERR_OK, recorder_->Prepare()); + OHOS::sptr surface = recorder_->GetMetaSurface(g_videoRecorderConfig.metaSourceId); + ASSERT_TRUE(surface != nullptr); + EXPECT_EQ(MSERR_OK, recorder_->RequesetBuffer(AUDIO_VIDEO, g_videoRecorderConfig)); + + EXPECT_EQ(MSERR_OK, recorder_->Start()); + sleep(RECORDER_TIME); + EXPECT_EQ(MSERR_OK, recorder_->Stop(false)); + recorder_->StopBuffer(PURE_VIDEO); + EXPECT_EQ(MSERR_OK, recorder_->Reset()); + EXPECT_EQ(MSERR_OK, recorder_->Release()); + close(g_videoRecorderConfig.outputFd); +} } // namespace Media } // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/native/recorder.h b/interfaces/inner_api/native/recorder.h index 085b37db68f77ad195faa0511f64ffc85a308e37..20a56e955c2d286acb61f8ebb914bb2d29e481c0 100644 --- a/interfaces/inner_api/native/recorder.h +++ b/interfaces/inner_api/native/recorder.h @@ -51,6 +51,21 @@ enum VideoSourceType : int32_t { VIDEO_SOURCE_BUTT }; +/** + * @brief Enumerates meta source types. + * + * @since 4.2 + * @version 4.2 + */ +enum MetaSourceType : int32_t { + /** Invalid metadata source */ + VIDEO_META_SOURCE_INVALID = -1, + /** Video Maker info */ + VIDEO_META_MAKER_INFO, + /** max enum */ + VIDEO_META_SOURCE_BUTT +}; + /** * @brief Enumerates audio source types. * @@ -502,6 +517,33 @@ public: */ virtual int32_t SetDataSource(DataSourceType dataType, int32_t &sourceId) = 0; + /** + * @brief Sets a meta source for recording. + * + * If this function is not called, the output file does not contain the meta track. + * + * @param source Indicates the meta source type. For details, see {@link MetaSourceType}. + * @param sourceId Indicates the meta source ID. The value -1 indicates an invalid ID and the setting fails. + * + * @return Returns {@link MSERR_OK} if the setting is successful; returns an error code otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) = 0; + + /** + * @brief Sets a meta track configurations for recording. + * + * If this function is not called, the output file does not contain the meta track. + * + * @param sourceId Indicates the data source ID. The value -1 indicates an invalid ID and the setting fails. + * + * @return Returns {@link MSERR_OK} if the setting is successful; returns an error code otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaConfigs(int32_t sourceId) = 0; + /** * @brief Sets the output file format. * @@ -621,6 +663,17 @@ public: */ virtual sptr GetSurface(int32_t sourceId) = 0; + /** + * @brief Obtains the surface of the video source. This function can only be called after {@link Prepare} and + * before {@link Stop}. + * + * @param sourceId Indicates the meta source ID, which can be obtained from {@link SetMetaSource}. + * @return Returns the pointer to the surface. + * @since 1.0 + * @version 1.0 + */ + virtual sptr GetMetaSurface(int32_t sourceId) = 0; + /** * @brief Sets an audio encoder for recording. * diff --git a/services/engine/histreamer/recorder/hirecorder_impl.cpp b/services/engine/histreamer/recorder/hirecorder_impl.cpp index 7e85f7165a4a40f7a86aa81a5dc1b49db3f8c3c6..1d0023e1a1002160773390a7a5b513081ddbeb39 100644 --- a/services/engine/histreamer/recorder/hirecorder_impl.cpp +++ b/services/engine/histreamer/recorder/hirecorder_impl.cpp @@ -77,6 +77,11 @@ private: HiRecorderImpl *hiRecorderImpl_; }; +static inline MetaSourceType GetMetaSourceType(int32_t sourceId) +{ + return static_cast(sourceId - SourceIdGenerator::META_MASK); +} + HiRecorderImpl::HiRecorderImpl(int32_t appUid, int32_t appPid, uint32_t appTokenId, uint64_t appFullTokenId) : appUid_(appUid), appPid_(appPid), appTokenId_(appTokenId), appFullTokenId_(appFullTokenId) { @@ -149,6 +154,29 @@ int32_t HiRecorderImpl::SetVideoSource(VideoSourceType source, int32_t &sourceId return (int32_t)ret; } +int32_t HiRecorderImpl::SetMetaSource(MetaSourceType source, int32_t &sourceId) +{ + MediaTrace trace("HiRecorderImpl::SetMetaSource"); + MEDIA_LOG_I("SetMetaSource enter, sourceType:" PUBLIC_LOG_D32, static_cast(source)); + sourceId = INVALID_SOURCE_ID; + FALSE_RETURN_V( + source > MetaSourceType::VIDEO_META_SOURCE_INVALID && source < MetaSourceType::VIDEO_META_SOURCE_BUTT, + (int32_t)Status::ERROR_INVALID_PARAMETER + ); + Status ret; + auto filter = Pipeline::FilterFactory::Instance().CreateFilter + ("MetaDataFilter", Pipeline::FilterType::TIMED_METADATA); + ret = pipeline_->AddHeadFilters({filter}); + FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "AddFilters MetaDataFilter to pipeline fail"); + if (filter && ret == Status::OK) { + MEDIA_LOG_I("SetMetaSource success."); + sourceId = SourceIdGenerator::GenerateMetaSourceId(static_cast(source)); + metaDataFilters_.emplace(std::make_pair(sourceId, filter)); + OnStateChanged(StateId::RECORDING_SETTING); + } + return (int32_t)ret; +} + int32_t HiRecorderImpl::SetAudioSource(AudioSourceType source, int32_t &sourceId) { MediaTrace trace("HiRecorderImpl::SetAudioSource"); @@ -240,9 +268,18 @@ int32_t HiRecorderImpl::Configure(int32_t sourceId, const RecorderParam &recPara case RecorderPublicParamType::CUSTOM_INFO: ConfigureMuxer(recParam); break; + case RecorderPublicParamType::META_MIME_TYPE: + case RecorderPublicParamType::META_TIMED_KEY: + case RecorderPublicParamType::META_SOURCE_TRACK_MIME: + ConfigureMeta(sourceId, recParam); + break; default: break; } + if (metaDataFormats_.size() != 0 && muxerFilter_) { + muxerFormat_->SetData("use_timed_meta_track", 1); + muxerFilter_->SetParameter(muxerFormat_); + } OnStateChanged(StateId::RECORDING_SETTING); return (int32_t)Status::OK; } @@ -259,6 +296,32 @@ sptr HiRecorderImpl::GetSurface(int32_t sourceId) return producerSurface_; } +sptr HiRecorderImpl::GetMetaSurface(int32_t sourceId) +{ + MEDIA_LOG_I("HiRecorderImpl GetMetaSurface enter."); + + if (SourceIdGenerator::IsMeta(sourceId) && + (GetMetaSourceType(sourceId) > VIDEO_META_SOURCE_INVALID && + GetMetaSourceType(sourceId) < VIDEO_META_SOURCE_BUTT)) { + producerMetaSurface_ = metaDataFilters_.at(sourceId)->GetInputMetaSurface(); + } + return producerMetaSurface_; +} + +int32_t HiRecorderImpl::PrepareMeta() +{ + MEDIA_LOG_I("HiRecorderImpl PrepareMeta enter."); + for (auto iter : metaDataFilters_) { + if (metaDataFormats_.find(iter.first) != metaDataFormats_.end()) { + FALSE_RETURN_V_MSG_E(iter.second->Configure(metaDataFormats_.at(iter.first)) == Status::OK, + ERR_UNKNOWN_REASON, "MetaDataFilter Configure fail MetaType(%{public}d)", iter.first); + iter.second->SetCodecFormat(metaDataFormats_.at(iter.first)); + } + iter.second->Init(recorderEventReceiver_, recorderCallback_); + } + return (int32_t)Status::OK; +} + int32_t HiRecorderImpl::Prepare() { MediaTrace trace("HiRecorderImpl::Prepare"); @@ -298,6 +361,11 @@ int32_t HiRecorderImpl::Prepare() FALSE_RETURN_V_MSG_E(videoEncoderFilter_->Configure(videoEncFormat_) == Status::OK, ERR_UNKNOWN_REASON, "videoEncoderFilter Configure fail"); } + + if (metaDataFilters_.size()) { + FALSE_RETURN_V_MSG_E(PrepareMeta() == (int32_t)Status::OK, ERR_UNKNOWN_REASON, "prepare MetadataFilter fail"); + } + if (videoCaptureFilter_) { videoCaptureFilter_->SetCodecFormat(videoEncFormat_); videoCaptureFilter_->Init(recorderEventReceiver_, recorderCallback_); @@ -383,6 +451,13 @@ int32_t HiRecorderImpl::Stop(bool isDrainAll) if (videoEncoderFilter_) { pipeline_->RemoveHeadFilter(videoEncoderFilter_); } + for (auto iter : metaDataFilters_) { + if (metaDataFormats_.find(iter.first) != metaDataFormats_.end()) { + metaDataFormats_.at(iter.first)->Clear(); + } + pipeline_->RemoveHeadFilter(iter.second); + } + metaDataFilters_.clear(); if (videoCaptureFilter_) { pipeline_->RemoveHeadFilter(videoCaptureFilter_); } @@ -625,6 +700,36 @@ void HiRecorderImpl::ConfigureVideo(const RecorderParam &recParam) } } + +void HiRecorderImpl::ConfigureMeta(int32_t sourceId, const RecorderParam &recParam) +{ + MEDIA_LOG_I("HiRecorderImpl ConfigureMeta enter"); + if (metaDataFormats_.find(sourceId) == metaDataFormats_.end()) { + auto format = std::make_shared(); + metaDataFormats_.emplace(std::make_pair(sourceId, format)); + } + auto metaFormat = metaDataFormats_.at(sourceId); + switch (recParam.type) { + case RecorderPublicParamType::META_MIME_TYPE: { + MetaMimeType mimeType = static_cast(recParam); + metaFormat->Set(mimeType.mimeType); + break; + } + case RecorderPublicParamType::META_TIMED_KEY: { + MetaTimedKey timedKey = static_cast(recParam); + metaFormat->Set(timedKey.timedKey); + break; + } + case RecorderPublicParamType::META_SOURCE_TRACK_MIME: { + MetaSourceTrackMime sourceTrackMime = static_cast(recParam); + metaFormat->Set(sourceTrackMime.sourceMime); + break; + } + default: + break; + } +} + void HiRecorderImpl::ConfigureVideoEnableTemporalScale(const RecorderParam &recParam) { VidEnableTemporalScale vidEnableTemporalScale = static_cast(recParam); @@ -743,6 +848,9 @@ bool HiRecorderImpl::CheckParamType(int32_t sourceId, const RecorderParam &recPa static_cast(audioSourceId_) == sourceId) || (SourceIdGenerator::IsVideo(sourceId) && recParam.IsVideoParam() && static_cast(videoSourceId_) == sourceId) || + (SourceIdGenerator::IsMeta(sourceId) && recParam.IsMetaParam() && + (GetMetaSourceType(sourceId) > VIDEO_META_SOURCE_INVALID && + GetMetaSourceType(sourceId) < VIDEO_META_SOURCE_BUTT)) || ((sourceId == DUMMY_SOURCE_ID) && !(recParam.IsAudioParam() || recParam.IsVideoParam())), false); return true; } diff --git a/services/engine/histreamer/recorder/hirecorder_impl.h b/services/engine/histreamer/recorder/hirecorder_impl.h index 23c9ef86f08d9b20563b58b0a426f5c343ef1d35..05e267009fca5c482bcf6d6dc36ae427de81dbe5 100644 --- a/services/engine/histreamer/recorder/hirecorder_impl.h +++ b/services/engine/histreamer/recorder/hirecorder_impl.h @@ -26,6 +26,7 @@ #include "audio_capture_filter.h" #include "audio_data_source_filter.h" #include "audio_encoder_filter.h" +#include "metadata_filter.h" #include "media_errors.h" #include "muxer_filter.h" #include "osal/task/task.h" @@ -57,11 +58,13 @@ public: int32_t Init(); int32_t SetVideoSource(VideoSourceType source, int32_t &sourceId); int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId); + int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId); int32_t SetAudioDataSource(const std::shared_ptr& audioSource, int32_t& sourceId); int32_t SetOutputFormat(OutputFormatType format); int32_t SetObs(const std::weak_ptr &obs); int32_t Configure(int32_t sourceId, const RecorderParam &recParam); sptr GetSurface(int32_t sourceId); + sptr GetMetaSurface(int32_t sourceId); int32_t Prepare(); int32_t Start(); int32_t Pause(); @@ -84,6 +87,7 @@ private: void ConfigureAudioCapture(); void ConfigureAudio(const RecorderParam &recParam); void ConfigureVideo(const RecorderParam &recParam); + void ConfigureMeta(int32_t sourceId, const RecorderParam &recParam); void ConfigureMuxer(const RecorderParam &recParam); bool CheckParamType(int32_t sourceId, const RecorderParam &recParam); void OnStateChanged(StateId state); @@ -91,6 +95,7 @@ private: void ConfigureVideoEnableTemporalScale(const RecorderParam &recParam); bool CheckAudioSourceType(AudioSourceType sourceType); void ConfigureRotation(const RecorderParam &recParam); + int32_t PrepareMeta(); EncoderCapabilityData ConvertAudioEncoderInfo(MediaAVCodec::CapabilityData *capabilityData); EncoderCapabilityData ConvertVideoEncoderInfo(MediaAVCodec::CapabilityData *capabilityData); std::vector ConvertEncoderInfo(std::vector &capData); @@ -123,6 +128,9 @@ private: std::shared_ptr userMeta_ = std::make_shared(); std::atomic curState_; + std::map> metaDataFilters_; + std::map> metaDataFormats_; + std::shared_ptr CapturerInfoChangeCallback_; std::weak_ptr obs_{}; OutputFormatType outputFormatType_{OutputFormatType::FORMAT_BUTT}; @@ -138,6 +146,7 @@ private: ConditionVariable cond_ {}; sptr producerSurface_{nullptr}; + sptr producerMetaSurface_{nullptr}; sptr consumerSurface_{nullptr}; static constexpr uint32_t ENCODE_USAGE = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | diff --git a/services/engine/histreamer/recorder/recorder_utils.h b/services/engine/histreamer/recorder/recorder_utils.h index 27dbd70b56328e929e273ed1c28580ac85fc80a4..65374a427f8840e685733cc9acebf602c3d58702 100644 --- a/services/engine/histreamer/recorder/recorder_utils.h +++ b/services/engine/histreamer/recorder/recorder_utils.h @@ -31,6 +31,7 @@ struct SourceIdGenerator { static inline const uint32_t SOURCE_MASK = 0xF00; static inline const uint32_t VIDEO_MASK = 0x100; static inline const uint32_t AUDIO_MASK = 0x200; +static inline const uint32_t META_MASK = 0x300; static inline const uint32_t INDEX_MASK = 0xFF; static inline int32_t GenerateAudioSourceId(uint32_t index) @@ -43,6 +44,11 @@ static inline int32_t GenerateVideoSourceId(uint32_t index) return static_cast(VIDEO_MASK + (INDEX_MASK & index)); } +static inline int32_t GenerateMetaSourceId(uint32_t index) +{ + return static_cast(META_MASK + (INDEX_MASK & index)); +} + static inline int32_t IsAudio(int32_t sourceId) { return ((sourceId > 0) && @@ -54,6 +60,12 @@ static inline int32_t IsVideo(int32_t sourceId) return ((sourceId > 0) && ((static_cast(sourceId) & SOURCE_MASK) == VIDEO_MASK)); } + +static inline int32_t IsMeta(int32_t sourceId) +{ + return ((sourceId > 0) && + ((static_cast(sourceId) & SOURCE_MASK) == META_MASK)); +} }; } // Media } // OHOS diff --git a/services/include/i_recorder_service.h b/services/include/i_recorder_service.h index 81ddf527f9469899eb0ccf823236501b7d0271bf..44f23b88f0bd2b77811ba3642082c9b0b48ec82a 100644 --- a/services/include/i_recorder_service.h +++ b/services/include/i_recorder_service.h @@ -43,6 +43,78 @@ public: */ virtual int32_t SetVideoSource(VideoSourceType source, int32_t &sourceId) = 0; + /** + * @brief Sets a meta source for recording. + * + * If this function is not called, the output file does not contain the meta track. + * + * @param source Indicates the meta source type. For details, see {@link MetaSourceType}. + * @param sourceId Indicates the meta source ID. The value -1 indicates an invalid ID and the setting fails. + * + * @return Returns {@link SUCCESS} if the setting is successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) = 0; + + /** + * @brief Sets a meta configurations for recording. + * + * If this function is not called, the output file does not contain the meta track. + * + * @param source Indicates the meta source type. For details, see {@link MetaSourceType}. + * @param sourceId Indicates the meta source ID. The value -1 indicates an invalid ID and the setting fails. + * + * @return Returns {@link SUCCESS} if the setting is successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaConfigs(int32_t sourceId) = 0; + + /** + * @brief Sets the meta mime type. + * + * This function must be called after {@link SetVideoSource} but before {@link Prepare}. + * + * @param sourceId Indicates the meta source ID, which can be obtained from {@link SetVideoSource}. + * @param type mime type. + * @return Returns {@link SUCCESS} if the setting is successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaMimeType(int32_t sourceId, const std::string_view &type) = 0; + + /** + * @brief Sets the meta timed key. + * + * This function must be called after {@link SetVideoSource} but before {@link Prepare}. + * + * @param sourceId Indicates the meta source ID, which can be obtained from {@link SetVideoSource}. + * @param key meta data timed key. + * @return Returns {@link SUCCESS} if the setting is successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) = 0; + + /** + * @brief Sets the meta timed key. + * + * This function must be called after {@link SetVideoSource} but before {@link Prepare}. + * + * @param sourceId Indicates the meta source ID, which can be obtained from {@link SetVideoSource}. + * @param type meta data source track mime type. + * @return Returns {@link SUCCESS} if the setting is successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) = 0; + /** * @brief Sets a video encoder for recording. * @@ -150,6 +222,16 @@ public: */ virtual sptr GetSurface(int32_t sourceId) = 0; + /** + * @brief Obtains the surface of the meta track. + * + * @param sourceId Indicates the video source ID, which can be obtained from {@link SetMetaSource}. + * @return Returns the pointer to the surface. + * @since 1.0 + * @version 1.0 + */ + virtual sptr GetMetaSurface(int32_t sourceId) = 0; + /** * @brief Sets the audio source for recording. * diff --git a/services/services/engine_intf/i_recorder_engine.h b/services/services/engine_intf/i_recorder_engine.h index b6f002eee2042bff0835ff2b364bac70ba8f6188..c3d4f97c58343a5c51b4bc4d0db7763e839a8db9 100644 --- a/services/services/engine_intf/i_recorder_engine.h +++ b/services/services/engine_intf/i_recorder_engine.h @@ -93,6 +93,14 @@ public: */ virtual int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) = 0; + /** + * Sets the meta source for recording. The sourceId can be used to identify the meta source when configure + * the meta track's any properties. When the setting is failed, the sourceId is -1. + * This interface must be called before SetOutputFormat. + * Return MSERR_OK indicates success, or others indicate failed. + */ + virtual int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) = 0; + /** * Sets the audio data source for recording. The sourceId can be used to identify the audio data source * when configure the audio track's any properties. When the setting is failed, the sourceId is -1. @@ -133,6 +141,12 @@ public: */ virtual sptr GetSurface(int32_t sourceId) = 0; + /** + * Obtains the surface of the meta source. The sourceId indicates the meta source ID, which can be obtained + * from SetMetaSource. + */ + virtual sptr GetMetaSurface(int32_t sourceId) = 0; + /** * Prepares for recording. This function must be called before Start. Ensure all required recorder parameter * have already been set, or this call will be failed. diff --git a/services/services/engine_intf/recorder_param.h b/services/services/engine_intf/recorder_param.h index 5a965cff7e9b138e1f972ecc458fb0d8c0bf193a..ec51b9d4e6ddea108d88e0d95deb4e5950f34eb3 100644 --- a/services/services/engine_intf/recorder_param.h +++ b/services/services/engine_intf/recorder_param.h @@ -52,6 +52,12 @@ enum RecorderPublicParamType : uint32_t { AUD_CHANNEL, AUD_BITRATE, AUD_PUBIC_PARAM_END, + // meta data + META_PARAM_BEGIN, + META_MIME_TYPE, + META_TIMED_KEY, + META_SOURCE_TRACK_MIME, + META_PARAM_END, // output begin, MAX_DURATION, MAX_SIZE, @@ -77,6 +83,11 @@ struct RecorderParam { return (type > VID_PUBLIC_PARAM_BEGIN) && (type < VID_PUBLIC_PARAM_END); } + bool IsMetaParam() const + { + return (type >= META_PARAM_BEGIN) && (type < META_PARAM_END); + } + bool IsAudioParam() const { return (type > AUD_PUBLIC_PARAM_BEGIN) && (type < AUD_PUBIC_PARAM_END); @@ -192,6 +203,24 @@ struct GenreInfo : public RecorderParam { genre(genreInfo) {} std::string genre; }; + +struct MetaMimeType : public RecorderParam { + explicit MetaMimeType(const std::string_view &type) : RecorderParam(RecorderPublicParamType::META_MIME_TYPE), + mimeType(type) {} + std::string mimeType; +}; + +struct MetaTimedKey : public RecorderParam { + explicit MetaTimedKey(const std::string_view &key) : RecorderParam(RecorderPublicParamType::META_TIMED_KEY), + timedKey(key) {} + std::string timedKey; +}; + +struct MetaSourceTrackMime : public RecorderParam { + explicit MetaSourceTrackMime(std::string_view type) + : RecorderParam(RecorderPublicParamType::META_SOURCE_TRACK_MIME), sourceMime(type) {} + std::string sourceMime; +}; } // namespace Media } // namespace OHOS #endif diff --git a/services/services/recorder/client/recorder_client.cpp b/services/services/recorder/client/recorder_client.cpp index 7d1ce6c1a8f4cb476969dc9a956161c2aedf2f23..15da4b81aa6d6a2e81253715a38dd7f8c22079bd 100644 --- a/services/services/recorder/client/recorder_client.cpp +++ b/services/services/recorder/client/recorder_client.cpp @@ -146,6 +146,55 @@ int32_t RecorderClient::SetVideoEnableTemporalScale(int32_t sourceId, bool enabl return recorderProxy_->SetVideoEnableTemporalScale(sourceId, enableTemporalScale); } +int32_t RecorderClient::SetMetaSource(MetaSourceType source, int32_t &sourceId) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, MSERR_NO_MEMORY, "recorder service does not exist."); + + MEDIA_LOGD("SetMetaSourceType source(%{public}d), sourceId(%{public}d)", + source, sourceId); + return recorderProxy_->SetMetaSource(source, sourceId); +} + +int32_t RecorderClient::SetMetaConfigs(int32_t sourceId) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, MSERR_NO_MEMORY, "recorder service does not exist."); + + MEDIA_LOGD("SetMetaConfigs sourceId(%{public}d)", sourceId); + return recorderProxy_->SetMetaConfigs(sourceId); +} + +int32_t RecorderClient::SetMetaMimeType(int32_t sourceId, const std::string_view &type) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, MSERR_NO_MEMORY, "recorder service does not exist."); + + MEDIA_LOGD("SetMetaMimeType sourceId(%{public}d), MetaMimeType(%{public}s)", + sourceId, type.data()); + return recorderProxy_->SetMetaMimeType(sourceId, type); +} + +int32_t RecorderClient::SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, MSERR_NO_MEMORY, "recorder service does not exist."); + + MEDIA_LOGD("SetMetaTimedKey sourceId(%{public}d), MetaTimedKey(%{public}s)", + sourceId, timedKey.data()); + return recorderProxy_->SetMetaTimedKey(sourceId, timedKey); +} + +int32_t RecorderClient::SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, MSERR_NO_MEMORY, "recorder service does not exist."); + + MEDIA_LOGD("SetMetaSourceTrackMime sourceId(%{public}d), srcTrackMime(%{public}s)", + sourceId, srcTrackMime.data()); + return recorderProxy_->SetMetaSourceTrackMime(sourceId, srcTrackMime); +} + int32_t RecorderClient::SetCaptureRate(int32_t sourceId, double fps) { std::lock_guard lock(mutex_); @@ -164,6 +213,15 @@ sptr RecorderClient::GetSurface(int32_t sourceId) return recorderProxy_->GetSurface(sourceId); } +sptr RecorderClient::GetMetaSurface(int32_t sourceId) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, nullptr, "recorder service does not exist."); + + MEDIA_LOGD("GetMetaSurface sourceId(%{public}d)", sourceId); + return recorderProxy_->GetMetaSurface(sourceId); +} + int32_t RecorderClient::SetAudioSource(AudioSourceType source, int32_t &sourceId) { std::lock_guard lock(mutex_); diff --git a/services/services/recorder/client/recorder_client.h b/services/services/recorder/client/recorder_client.h index 7ff095a5ba51c83a01b81a533a22301557a5d08c..01173e75e32fb2b8e19271d0d6daa1207fec537c 100644 --- a/services/services/recorder/client/recorder_client.h +++ b/services/services/recorder/client/recorder_client.h @@ -37,8 +37,14 @@ public: int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate) override; int32_t SetVideoIsHdr(int32_t sourceId, bool isHdr) override; int32_t SetVideoEnableTemporalScale(int32_t sourceId, bool enableTemporalScale) override; + int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) override; + int32_t SetMetaConfigs(int32_t sourceId) override; + int32_t SetMetaMimeType(int32_t sourceId, const std::string_view &type) override; + int32_t SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) override; + int32_t SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) override; int32_t SetCaptureRate(int32_t sourceId, double fps) override; sptr GetSurface(int32_t sourceId) override; + sptr GetMetaSurface(int32_t sourceId) override; int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) override; int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) override; int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate) override; diff --git a/services/services/recorder/ipc/i_standard_recorder_service.h b/services/services/recorder/ipc/i_standard_recorder_service.h index e985d49e415af36395ab47df771898497cce1184..fc38b594edc9efc4b7a8bcced9809e0a04d5e205 100644 --- a/services/services/recorder/ipc/i_standard_recorder_service.h +++ b/services/services/recorder/ipc/i_standard_recorder_service.h @@ -33,6 +33,11 @@ public: virtual int32_t SetVideoSize(int32_t sourceId, int32_t width, int32_t height) = 0; virtual int32_t SetVideoFrameRate(int32_t sourceId, int32_t frameRate) = 0; virtual int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate) = 0; + virtual int32_t SetMetaConfigs(int32_t sourceId) = 0; + virtual int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) = 0; + virtual int32_t SetMetaMimeType(int32_t sourceId, const std::string_view &type) = 0; + virtual int32_t SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) = 0; + virtual int32_t SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) = 0; virtual int32_t SetCaptureRate(int32_t sourceId, double fps) { (void)sourceId; @@ -40,6 +45,7 @@ public: return MSERR_UNSUPPORT; }; virtual sptr GetSurface(int32_t sourceId) = 0; + virtual sptr GetMetaSurface(int32_t sourceId) = 0; virtual int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) = 0; virtual int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) = 0; virtual int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate) = 0; @@ -132,6 +138,12 @@ public: GET_MAX_AMPLITUDE, IS_WATERMARK_SUPPORTED, SET_WATERMARK, + SET_META_CONFIGS, + SET_META_SOURCE, + SET_META_MIME_TYPE, + SET_META_TIMED_KEY, + SET_META_TRACK_SRC_MIME_TYPE, + GET_META_SURFACE, }; DECLARE_INTERFACE_DESCRIPTOR(u"IStandardRecorderService"); diff --git a/services/services/recorder/ipc/recorder_service_proxy.cpp b/services/services/recorder/ipc/recorder_service_proxy.cpp index 06fefdf8b81077cabd32486e10daab86b812b9af..2c839bbc1c57e24dd5d575daf67c9f73732885e7 100644 --- a/services/services/recorder/ipc/recorder_service_proxy.cpp +++ b/services/services/recorder/ipc/recorder_service_proxy.cpp @@ -179,6 +179,95 @@ int32_t RecorderServiceProxy::SetVideoEnableTemporalScale(int32_t sourceId, bool return reply.ReadInt32(); } +int32_t RecorderServiceProxy::SetMetaConfigs(int32_t sourceId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + data.WriteInt32(sourceId); + int error = Remote()->SendRequest(SET_META_CONFIGS, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "SetMetaConfigs failed, error: %{public}d", error); + + return reply.ReadInt32(); +} + +int32_t RecorderServiceProxy::SetMetaSource(MetaSourceType source, int32_t &sourceId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + data.WriteInt32(source); + int error = Remote()->SendRequest(SET_META_SOURCE, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "SetMetaSource failed, error: %{public}d", error); + + sourceId = reply.ReadInt32(); + return reply.ReadInt32(); +} + +int32_t RecorderServiceProxy::SetMetaMimeType(int32_t sourceId, const std::string_view &type) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + data.WriteInt32(sourceId); + data.WriteCString(type.data()); + int error = Remote()->SendRequest(SET_META_MIME_TYPE, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "SetMetaMimeType failed, error: %{public}d", error); + + return reply.ReadInt32(); +} + +int32_t RecorderServiceProxy::SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + data.WriteInt32(sourceId); + data.WriteCString(timedKey.data()); + int error = Remote()->SendRequest(SET_META_TIMED_KEY, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "SetMetaTimedKey failed, error: %{public}d", error); + + return reply.ReadInt32(); +} + +int32_t RecorderServiceProxy::SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + data.WriteInt32(sourceId); + data.WriteCString(srcTrackMime.data()); + int error = Remote()->SendRequest(SET_META_TRACK_SRC_MIME_TYPE, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "SetMetaSourceTrackMime failed, error: %{public}d", error); + + return reply.ReadInt32(); +} + int32_t RecorderServiceProxy::SetCaptureRate(int32_t sourceId, double fps) { MessageParcel data; @@ -220,6 +309,29 @@ sptr RecorderServiceProxy::GetSurface(int32_t sourceId) return OHOS::Surface::CreateSurfaceAsProducer(producer); } +sptr RecorderServiceProxy::GetMetaSurface(int32_t sourceId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, nullptr, "Failed to write descriptor!"); + + data.WriteInt32(sourceId); + int error = Remote()->SendRequest(GET_META_SURFACE, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, nullptr, + "GetMetaSurface failed, error: %{public}d", error); + + sptr object = reply.ReadRemoteObject(); + CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to read surface object"); + + sptr producer = iface_cast(object); + CHECK_AND_RETURN_RET_LOG(producer != nullptr, nullptr, "failed to convert object to producer"); + + return OHOS::Surface::CreateSurfaceAsProducer(producer); +} + int32_t RecorderServiceProxy::SetAudioSource(AudioSourceType source, int32_t &sourceId) { MessageParcel data; diff --git a/services/services/recorder/ipc/recorder_service_proxy.h b/services/services/recorder/ipc/recorder_service_proxy.h index 519b9500df2dda071d01b1a5c0b5da3ea374b828..38e087e2900cdabf0723d23bc35a30ef64cb6b16 100644 --- a/services/services/recorder/ipc/recorder_service_proxy.h +++ b/services/services/recorder/ipc/recorder_service_proxy.h @@ -34,8 +34,14 @@ public: int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate) override; int32_t SetVideoIsHdr(int32_t sourceId, bool isHdr) override; int32_t SetVideoEnableTemporalScale(int32_t sourceId, bool enableTemporalScale) override; + int32_t SetMetaConfigs(int32_t sourceId) override; + int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) override; + int32_t SetMetaMimeType(int32_t sourceId, const std::string_view &type) override; + int32_t SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) override; + int32_t SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) override; int32_t SetCaptureRate(int32_t sourceId, double fps) override; sptr GetSurface(int32_t sourceId) override; + sptr GetMetaSurface(int32_t sourceId) override; int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) override; int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) override; int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate) override; diff --git a/services/services/recorder/ipc/recorder_service_stub.cpp b/services/services/recorder/ipc/recorder_service_stub.cpp index 038b8b931f80749c3629d9ec3974c7d0d9cdf7ea..73997027189e50f354871c8b7610558c554850de 100644 --- a/services/services/recorder/ipc/recorder_service_stub.cpp +++ b/services/services/recorder/ipc/recorder_service_stub.cpp @@ -144,6 +144,18 @@ void RecorderServiceStub::FillRecFuncPart2() [this](MessageParcel &data, MessageParcel &reply) { return IsWatermarkSupported(data, reply); }; recFuncs_[SET_WATERMARK] = [this](MessageParcel &data, MessageParcel &reply) { return SetWatermark(data, reply); }; + recFuncs_[SET_META_CONFIGS] = + [this](MessageParcel &data, MessageParcel &reply) { return SetMetaConfigs(data, reply); }; + recFuncs_[SET_META_SOURCE] = + [this](MessageParcel &data, MessageParcel &reply) { return SetMetaSource(data, reply); }; + recFuncs_[SET_META_MIME_TYPE] = + [this](MessageParcel &data, MessageParcel &reply) { return SetMetaMimeType(data, reply); }; + recFuncs_[SET_META_TIMED_KEY] = + [this](MessageParcel &data, MessageParcel &reply) { return SetMetaTimedKey(data, reply); }; + recFuncs_[SET_META_TRACK_SRC_MIME_TYPE] = + [this](MessageParcel &data, MessageParcel &reply) { return SetMetaSourceTrackMime(data, reply); }; + recFuncs_[GET_META_SURFACE] = + [this](MessageParcel &data, MessageParcel &reply) { return GetMetaSurface(data, reply); }; } int32_t RecorderServiceStub::DestroyStub() @@ -268,12 +280,48 @@ int32_t RecorderServiceStub::SetVideoEnableTemporalScale(int32_t sourceId, bool return recorderServer_->SetVideoEnableTemporalScale(sourceId, enableTemporalScale); } +int32_t RecorderServiceStub::SetMetaConfigs(int32_t sourceId) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); + return recorderServer_->SetMetaConfigs(sourceId); +} + +int32_t RecorderServiceStub::SetMetaSource(MetaSourceType source, int32_t &sourceId) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); + return recorderServer_->SetMetaSource(source, sourceId); +} + +int32_t RecorderServiceStub::SetMetaMimeType(int32_t sourceId, const std::string_view &type) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); + return recorderServer_->SetMetaMimeType(sourceId, type); +} + +int32_t RecorderServiceStub::SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); + return recorderServer_->SetMetaTimedKey(sourceId, timedKey); +} + +int32_t RecorderServiceStub::SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); + return recorderServer_->SetMetaSourceTrackMime(sourceId, srcTrackMime); +} + sptr RecorderServiceStub::GetSurface(int32_t sourceId) { CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, nullptr, "recorder server is nullptr"); return recorderServer_->GetSurface(sourceId); } +sptr RecorderServiceStub::GetMetaSurface(int32_t sourceId) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, nullptr, "recorder server is nullptr"); + return recorderServer_->GetMetaSurface(sourceId); +} + int32_t RecorderServiceStub::SetAudioSource(AudioSourceType source, int32_t &sourceId) { CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); @@ -526,6 +574,49 @@ int32_t RecorderServiceStub::SetVideoEnableTemporalScale(MessageParcel &data, Me return MSERR_OK; } +int32_t RecorderServiceStub::SetMetaConfigs(MessageParcel &data, MessageParcel &reply) +{ + int32_t sourceId = data.ReadInt32(); + int32_t ret = SetMetaConfigs(sourceId); + reply.WriteInt32(ret); + return MSERR_OK; +} + +int32_t RecorderServiceStub::SetMetaSource(MessageParcel &data, MessageParcel &reply) +{ + int32_t source = data.ReadInt32(); + MetaSourceType sourceType = static_cast(source); + int32_t sourceId = 0; + int32_t ret = SetMetaSource(sourceType, sourceId); + reply.WriteInt32(sourceId); + reply.WriteInt32(ret); + return MSERR_OK; +} + +int32_t RecorderServiceStub::SetMetaMimeType(MessageParcel &data, MessageParcel &reply) +{ + int32_t sourceId = data.ReadInt32(); + std::string_view mimetype(data.ReadCString()); + reply.WriteInt32(SetMetaMimeType(sourceId, mimetype)); + return MSERR_OK; +} + +int32_t RecorderServiceStub::SetMetaTimedKey(MessageParcel &data, MessageParcel &reply) +{ + int32_t sourceId = data.ReadInt32(); + std::string_view timedKey(data.ReadCString()); + reply.WriteInt32(SetMetaTimedKey(sourceId, timedKey)); + return MSERR_OK; +} + +int32_t RecorderServiceStub::SetMetaSourceTrackMime(MessageParcel &data, MessageParcel &reply) +{ + int32_t sourceId = data.ReadInt32(); + std::string_view srcTrackMime(data.ReadCString()); + reply.WriteInt32(SetMetaSourceTrackMime(sourceId, srcTrackMime)); + return MSERR_OK; +} + int32_t RecorderServiceStub::GetSurface(MessageParcel &data, MessageParcel &reply) { int32_t sourceId = data.ReadInt32(); @@ -537,6 +628,17 @@ int32_t RecorderServiceStub::GetSurface(MessageParcel &data, MessageParcel &repl return MSERR_OK; } +int32_t RecorderServiceStub::GetMetaSurface(MessageParcel &data, MessageParcel &reply) +{ + int32_t sourceId = data.ReadInt32(); + sptr surface = GetMetaSurface(sourceId); + if (surface != nullptr && surface->GetProducer() != nullptr) { + sptr object = surface->GetProducer()->AsObject(); + (void)reply.WriteRemoteObject(object); + } + return MSERR_OK; +} + int32_t RecorderServiceStub::SetAudioSource(MessageParcel &data, MessageParcel &reply) { int32_t sourceId = 0; diff --git a/services/services/recorder/ipc/recorder_service_stub.h b/services/services/recorder/ipc/recorder_service_stub.h index a6f58e668d9f1fb450332460100370b16b83c441..31e70a160971144c9a33b3e9cd62a4ebb7419b15 100644 --- a/services/services/recorder/ipc/recorder_service_stub.h +++ b/services/services/recorder/ipc/recorder_service_stub.h @@ -43,7 +43,13 @@ public: int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate) override; int32_t SetVideoIsHdr(int32_t sourceId, bool isHdr) override; int32_t SetVideoEnableTemporalScale(int32_t sourceId, bool enableTemporalScale) override; + int32_t SetMetaConfigs(int32_t sourceId) override; + int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) override; + int32_t SetMetaMimeType(int32_t sourceId, const std::string_view &type) override; + int32_t SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) override; + int32_t SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) override; sptr GetSurface(int32_t sourceId) override; + sptr GetMetaSurface(int32_t sourceId) override; int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) override; int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) override; int32_t SetAudioSampleRate(int32_t sourceId, int32_t rate) override; @@ -88,7 +94,13 @@ private: int32_t SetVideoEncodingBitRate(MessageParcel &data, MessageParcel &reply); int32_t SetVideoIsHdr(MessageParcel &data, MessageParcel &reply); int32_t SetVideoEnableTemporalScale(MessageParcel &data, MessageParcel &reply); + int32_t SetMetaConfigs(MessageParcel &data, MessageParcel &reply); + int32_t SetMetaSource(MessageParcel &data, MessageParcel &reply); + int32_t SetMetaMimeType(MessageParcel &data, MessageParcel &reply); + int32_t SetMetaTimedKey(MessageParcel &data, MessageParcel &reply); + int32_t SetMetaSourceTrackMime(MessageParcel &data, MessageParcel &reply); int32_t GetSurface(MessageParcel &data, MessageParcel &reply); + int32_t GetMetaSurface(MessageParcel &data, MessageParcel &reply); int32_t SetAudioSource(MessageParcel &data, MessageParcel &reply); int32_t SetAudioEncoder(MessageParcel &data, MessageParcel &reply); int32_t SetAudioSampleRate(MessageParcel &data, MessageParcel &reply); diff --git a/services/services/recorder/server/recorder_server.cpp b/services/services/recorder/server/recorder_server.cpp index 5e71974097eda2eb31901ebe6611d87152175818..e1ee9852bf99df36e42b1bd7cccf351a36f10ac5 100644 --- a/services/services/recorder/server/recorder_server.cpp +++ b/services/services/recorder/server/recorder_server.cpp @@ -38,6 +38,7 @@ namespace { {OHOS::Media::RecorderServer::REC_PAUSED, "paused"}, {OHOS::Media::RecorderServer::REC_ERROR, "error"}, }; + const std::string VID_DEBUG_INFO_KEY = "com.openharmony.timed_metadata.vid_maker_info"; } namespace OHOS { @@ -290,6 +291,90 @@ int32_t RecorderServer::SetVideoEnableTemporalScale(int32_t sourceId, bool enabl return result.Value(); } +int32_t RecorderServer::SetMetaSource(MetaSourceType source, int32_t &sourceId) +{ + MEDIA_LOGI("RecorderServer:0x%{public}06" PRIXPTR " SetMetaSource in, source(%{public}d), " + "sourceId(%{public}d)", FAKE_POINTER(this), source, sourceId); + + std::lock_guard lock(mutex_); + CHECK_STATUS_FAILED_AND_LOGE_RET(status_ != REC_INITIALIZED, MSERR_INVALID_OPERATION); + CHECK_AND_RETURN_RET_LOG(recorderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr"); + + config_.metaSource = source; + auto task = std::make_shared>([&, this] { + return recorderEngine_->SetMetaSource(source, sourceId); + }); + + int32_t ret = taskQue_.EnqueueTask(task); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed"); + + auto result = task->GetResult(); + return result.Value(); +} + +int32_t RecorderServer::SetMetaMimeType(int32_t sourceId, const std::string_view &type) +{ + MEDIA_LOGI("RecorderServer:0x%{public}06" PRIXPTR " SetMetaMimeType in, sourceId(%{public}d), " + "MimeType(%{public}s)", FAKE_POINTER(this), sourceId, type.data()); + + std::lock_guard lock(mutex_); + CHECK_STATUS_FAILED_AND_LOGE_RET(status_ != REC_CONFIGURED, MSERR_INVALID_OPERATION); + CHECK_AND_RETURN_RET_LOG(recorderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr"); + + config_.metaMimeType = type; + MetaMimeType metaMimeType(type); + auto task = std::make_shared>([&, this] { + return recorderEngine_->Configure(sourceId, metaMimeType); + }); + + int32_t ret = taskQue_.EnqueueTask(task); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed"); + + auto result = task->GetResult(); + return result.Value(); +} + +int32_t RecorderServer::SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) +{ + MEDIA_LOGI("RecorderServer:0x%{public}06" PRIXPTR " SetMetaTimedKey in, sourceId(%{public}d), " + "MetaTimedKey(%{public}s)", FAKE_POINTER(this), sourceId, timedKey.data()); + + std::lock_guard lock(mutex_); + CHECK_STATUS_FAILED_AND_LOGE_RET(status_ != REC_CONFIGURED, MSERR_INVALID_OPERATION); + CHECK_AND_RETURN_RET_LOG(recorderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr"); + + config_.metaTimedKey = timedKey; + MetaTimedKey metaTimedKey(timedKey); + auto task = std::make_shared>([&, this] { + return recorderEngine_->Configure(sourceId, metaTimedKey); + }); + int32_t ret = taskQue_.EnqueueTask(task); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed"); + + auto result = task->GetResult(); + return result.Value(); +} + +int32_t RecorderServer::SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) +{ + MEDIA_LOGI("RecorderServer:0x%{public}06" PRIXPTR " SetMetaSourceTrackMime in, sourceId(%{public}d), " + "sourceTrackMime(%{public}s)", FAKE_POINTER(this), sourceId, srcTrackMime.data()); + std::lock_guard lock(mutex_); + CHECK_STATUS_FAILED_AND_LOGE_RET(status_ != REC_CONFIGURED, MSERR_INVALID_OPERATION); + CHECK_AND_RETURN_RET_LOG(recorderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr"); + + config_.metaSrcTrackMime = srcTrackMime; + MetaSourceTrackMime metaSrcTrackMime(srcTrackMime); + auto task = std::make_shared>([&, this] { + return recorderEngine_->Configure(sourceId, metaSrcTrackMime); + }); + int32_t ret = taskQue_.EnqueueTask(task); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed"); + + auto result = task->GetResult(); + return result.Value(); +} + int32_t RecorderServer::SetCaptureRate(int32_t sourceId, double fps) { MEDIA_LOGI("SetCaptureRate sourceId(%{public}d), fps(%{public}lf)", sourceId, fps); @@ -326,6 +411,24 @@ sptr RecorderServer::GetSurface(int32_t sourceId) return result.Value(); } +sptr RecorderServer::GetMetaSurface(int32_t sourceId) +{ + MEDIA_LOGI("ecorderServer:0x%{public}06" PRIXPTR " GetMetaSurface in, sourceId(%{public}d)", + FAKE_POINTER(this), sourceId); + std::lock_guard lock(mutex_); + CHECK_STATUS_FAILED_AND_LOGE_RET(status_ != REC_PREPARED && status_ != REC_RECORDING && status_ != REC_PAUSED, + nullptr); + CHECK_AND_RETURN_RET_LOG(recorderEngine_ != nullptr, nullptr, "engine is nullptr"); + auto task = std::make_shared>>([&, this] { + return recorderEngine_->GetMetaSurface(sourceId); + }); + int32_t ret = taskQue_.EnqueueTask(task); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "EnqueueTask failed"); + + auto result = task->GetResult(); + return result.Value(); +} + int32_t RecorderServer::SetAudioSource(AudioSourceType source, int32_t &sourceId) { MediaTrace trace("RecorderServer::SetAudioSource"); @@ -446,6 +549,24 @@ int32_t RecorderServer::SetAudioEncodingBitRate(int32_t sourceId, int32_t bitRat return result.Value(); } +int32_t RecorderServer::SetMetaConfigs(int32_t sourceId) +{ + MEDIA_LOGI("RecorderServer:0x%{public}06" PRIXPTR " SetMetaConfigs in, sourceId(%{public}d)", + FAKE_POINTER(this), sourceId); + CHECK_AND_RETURN_RET_LOG(SetMetaMimeType(sourceId, Plugins::MimeType::TIMED_METADATA) == MSERR_OK, + MSERR_EXT_OPERATE_NOT_PERMIT, "set meta mime type failed"); + if (config_.metaSource == MetaSourceType::VIDEO_META_MAKER_INFO) { + CHECK_AND_RETURN_RET_LOG( + SetMetaTimedKey(sourceId, VID_DEBUG_INFO_KEY) == MSERR_OK, MSERR_EXT_OPERATE_NOT_PERMIT, + "set meta key failed"); + auto sourceTrackMime = GetVideoMime(config_.videoCodec); + CHECK_AND_RETURN_RET_LOG( + SetMetaSourceTrackMime(sourceId, sourceTrackMime) == MSERR_OK, + MSERR_EXT_OPERATE_NOT_PERMIT, "set meta source track mime failed"); + } + return MSERR_OK; +} + int32_t RecorderServer::SetDataSource(DataSourceType dataType, int32_t &sourceId) { (void)dataType; diff --git a/services/services/recorder/server/recorder_server.h b/services/services/recorder/server/recorder_server.h index f6090171fe4ad07cc65c51cd4d1830d5196bd31e..705d2eaf47fe08c46a8fac9cdf7203d599072298 100644 --- a/services/services/recorder/server/recorder_server.h +++ b/services/services/recorder/server/recorder_server.h @@ -75,8 +75,14 @@ public: int32_t SetVideoEncodingBitRate(int32_t sourceId, int32_t rate) override; int32_t SetVideoIsHdr(int32_t sourceId, bool isHdr) override; int32_t SetVideoEnableTemporalScale(int32_t sourceId, bool enableTemporalScale) override; + int32_t SetMetaSource(MetaSourceType source, int32_t &sourceId) override; + int32_t SetMetaConfigs(int32_t sourceId) override; + int32_t SetMetaMimeType(int32_t sourceId, const std::string_view &type) override; + int32_t SetMetaTimedKey(int32_t sourceId, const std::string_view &timedKey) override; + int32_t SetMetaSourceTrackMime(int32_t sourceId, const std::string_view &srcTrackMime) override; int32_t SetCaptureRate(int32_t sourceId, double fps) override; sptr GetSurface(int32_t sourceId) override; + sptr GetMetaSurface(int32_t sourceId) override; int32_t SetAudioSource(AudioSourceType source, int32_t &sourceId) override; int32_t SetAudioDataSource(const std::shared_ptr& audioSource, int32_t& sourceId) override; int32_t SetAudioEncoder(int32_t sourceId, AudioCodecFormat encoder) override; @@ -139,6 +145,7 @@ private: struct ConfigInfo { VideoSourceType videoSource = VIDEO_SOURCE_BUTT; AudioSourceType audioSource = AUDIO_SOURCE_INVALID; + MetaSourceType metaSource = VIDEO_META_SOURCE_INVALID; VideoCodecFormat videoCodec = VIDEO_CODEC_FORMAT_BUTT; AudioCodecFormat audioCodec = AUDIO_CODEC_FORMAT_BUTT; int32_t width = 0; @@ -158,8 +165,11 @@ private: float longitude = 0.0; int32_t rotation = 0; int32_t url = -1; + std::string metaSrcTrackMime; Meta customInfo; std::string genre; + std::string metaMimeType; + std::string metaTimedKey; bool withVideo = false; bool withAudio = false; bool withLocation = false; diff --git a/test/unittest/resources/ohos_test.xml b/test/unittest/resources/ohos_test.xml index 5b5815b547f90e93299b9d6236fbc6c1b458d669..a04529e288b2b34918ffa96479dcbb7116863bd1 100644 --- a/test/unittest/resources/ohos_test.xml +++ b/test/unittest/resources/ohos_test.xml @@ -118,6 +118,7 @@