mirror of
https://github.com/openharmony/multimedia_video_processing_engine.git
synced 2026-08-26 12:24:46 -04:00
!66 merge master into master
新增AIHDR查询接口 Created-by: zhuyicheng666 Commit-by: zhuyicheng666 Merged-by: openharmony_ci Description: ### 一、内容说明(相关的Issue) https://gitcode.com/openharmony/multimedia_video_processing_engine/issues/44 ### 二、建议测试周期和提测地址 建议测试完成时间:xxxx.xx.xx 投产上线时间:xxxx.xx.xx 提测地址:CI环境/压测环境 测试账号: ### 三、变更内容 * 3.1 关联PR列表 * 3.2 数据库和部署说明 1. 常规更新 2. 重启unicorn 3. 重启sidekiq 4. 迁移任务:是否有迁移任务,没有写 "无" 5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无" * 3.4 其他技术优化内容(做了什么,变更了什么) - 重构了 xxxx 代码 - xxxx 算法优化 * 3.5 废弃通知(什么字段、方法弃用?) * 3.6 后向不兼容变更(是否有无法向后兼容的变更?) ### 四、研发自测点(自测哪些?冒烟用例全部自测?) 自测测试结论: ### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方) 检查点: | 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 | |------|------------|----------|---------------| | xxx | 否 | 需要 | 不需要 | | | | | | 接口测试: 性能测试: 并发测试: 其他: See merge request: openharmony/multimedia_video_processing_engine!66
This commit is contained in:
+3
-1
@@ -56,7 +56,9 @@
|
||||
"//foundation/multimedia/video_processing_engine/framework:videoprocessingengine",
|
||||
"//foundation/multimedia/video_processing_engine/services:video_processing_service_group",
|
||||
"//foundation/multimedia/video_processing_engine/interfaces/kits/taihe:video_processing_engine_taihe_gen_only",
|
||||
"//foundation/multimedia/video_processing_engine/interfaces/kits/taihe:video_processing_engine_taihe_group"
|
||||
"//foundation/multimedia/video_processing_engine/interfaces/kits/taihe:video_processing_engine_taihe_group",
|
||||
"//foundation/multimedia/video_processing_engine/interfaces/kits/taihe:video_processing_taihe_group",
|
||||
"//foundation/multimedia/video_processing_engine/framework:videoprocessing_napi"
|
||||
],
|
||||
"inner_kits": [
|
||||
{
|
||||
|
||||
@@ -541,3 +541,48 @@ ohos_shared_library("videoprocessingenginenapi") {
|
||||
relative_install_dir = "module/multimedia"
|
||||
part_name = "video_processing_engine"
|
||||
}
|
||||
|
||||
ohos_shared_library("videoprocessing_napi") {
|
||||
branch_protector_ret = "pac_ret"
|
||||
sanitize = {
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
cfi_vcall_icall_only = true
|
||||
debug = false
|
||||
}
|
||||
|
||||
defines = [ ]
|
||||
|
||||
include_dirs = [
|
||||
"$DFX_DIR/include",
|
||||
"$INTERFACES_DIR/kits/js",
|
||||
"$INTERFACES_INNER_API_DIR",
|
||||
"$ALGORITHM_COMMON_DIR/include/",
|
||||
"$INTERFACES_CAPI_DIR",
|
||||
"$SERVICES_DIR/utils/include",
|
||||
]
|
||||
sources = [
|
||||
"$INTERFACES_DIR/kits/js/native_module_ohos_video_processing.cpp",
|
||||
"$INTERFACES_DIR/kits/js/video_processor_napi.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":videoprocessingengine",
|
||||
]
|
||||
|
||||
cflags = VIDEO_PROCESSING_ENGINE_CFLAGS
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"drivers_interface_display:libdisplay_commontype_proxy_2.1",
|
||||
"hilog:libhilog",
|
||||
"hitrace:hitrace_meter",
|
||||
"ipc:ipc_napi",
|
||||
"media_foundation:native_media_core",
|
||||
"media_foundation:media_foundation",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
|
||||
subsystem_name = "multimedia"
|
||||
relative_install_dir = "module/multimedia"
|
||||
part_name = "video_processing_engine"
|
||||
}
|
||||
|
||||
@@ -48,6 +48,19 @@ std::unordered_map<uint32_t, std::function<bool(const OHOS::Media::Format& param
|
||||
std::unordered_map<uint32_t, std::function<bool(const sptr<Surface>& surface)>> g_isSurfaceSupporteds = {
|
||||
{ VIDEO_TYPE_AUTO_EFFECT_AISR, &AutoEffectAisrVideo::IsSurfaceSupported },
|
||||
};
|
||||
|
||||
std::unordered_map<uint32_t, std::function<int32_t(VpeVideo::SettingsChangeCallback)>>
|
||||
g_registerSettingsChangeCallback = {
|
||||
// NOTE: Add feature altorithm GetParameter here. Every time a new client is created for communication
|
||||
// Feature altorithm header GetParameter begin
|
||||
// Feature altorithm header GetParameter end
|
||||
};
|
||||
|
||||
std::unordered_map<uint32_t, std::function<int32_t(void)>> g_unregisterSettingsChangeCallback = {
|
||||
// NOTE: Add feature altorithm GetParameter here. Every time a new client is created for communication
|
||||
// Feature altorithm header GetParameter begin
|
||||
// Feature altorithm header GetParameter end
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<VpeVideo> VpeVideo::Create(uint32_t type)
|
||||
@@ -145,3 +158,23 @@ VPEAlgoErrCode VpeVideo::RenderOutputBufferAtTime([[maybe_unused]] uint32_t inde
|
||||
{
|
||||
return VPE_ALGO_ERR_OK;
|
||||
}
|
||||
|
||||
int32_t VpeVideo::RegisterSettingsChangeCallback(uint32_t type, SettingsChangeCallback callback)
|
||||
{
|
||||
auto it = g_registerSettingsChangeCallback.find(type);
|
||||
if (it == g_registerSettingsChangeCallback.end()) {
|
||||
VPE_LOGE("Unsupported type: 0x%{public}x", type);
|
||||
return VPE_ALGO_ERR_INVALID_PARAM;
|
||||
}
|
||||
return it->second(callback);
|
||||
}
|
||||
|
||||
int32_t VpeVideo::UnregisterSettingsChangeCallback(uint32_t type)
|
||||
{
|
||||
auto it = g_unregisterSettingsChangeCallback.find(type);
|
||||
if (it == g_unregisterSettingsChangeCallback.end()) {
|
||||
VPE_LOGE("Unsupported type: 0x%{public}x", type);
|
||||
return VPE_ALGO_ERR_INVALID_PARAM;
|
||||
}
|
||||
return it->second();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace Media {
|
||||
namespace VideoProcessingEngine {
|
||||
class __attribute__((visibility("default"))) VpeVideo {
|
||||
public:
|
||||
using SettingsChangeCallback = std::function<void(int32_t feature, int32_t tag, int32_t param)>;
|
||||
/**
|
||||
* @brief Create a VpeVideo object.
|
||||
* @param type Use VIDEO_TYPE_XXX to specify the processing type. For details, see {@link VpeVideoType}.
|
||||
@@ -57,6 +58,9 @@ public:
|
||||
*/
|
||||
static bool IsSupported(void);
|
||||
|
||||
static int32_t RegisterSettingsChangeCallback(uint32_t type, SettingsChangeCallback callback);
|
||||
static int32_t UnregisterSettingsChangeCallback(uint32_t type);
|
||||
|
||||
/**
|
||||
* @brief Register callback object.
|
||||
* @param callback Callback object to be registered. For details, see {@link VpeVideoCallback}.
|
||||
|
||||
@@ -35,7 +35,7 @@ static napi_value Export(napi_env env, napi_value exports)
|
||||
/*
|
||||
* module define
|
||||
*/
|
||||
static napi_module videoProcessingModule = {
|
||||
static napi_module videoProcessingEngineModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
@@ -48,9 +48,9 @@ static napi_module videoProcessingModule = {
|
||||
/*
|
||||
* module register
|
||||
*/
|
||||
extern "C" __attribute__((constructor)) void VideoProcessingModule(void)
|
||||
extern "C" __attribute__((constructor)) void RegisterVideoProcessingEngineModule(void)
|
||||
{
|
||||
napi_module_register(&videoProcessingModule);
|
||||
napi_module_register(&videoProcessingEngineModule);
|
||||
}
|
||||
} // namespace Media
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "native_module_ohos_video_processing.h"
|
||||
#include "video_processor_napi.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Media {
|
||||
/*
|
||||
* Function registering all props and functions of multimedia.videoProcessing module
|
||||
*/
|
||||
static napi_value Export(napi_env env, napi_value exports)
|
||||
{
|
||||
VideoProcessorNapi::Init(env, exports);
|
||||
return exports;
|
||||
}
|
||||
|
||||
/*
|
||||
* module define
|
||||
*/
|
||||
static napi_module videoProcessingModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = Export,
|
||||
.nm_modname = "multimedia.videoProcessing",
|
||||
.nm_priv = nullptr,
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
/*
|
||||
* module register
|
||||
*/
|
||||
extern "C" __attribute__((constructor)) void RegisterVideoProcessingModule(void)
|
||||
{
|
||||
napi_module_register(&videoProcessingModule);
|
||||
}
|
||||
} // namespace Media
|
||||
} // namespace OHOS
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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 NATIVE_MODULE_OHOS_VIDEO_PROCESSING_H
|
||||
#define NATIVE_MODULE_OHOS_VIDEO_PROCESSING_H
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef LOG_DOMAIN
|
||||
#define LOG_DOMAIN 0xD002B3F
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "VideoProcessorNapi"
|
||||
|
||||
#include "video_processor_napi.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "algorithm_video.h"
|
||||
#include "video_processing_types.h"
|
||||
#include "vpe_log.h"
|
||||
#include "vpe_trace.h"
|
||||
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t NUM_1 = 1;
|
||||
const char VIDEO_PROCESSOR_CLASS_NAME[] = "VideoProcessor";
|
||||
}
|
||||
|
||||
namespace OHOS {
|
||||
namespace Media {
|
||||
using namespace VideoProcessingEngine;
|
||||
using namespace std::chrono;
|
||||
thread_local napi_ref VideoProcessorNapi::constructor_ = nullptr;
|
||||
std::vector<napi_ref> VideoProcessorNapi::g_statusCallbacks{};
|
||||
std::mutex VideoProcessorNapi::g_statusCallbacksLock{};
|
||||
napi_threadsafe_function VideoProcessorNapi::g_statusTsfn = nullptr;
|
||||
|
||||
struct StatusCallbackData {
|
||||
bool aiHdrEnabled;
|
||||
};
|
||||
|
||||
void VideoProcessorNapi::ThrowExceptionError(napi_env env, const int32_t errCode, const std::string errMsg)
|
||||
{
|
||||
std::string errCodeStr = std::to_string(errCode);
|
||||
napi_throw_error(env, errCodeStr.c_str(), errMsg.c_str());
|
||||
}
|
||||
|
||||
napi_value VideoProcessorNapi::Constructor(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_status status;
|
||||
napi_value thisVar = nullptr;
|
||||
size_t argc = NUM_1;
|
||||
napi_value argv[NUM_1] = {0};
|
||||
status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
|
||||
if (status != napi_ok || thisVar == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
VideoProcessorNapi* pVideoProcessorNapi = new VideoProcessorNapi();
|
||||
CHECK_AND_RETURN_RET_LOG(pVideoProcessorNapi != nullptr, nullptr, "pVideoProcessorNapi == nullptr");
|
||||
status = napi_wrap_with_size(env, thisVar, reinterpret_cast<void*>(pVideoProcessorNapi),
|
||||
VideoProcessorNapi::Destructor, nullptr, nullptr, static_cast<size_t>(sizeof(VideoProcessorNapi)));
|
||||
CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failure wrapping js to native napi");
|
||||
return thisVar;
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::Destructor(napi_env env, void* nativeObject, void* finalize)
|
||||
{
|
||||
if (nativeObject != nullptr) {
|
||||
delete reinterpret_cast<VideoProcessorNapi*>(nativeObject);
|
||||
nativeObject = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_value BuildStatusObject(napi_env env, bool aiHdrEnabled)
|
||||
{
|
||||
napi_value jsStatus = nullptr;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_create_object(env, &jsStatus) == napi_ok, nullptr,
|
||||
"BuildStatusObject: create jsStatus failed");
|
||||
napi_value jsAiHdrStatus;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_create_object(env, &jsAiHdrStatus) == napi_ok, nullptr,
|
||||
"BuildStatusObject: create jsAiHdrStatus failed");
|
||||
napi_value jsAiHdrEnabled;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_get_boolean(env, aiHdrEnabled, &jsAiHdrEnabled) == napi_ok, nullptr,
|
||||
"BuildStatusObject: get boolean failed");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_set_named_property(env, jsAiHdrStatus, "enabled", jsAiHdrEnabled) == napi_ok, nullptr,
|
||||
"BuildStatusObject: set enabled failed");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_set_named_property(env, jsStatus, "aiHdr", jsAiHdrStatus) == napi_ok, nullptr,
|
||||
"BuildStatusObject: set aiHdr failed");
|
||||
return jsStatus;
|
||||
}
|
||||
|
||||
static void InvokeCallback(napi_env env, napi_ref callbackRef, napi_value jsStatus)
|
||||
{
|
||||
CHECK_AND_RETURN_LOG(jsStatus != nullptr, "jsStatus is nullptr");
|
||||
napi_value global;
|
||||
CHECK_AND_RETURN_LOG(napi_get_global(env, &global) == napi_ok, "InvokeCallback: get global failed");
|
||||
napi_value callbackFunc;
|
||||
CHECK_AND_RETURN_LOG(napi_get_reference_value(env, callbackRef, &callbackFunc) == napi_ok,
|
||||
"InvokeCallback: get reference value failed");
|
||||
napi_value argv[NUM_1] = {jsStatus};
|
||||
napi_value callbackResult;
|
||||
CHECK_AND_RETURN_LOG(napi_call_function(env, global, callbackFunc, NUM_1, argv, &callbackResult) == napi_ok,
|
||||
"InvokeCallback: call function failed");
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::NotifyCallback(napi_env env, napi_ref callbackRef, bool aiHdrEnabled)
|
||||
{
|
||||
napi_value jsStatus = BuildStatusObject(env, aiHdrEnabled);
|
||||
CHECK_AND_RETURN_LOG(jsStatus != nullptr, "NotifyCallback: jsStatus is nullptr");
|
||||
InvokeCallback(env, callbackRef, jsStatus);
|
||||
VPE_LOGI("NotifyCallback: aiHdrEnabled=%{public}d", aiHdrEnabled);
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::StatusTsfnCallJs(napi_env env, napi_value jsCallback, void* context, void* data)
|
||||
{
|
||||
std::unique_ptr<StatusCallbackData> callbackDataPtr;
|
||||
CHECK_AND_RETURN_LOG(data != nullptr, "StatusTsfnCallJs data is nullptr");
|
||||
callbackDataPtr.reset(static_cast<StatusCallbackData*>(data));
|
||||
napi_value jsStatus = BuildStatusObject(env, callbackDataPtr->aiHdrEnabled);
|
||||
CHECK_AND_RETURN_LOG(jsStatus != nullptr, "StatusTsfnCallJs: jsStatus is nullptr");
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_statusCallbacksLock);
|
||||
for (auto& callbackRef : g_statusCallbacks) {
|
||||
InvokeCallback(env, callbackRef, jsStatus);
|
||||
}
|
||||
VPE_LOGI("StatusTsfnCallJs: aiHdrEnabled=%{public}d, callbackCount=%{public}zu",
|
||||
callbackDataPtr->aiHdrEnabled, g_statusCallbacks.size());
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::StatusTsfnFinalize(napi_env env, void* data, void* hint)
|
||||
{
|
||||
VPE_LOGI("StatusTsfnFinalize");
|
||||
}
|
||||
|
||||
napi_value VideoProcessorNapi::GetStatus(napi_env env, napi_callback_info info)
|
||||
{
|
||||
VPETrace vpeTrace("VideoProcessorNapi::GetStatus");
|
||||
napi_value result;
|
||||
napi_get_undefined(env, &result);
|
||||
napi_deferred deferred;
|
||||
napi_value promise;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_create_promise(env, &deferred, &promise) == napi_ok, result,
|
||||
"GetStatus: create promise failed");
|
||||
napi_value jsStatus;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_create_object(env, &jsStatus) == napi_ok, result,
|
||||
"GetStatus: create jsStatus failed");
|
||||
napi_value jsAiHdrStatus;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_create_object(env, &jsAiHdrStatus) == napi_ok, result,
|
||||
"GetStatus: create jsAiHdrStatus failed");
|
||||
Media::Format parameter{};
|
||||
bool aiHdrEnabled = VpeVideo::IsSupported(VIDEO_TYPE_AIHDR_ENHANCER, parameter);
|
||||
napi_value jsAiHdrEnabled;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_get_boolean(env, aiHdrEnabled, &jsAiHdrEnabled) == napi_ok, result,
|
||||
"GetStatus: get boolean failed");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_set_named_property(env, jsAiHdrStatus, "enabled", jsAiHdrEnabled) == napi_ok, result,
|
||||
"GetStatus: set enabled failed");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_set_named_property(env, jsStatus, "aiHdr", jsAiHdrStatus) == napi_ok, result,
|
||||
"GetStatus: set aiHdr failed");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_resolve_deferred(env, deferred, jsStatus) == napi_ok, result,
|
||||
"GetStatus: resolve deferred failed");
|
||||
VPE_LOGI("GetStatus: aiHdrEnabled=%{public}d", aiHdrEnabled);
|
||||
return promise;
|
||||
}
|
||||
|
||||
bool VideoProcessorNapi::ValidateCallback(napi_env env, napi_value callbackValue)
|
||||
{
|
||||
napi_valuetype callbackType;
|
||||
napi_typeof(env, callbackValue, &callbackType);
|
||||
if (callbackType != napi_function) {
|
||||
VPE_LOGE("Callback arg is not function");
|
||||
ThrowExceptionError(env, VIDEO_PROCESSING_ERROR_INVALID_VALUE, "Callback arg is not function");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::RegisterObserver(napi_env env)
|
||||
{
|
||||
CHECK_AND_RETURN_LOG(g_statusTsfn == nullptr, "RegisterObserver: already registered");
|
||||
napi_value cbName;
|
||||
std::string callbackName = "StatusChange";
|
||||
CHECK_AND_RETURN_LOG(napi_create_string_utf8(env, callbackName.c_str(), callbackName.length(), &cbName) == napi_ok,
|
||||
"RegisterObserverIf: create string failed");
|
||||
CHECK_AND_RETURN_LOG(napi_create_threadsafe_function(env, nullptr, nullptr, cbName, 0,
|
||||
1, nullptr, StatusTsfnFinalize, nullptr, StatusTsfnCallJs, &g_statusTsfn) == napi_ok,
|
||||
"RegisterObserverIf: create threadsafe function failed");
|
||||
napi_threadsafe_function tsfnCopy = g_statusTsfn;
|
||||
VpeVideo::RegisterSettingsChangeCallback(VIDEO_TYPE_AIHDR_ENHANCER,
|
||||
[tsfnCopy](int32_t feature, int32_t tag, int32_t param) {
|
||||
VPE_LOGI("Settings changed, calling TSFN");
|
||||
auto* callbackData = new StatusCallbackData{(param != 0)};
|
||||
if (tsfnCopy != nullptr) {
|
||||
napi_call_threadsafe_function(tsfnCopy, callbackData, napi_tsfn_blocking);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::UnregisterObserver()
|
||||
{
|
||||
if (g_statusCallbacks.empty()) {
|
||||
VpeVideo::UnregisterSettingsChangeCallback(VIDEO_TYPE_AIHDR_ENHANCER);
|
||||
if (g_statusTsfn != nullptr) {
|
||||
napi_release_threadsafe_function(g_statusTsfn, napi_tsfn_release);
|
||||
g_statusTsfn = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
napi_value VideoProcessorNapi::OnStatusChange(napi_env env, napi_callback_info info)
|
||||
{
|
||||
VPETrace vpeTrace("VideoProcessorNapi::OnStatusChange");
|
||||
napi_value result;
|
||||
napi_get_undefined(env, &result);
|
||||
size_t argc = NUM_1;
|
||||
napi_value argv[NUM_1] = {0};
|
||||
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
|
||||
if (argc != NUM_1 || !ValidateCallback(env, argv[0])) {
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_ref callbackRef = nullptr;
|
||||
if (napi_create_reference(env, argv[0], 1, &callbackRef) != napi_ok) {
|
||||
VPE_LOGE("Create callback reference failed");
|
||||
ThrowExceptionError(env, VIDEO_PROCESSING_ERROR_INVALID_VALUE, "Create callback reference failed");
|
||||
return result;
|
||||
}
|
||||
size_t callbackSize = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_statusCallbacksLock);
|
||||
if (g_statusCallbacks.empty()) {
|
||||
RegisterObserver(env);
|
||||
}
|
||||
g_statusCallbacks.push_back(callbackRef);
|
||||
callbackSize = g_statusCallbacks.size();
|
||||
}
|
||||
Media::Format parameter{};
|
||||
bool aiHdrEnabled = VpeVideo::IsSupported(VIDEO_TYPE_AIHDR_ENHANCER, parameter);
|
||||
NotifyCallback(env, callbackRef, aiHdrEnabled);
|
||||
VPE_LOGI("OnStatusChange done, callbackCount=%{public}zu", callbackSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
void VideoProcessorNapi::RemoveCallbackRef(napi_env env, napi_value callback)
|
||||
{
|
||||
auto it = std::find_if(g_statusCallbacks.begin(), g_statusCallbacks.end(),
|
||||
[env, callback](napi_ref ref) {
|
||||
napi_value refFunc;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_get_reference_value(env, ref, &refFunc) == napi_ok, false,
|
||||
"RemoveCallbackRef: get reference value failed");
|
||||
bool isEqual = false;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_strict_equals(env, callback, refFunc, &isEqual) == napi_ok, false,
|
||||
"RemoveCallbackRef: strict equals failed");
|
||||
return isEqual;
|
||||
});
|
||||
CHECK_AND_RETURN_LOG(it != g_statusCallbacks.end(), "RemoveCallbackRef: callback not found");
|
||||
CHECK_AND_RETURN_LOG(napi_delete_reference(env, *it) == napi_ok,
|
||||
"RemoveCallbackRef: delete reference failed");
|
||||
g_statusCallbacks.erase(it);
|
||||
}
|
||||
|
||||
napi_value VideoProcessorNapi::OffStatusChange(napi_env env, napi_callback_info info)
|
||||
{
|
||||
VPETrace vpeTrace("VideoProcessorNapi::OffStatusChange");
|
||||
napi_value result;
|
||||
napi_get_undefined(env, &result);
|
||||
size_t argc = NUM_1;
|
||||
napi_value argv[NUM_1] = {0};
|
||||
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
|
||||
if (argc > NUM_1) {
|
||||
VPE_LOGE("Invalid args count %{public}zu", argc);
|
||||
ThrowExceptionError(env, VIDEO_PROCESSING_ERROR_INVALID_VALUE, "Invalid args count");
|
||||
return result;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_statusCallbacksLock);
|
||||
if (argc == NUM_1) {
|
||||
if (!ValidateCallback(env, argv[0])) {
|
||||
return result;
|
||||
}
|
||||
RemoveCallbackRef(env, argv[0]);
|
||||
} else {
|
||||
for (auto& ref : g_statusCallbacks) {
|
||||
napi_delete_reference(env, ref);
|
||||
}
|
||||
g_statusCallbacks.clear();
|
||||
}
|
||||
UnregisterObserver();
|
||||
VPE_LOGI("OffStatusChange done, remainingCallbacks=%{public}zu", g_statusCallbacks.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value VideoProcessorNapi::Init(napi_env env, napi_value exports)
|
||||
{
|
||||
napi_property_descriptor props[] = {
|
||||
DECLARE_NAPI_FUNCTION("getStatus", VideoProcessorNapi::GetStatus),
|
||||
DECLARE_NAPI_FUNCTION("onStatusChange", VideoProcessorNapi::OnStatusChange),
|
||||
DECLARE_NAPI_FUNCTION("offStatusChange", VideoProcessorNapi::OffStatusChange)
|
||||
};
|
||||
|
||||
napi_value constructor = nullptr;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_define_class(env, VIDEO_PROCESSOR_CLASS_NAME, sizeof(VIDEO_PROCESSOR_CLASS_NAME),
|
||||
VideoProcessorNapi::Constructor, nullptr, sizeof(props) / sizeof(props[0]), props, &constructor) == napi_ok,
|
||||
nullptr, "define class fail");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_set_named_property(env, exports, VIDEO_PROCESSOR_CLASS_NAME, constructor) == napi_ok,
|
||||
nullptr, "set named property fail");
|
||||
CHECK_AND_RETURN_RET_LOG(napi_create_reference(env, constructor, 1, &constructor_) == napi_ok,
|
||||
nullptr, "create reference fail");
|
||||
napi_property_descriptor moduleFuncs[] = {
|
||||
DECLARE_NAPI_FUNCTION("createVideoProcessor", VideoProcessorNapi::CreateVideoProcessor),
|
||||
};
|
||||
napi_define_properties(env, exports, sizeof(moduleFuncs) / sizeof(moduleFuncs[0]), moduleFuncs);
|
||||
return exports;
|
||||
}
|
||||
|
||||
napi_value VideoProcessorNapi::CreateVideoProcessor(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value result = nullptr;
|
||||
napi_value constructor = nullptr;
|
||||
CHECK_AND_RETURN_RET_LOG(napi_get_reference_value(env, constructor_, &constructor) == napi_ok,
|
||||
nullptr, "CreateVideoProcessor: get constructor failed");
|
||||
size_t argc = NUM_1;
|
||||
napi_value argv[NUM_1] = {0};
|
||||
CHECK_AND_RETURN_RET_LOG(napi_new_instance(env, constructor, argc, argv, &result) == napi_ok,
|
||||
nullptr, "CreateVideoProcessor: new instance failed");
|
||||
VPE_LOGI("create done");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 VIDEO_PROCESSOR_NAPI_H
|
||||
#define VIDEO_PROCESSOR_NAPI_H
|
||||
|
||||
#include "algorithm_video.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Media {
|
||||
|
||||
class VideoProcessorNapi {
|
||||
public:
|
||||
VideoProcessorNapi() = default;
|
||||
~VideoProcessorNapi() = default;
|
||||
|
||||
static napi_value Init(napi_env env, napi_value exports);
|
||||
static napi_value CreateVideoProcessor(napi_env env, napi_callback_info info);
|
||||
static napi_value GetStatus(napi_env env, napi_callback_info info);
|
||||
static napi_value OnStatusChange(napi_env env, napi_callback_info info);
|
||||
static napi_value OffStatusChange(napi_env env, napi_callback_info info);
|
||||
|
||||
private:
|
||||
static thread_local napi_ref constructor_;
|
||||
static std::vector<napi_ref> g_statusCallbacks;
|
||||
static std::mutex g_statusCallbacksLock;
|
||||
static napi_threadsafe_function g_statusTsfn;
|
||||
|
||||
static napi_value Constructor(napi_env env, napi_callback_info info);
|
||||
static void Destructor(napi_env env, void* nativeObject, void* finalize);
|
||||
static void ThrowExceptionError(napi_env env, const int32_t errCode, const std::string errMsg);
|
||||
static void NotifyCallback(napi_env env, napi_ref callbackRef, bool aiHdrEnabled);
|
||||
static void StatusTsfnCallJs(napi_env env, napi_value jsCallback, void* context, void* data);
|
||||
static void StatusTsfnFinalize(napi_env env, void* data, void* hint);
|
||||
|
||||
static bool ValidateCallback(napi_env env, napi_value callbackValue);
|
||||
static void RegisterObserver(napi_env env);
|
||||
static void UnregisterObserver();
|
||||
static void RemoveCallbackRef(napi_env env, napi_value callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -18,8 +18,10 @@ import("//foundation/multimedia/video_processing_engine/config.gni")
|
||||
|
||||
subsystem_name = "multimedia"
|
||||
part_name = "video_processing_engine"
|
||||
taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name"
|
||||
|
||||
# =============== videoProcessingEngine Module ===============
|
||||
videoProcessingEngine = "videoProcessingEngine"
|
||||
video_processing_engine_taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name/$videoProcessingEngine"
|
||||
config("video_processing_engine_taihe_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [ "include" ]
|
||||
@@ -36,17 +38,17 @@ copy_taihe_idl("copy_video_processing_engine_taihe") {
|
||||
}
|
||||
|
||||
ohos_taihe("run_taihe") {
|
||||
taihe_generated_file_path = "$taihe_generated_file_path"
|
||||
taihe_generated_file_path = "$video_processing_engine_taihe_generated_file_path"
|
||||
deps = [ ":copy_video_processing_engine_taihe" ]
|
||||
outputs = [
|
||||
"$taihe_generated_file_path/src/ohos.multimedia.videoProcessingEngine.ani.cpp",
|
||||
"$taihe_generated_file_path/src/ohos.multimedia.videoProcessingEngine.abi.c",
|
||||
"$video_processing_engine_taihe_generated_file_path/src/ohos.multimedia.videoProcessingEngine.ani.cpp",
|
||||
"$video_processing_engine_taihe_generated_file_path/src/ohos.multimedia.videoProcessingEngine.abi.c",
|
||||
]
|
||||
}
|
||||
|
||||
generate_static_abc("video_processing_engine_taihe_abc") {
|
||||
base_url = "$taihe_generated_file_path"
|
||||
files = [ "$taihe_generated_file_path/@ohos.multimedia.videoProcessingEngine.ets" ]
|
||||
base_url = "$video_processing_engine_taihe_generated_file_path"
|
||||
files = [ "$video_processing_engine_taihe_generated_file_path/@ohos.multimedia.videoProcessingEngine.ets" ]
|
||||
is_boot_abc = "True"
|
||||
device_dst_file = "/system/framework/video_processing_engine_taihe_abc.abc"
|
||||
dependencies = [ ":run_taihe" ]
|
||||
@@ -72,7 +74,7 @@ group("video_processing_engine_taihe_gen_only") {
|
||||
}
|
||||
|
||||
taihe_shared_library("video_processing_engine_taihe") {
|
||||
taihe_generated_file_path = "$taihe_generated_file_path"
|
||||
taihe_generated_file_path = "$video_processing_engine_taihe_generated_file_path"
|
||||
subsystem_name = "$subsystem_name"
|
||||
part_name = "$part_name"
|
||||
|
||||
@@ -113,6 +115,7 @@ taihe_shared_library("video_processing_engine_taihe") {
|
||||
"media_foundation:native_media_core",
|
||||
"media_foundation:media_foundation",
|
||||
"runtime_core:ani_helpers",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
@@ -131,7 +134,7 @@ taihe_shared_library("video_processing_engine_taihe") {
|
||||
}
|
||||
|
||||
taihe_shared_library("video_processing_engine_taihe_core") {
|
||||
taihe_generated_file_path = "$taihe_generated_file_path"
|
||||
taihe_generated_file_path = "$video_processing_engine_taihe_generated_file_path"
|
||||
subsystem_name = "$subsystem_name"
|
||||
part_name = "$part_name"
|
||||
shlib_type = "ani"
|
||||
@@ -147,4 +150,108 @@ taihe_shared_library("video_processing_engine_taihe_core") {
|
||||
ubsan = true
|
||||
debug = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# =============== videoProcessing Module ===============
|
||||
videoProcessing = "videoProcessing"
|
||||
video_processing_taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name/$videoProcessing"
|
||||
config("video_processing_taihe_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
copy_taihe_idl("copy_video_processing_taihe") {
|
||||
sources = [
|
||||
"$INTERFACES_DIR/kits/taihe/idl/ohos.multimedia.videoProcessing.taihe",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_taihe("run_taihe_video_processing") {
|
||||
taihe_generated_file_path = "$video_processing_taihe_generated_file_path"
|
||||
deps = [ ":copy_video_processing_taihe" ]
|
||||
outputs = [
|
||||
"$video_processing_taihe_generated_file_path/src/ohos.multimedia.videoProcessing.ani.cpp",
|
||||
"$video_processing_taihe_generated_file_path/src/ohos.multimedia.videoProcessing.abi.c",
|
||||
]
|
||||
}
|
||||
|
||||
generate_static_abc("video_processing_taihe_abc") {
|
||||
base_url = "$video_processing_taihe_generated_file_path"
|
||||
files = [ "$video_processing_taihe_generated_file_path/@ohos.multimedia.videoProcessing.ets" ]
|
||||
is_boot_abc = "True"
|
||||
device_dst_file = "/system/framework/video_processing_taihe_abc.abc"
|
||||
dependencies = [ ":run_taihe_video_processing" ]
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("video_processing_etc") {
|
||||
source = "$target_out_dir/video_processing_taihe_abc.abc"
|
||||
module_install_dir = "framework"
|
||||
part_name = "$part_name"
|
||||
subsystem_name = "$subsystem_name"
|
||||
deps = [ ":video_processing_taihe_abc" ]
|
||||
}
|
||||
|
||||
group("video_processing_taihe_gen_only") {
|
||||
deps = [ ":run_taihe_video_processing" ]
|
||||
}
|
||||
|
||||
group("video_processing_taihe_group") {
|
||||
deps = [
|
||||
":video_processing_etc",
|
||||
":video_processing_taihe_native",
|
||||
]
|
||||
}
|
||||
|
||||
taihe_shared_library("video_processing_taihe_native") {
|
||||
taihe_generated_file_path = "$video_processing_taihe_generated_file_path"
|
||||
subsystem_name = "$subsystem_name"
|
||||
part_name = "$part_name"
|
||||
public_configs = [ ":video_processing_taihe_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"$DFX_DIR/include",
|
||||
"$INTERFACES_DIR/kits/js",
|
||||
"$INTERFACES_INNER_API_DIR",
|
||||
"$CAPI_DIR/image_processing/include/",
|
||||
"$ALGORITHM_COMMON_DIR/include/",
|
||||
"$INTERFACES_CAPI_DIR",
|
||||
]
|
||||
|
||||
sources = get_target_outputs(":run_taihe_video_processing")
|
||||
sources += [
|
||||
"src/video_processing_taihe.cpp",
|
||||
"src/video_processing_ani_constructor.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":run_taihe_video_processing",
|
||||
"$VIDEO_PROCESSING_ENGINE_ROOT_DIR/framework:videoprocessingengine",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"drivers_interface_display:libdisplay_commontype_proxy_2.1",
|
||||
"hilog:libhilog",
|
||||
"hitrace:hitrace_meter",
|
||||
"ipc:ipc_napi",
|
||||
"media_foundation:native_media_core",
|
||||
"media_foundation:media_foundation",
|
||||
"runtime_core:ani_helpers",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
"-DIMAGE_DEBUG_FLAG",
|
||||
"-DIMAGE_COLORSPACE_FLAG",
|
||||
]
|
||||
|
||||
sanitize = {
|
||||
boundary_sanitize = true
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
integer_overflow = true
|
||||
ubsan = true
|
||||
debug = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2026 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.
|
||||
*/
|
||||
|
||||
@!namespace("@ohos.multimedia.videoProcessing", "videoProcessing")
|
||||
@!sts_export_default
|
||||
@!sts_inject("""
|
||||
static { loadLibraryWithPermissionCheck("video_processing_taihe_native.z", "@ohos.multimedia.videoProcessing"); }
|
||||
""")
|
||||
|
||||
struct VideoProcessorAiHdrStatus {
|
||||
@optional enabled: Optional<bool>;
|
||||
}
|
||||
|
||||
struct VideoProcessorStatus {
|
||||
@optional aiHdr: Optional<VideoProcessorAiHdrStatus>;
|
||||
}
|
||||
|
||||
interface VideoProcessor {
|
||||
@rename("getStatus") @promise GetStatus(): VideoProcessorStatus;
|
||||
@rename("onStatusChange") OnStatusChange(callback: (status: VideoProcessorStatus) => void): void;
|
||||
@rename("offStatusChange") OffStatusChange(@optional callback: Optional<(status: VideoProcessorStatus) => void>): void;
|
||||
}
|
||||
|
||||
function createVideoProcessor(): VideoProcessor;
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2026 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 FRAMEWORKS_KITS_TAIHE_INCLUDE_VIDEO_PROCESSING_TAIHE_H
|
||||
#define FRAMEWORKS_KITS_TAIHE_INCLUDE_VIDEO_PROCESSING_TAIHE_H
|
||||
|
||||
#include "ohos.multimedia.videoProcessing.impl.hpp"
|
||||
#include "ohos.multimedia.videoProcessing.proj.hpp"
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "taihe/runtime.hpp"
|
||||
|
||||
namespace ANI::Vp {
|
||||
using namespace taihe;
|
||||
namespace taiheVp = ::ohos::multimedia::videoProcessing;
|
||||
|
||||
class VideoProcessorImpl {
|
||||
public:
|
||||
VideoProcessorImpl() = default;
|
||||
~VideoProcessorImpl() = default;
|
||||
|
||||
taiheVp::VideoProcessorStatus GetStatus();
|
||||
void OnStatusChange(
|
||||
taihe::callback_view<void(const taiheVp::VideoProcessorStatus&)> callback);
|
||||
void OffStatusChange(
|
||||
taihe::optional_view<taihe::callback<void(const taiheVp::VideoProcessorStatus&)>> callback);
|
||||
|
||||
private:
|
||||
bool GetCurrentAiHdrEnabled();
|
||||
void TriggerSingleCallback(const taihe::callback<void(const taiheVp::VideoProcessorStatus&)>& callback,
|
||||
bool aiHdrEnabled);
|
||||
void StatusChangeCallback(int32_t feature, int32_t tag, int32_t param);
|
||||
|
||||
static std::vector<taihe::callback<void(const taiheVp::VideoProcessorStatus&)>> g_statusCallbacks;
|
||||
static std::mutex g_statusCallbacksLock;
|
||||
static bool g_isListenerRegistered;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2026 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.
|
||||
*/
|
||||
|
||||
#include "ohos.multimedia.videoProcessing.ani.hpp"
|
||||
#if __has_include(<ani.h>)
|
||||
#include <ani.h>
|
||||
#elif __has_include(<ani/ani.h>)
|
||||
#include <ani/ani.h>
|
||||
#else
|
||||
#error "ani.h not found. Please ensure the Ani SDK is correctly installed."
|
||||
#endif
|
||||
|
||||
ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result)
|
||||
{
|
||||
ani_env* env;
|
||||
if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
|
||||
return ANI_ERROR;
|
||||
}
|
||||
ani_status status = ANI_OK;
|
||||
if (ANI_OK != ohos::multimedia::videoProcessing::ANIRegister(env)) {
|
||||
std::cerr << "Error from ohos::multimedia::videoProcessing::ANIRegister" << std::endl;
|
||||
status = ANI_ERROR;
|
||||
}
|
||||
*result = ANI_VERSION_1;
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2026 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.
|
||||
*/
|
||||
|
||||
#include "video_processing_taihe.h"
|
||||
#include "algorithm_video.h"
|
||||
#include "vpe_log.h"
|
||||
#include "vpe_trace.h"
|
||||
#include "taihe/runtime.hpp"
|
||||
|
||||
using namespace taihe;
|
||||
using namespace OHOS::Media::VideoProcessingEngine;
|
||||
using namespace ANI;
|
||||
using namespace ANI::Vp;
|
||||
|
||||
namespace ANI::Vp {
|
||||
std::vector<taihe::callback<void(const taiheVp::VideoProcessorStatus&)>> VideoProcessorImpl::g_statusCallbacks;
|
||||
std::mutex VideoProcessorImpl::g_statusCallbacksLock;
|
||||
|
||||
taiheVp::VideoProcessor createVideoProcessor()
|
||||
{
|
||||
return taihe::make_holder<VideoProcessorImpl, taiheVp::VideoProcessor>();
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoProcessorImpl::GetCurrentAiHdrEnabled()
|
||||
{
|
||||
OHOS::Media::Format parameter;
|
||||
return VpeVideo::IsSupported(VIDEO_TYPE_AIHDR_ENHANCER, parameter);
|
||||
}
|
||||
|
||||
void VideoProcessorImpl::StatusChangeCallback(int32_t feature, int32_t tag, int32_t param)
|
||||
{
|
||||
VPE_LOGI("StatusChangeCallback: feature=%{public}d, param=%{public}d", feature, param);
|
||||
bool aiHdrEnabled = (param != 0);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_statusCallbacksLock);
|
||||
taiheVp::VideoProcessorAiHdrStatus aiHdrStatus;
|
||||
aiHdrStatus.enabled.emplace(aiHdrEnabled);
|
||||
taiheVp::VideoProcessorStatus status;
|
||||
status.aiHdr.emplace(aiHdrStatus);
|
||||
for (auto& callback : g_statusCallbacks) {
|
||||
callback(status);
|
||||
}
|
||||
VPE_LOGI("StatusChangeCallback: notified %{public}zu callbacks, aiHdrEnabled=%{public}d",
|
||||
g_statusCallbacks.size(), aiHdrEnabled);
|
||||
}
|
||||
|
||||
void VideoProcessorImpl::TriggerSingleCallback(
|
||||
const taihe::callback<void(const taiheVp::VideoProcessorStatus&)>& callback, bool aiHdrEnabled)
|
||||
{
|
||||
taiheVp::VideoProcessorAiHdrStatus aiHdrStatus;
|
||||
aiHdrStatus.enabled.emplace(aiHdrEnabled);
|
||||
taiheVp::VideoProcessorStatus status;
|
||||
status.aiHdr.emplace(aiHdrStatus);
|
||||
callback(status);
|
||||
VPE_LOGI("TriggerSingleCallback: aiHdrEnabled=%{public}d", aiHdrEnabled);
|
||||
}
|
||||
|
||||
taiheVp::VideoProcessorStatus VideoProcessorImpl::GetStatus()
|
||||
{
|
||||
taiheVp::VideoProcessorAiHdrStatus aiHdrStatus;
|
||||
bool aiHdrEnabled = GetCurrentAiHdrEnabled();
|
||||
aiHdrStatus.enabled.emplace(aiHdrEnabled);
|
||||
taiheVp::VideoProcessorStatus status;
|
||||
status.aiHdr.emplace(aiHdrStatus);
|
||||
VPE_LOGI("GetStatus: aiHdrEnabled=%{public}d", aiHdrEnabled);
|
||||
return status;
|
||||
}
|
||||
|
||||
void VideoProcessorImpl::OnStatusChange(
|
||||
taihe::callback_view<void(const taiheVp::VideoProcessorStatus&)> callback)
|
||||
{
|
||||
VPETrace vpeTrace("VideoProcessorImpl::OnStatusChange");
|
||||
size_t callbackSize = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_statusCallbacksLock);
|
||||
if (g_statusCallbacks.empty()) {
|
||||
VpeVideo::RegisterSettingsChangeCallback(VIDEO_TYPE_AIHDR_ENHANCER,
|
||||
[this](int32_t feature, int32_t tag, int32_t param) {
|
||||
StatusChangeCallback(feature, tag, param);
|
||||
});
|
||||
}
|
||||
g_statusCallbacks.push_back(callback);
|
||||
callbackSize = g_statusCallbacks.size();
|
||||
}
|
||||
|
||||
bool aiHdrEnabled = GetCurrentAiHdrEnabled();
|
||||
TriggerSingleCallback(callback, aiHdrEnabled);
|
||||
VPE_LOGI("OnStatusChange done, callbackCount=%{public}zu", callbackSize);
|
||||
}
|
||||
|
||||
void VideoProcessorImpl::OffStatusChange(
|
||||
taihe::optional_view<taihe::callback<void(const taiheVp::VideoProcessorStatus&)>> callback)
|
||||
{
|
||||
VPETrace vpeTrace("VideoProcessorImpl::OffStatusChange");
|
||||
std::lock_guard<std::mutex> lock(g_statusCallbacksLock);
|
||||
if (callback.has_value()) {
|
||||
auto it = std::find_if(g_statusCallbacks.begin(), g_statusCallbacks.end(),
|
||||
[&callback](const taihe::callback<void(const taiheVp::VideoProcessorStatus&)>& item) {
|
||||
return item == callback.value();
|
||||
});
|
||||
if (it != g_statusCallbacks.end()) {
|
||||
g_statusCallbacks.erase(it);
|
||||
}
|
||||
} else {
|
||||
g_statusCallbacks.clear();
|
||||
}
|
||||
|
||||
if (g_statusCallbacks.empty()) {
|
||||
VpeVideo::UnregisterSettingsChangeCallback(VIDEO_TYPE_AIHDR_ENHANCER);
|
||||
}
|
||||
VPE_LOGI("OffStatusChange done, remainingCallbacks=%{public}zu", g_statusCallbacks.size());
|
||||
}
|
||||
|
||||
// NOLINTBEGIN
|
||||
TH_EXPORT_CPP_API_createVideoProcessor(createVideoProcessor);
|
||||
// NOLINTEND
|
||||
Reference in New Issue
Block a user