* Copyright (c) 2024 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.h"
#include <atomic>
#include <functional>
#include "auto_effect_aisr_video.h"
#include "native_avformat.h"
#include "video_processing_utils.h"
#include "vpe_log.h"
#include "video_processing_capi_capability.h"
#include "video_environment_native.h"
#include "video_processing_callback_impl.h"
#include "video_processing_impl.h"
using namespace OHOS::Media::VideoProcessingEngine;
const int32_t VIDEO_PROCESSING_TYPE_COLOR_SPACE_CONVERSION = 0x1;
const int32_t VIDEO_PROCESSING_TYPE_METADATA_GENERATION = 0x2;
const int32_t VIDEO_PROCESSING_TYPE_DETAIL_ENHANCER = 0x4;
const int32_t VIDEO_PROCESSING_TYPE_AUTOEFFECT_AISR = 0x8;
const char* VIDEO_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL = "QualityLevel";
const char* VIDEO_METADATA_GENERATOR_STYLE_CONTROL = "StyleControl";
const char* VIDEO_AUTOEFFECT_ENABLE = "enable";
const char* VIDEO_AUTOEFFECT_AISR_STRENGTH = "strength";
namespace {
VideoProcessing_ErrorCode CallVideoProcessing(OH_VideoProcessing* videoProcessor,
std::function<VideoProcessing_ErrorCode(std::shared_ptr<IVideoProcessingNative>&)>&& operation)
{
CHECK_AND_RETURN_RET_LOG(videoProcessor != nullptr, VIDEO_PROCESSING_ERROR_INVALID_INSTANCE,
"videoProcessor is null!");
auto videoProcessing = videoProcessor->GetVideoProcessing();
CHECK_AND_RETURN_RET_LOG(videoProcessing != nullptr, VIDEO_PROCESSING_ERROR_INVALID_INSTANCE,
"videoProcessor is invalid!");
return operation(videoProcessing);
}
VideoProcessing_ErrorCode CallVideoProcessingCallback(VideoProcessing_Callback* callback,
std::function<VideoProcessing_ErrorCode(std::shared_ptr<VideoProcessingCallbackNative>&)>&& operation)
{
CHECK_AND_RETURN_RET_LOG(callback != nullptr, VIDEO_PROCESSING_ERROR_INVALID_PARAMETER, "callback is null!");
auto innerCallback = callback->GetInnerCallback();
CHECK_AND_RETURN_RET_LOG(innerCallback != nullptr, VIDEO_PROCESSING_ERROR_INVALID_PARAMETER,
"callback is invalid!");
return operation(innerCallback);
}
}
VideoProcessing_ErrorCode OH_VideoProcessing_InitializeEnvironment(void)
{
CHECK_AND_RETURN_RET_LOG(VideoProcessingCapiCapability::OpenGLInit() == VIDEO_PROCESSING_SUCCESS,
VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED, "OpenGLInit failed!");
return VideoEnvironmentNative::Get().Initialize();
}
VideoProcessing_ErrorCode OH_VideoProcessing_DeinitializeEnvironment(void)
{
return VideoEnvironmentNative::Get().Deinitialize();
}
bool OH_VideoProcessing_IsColorSpaceConversionSupported(const VideoProcessing_ColorSpaceInfo* sourceVideoInfo,
const VideoProcessing_ColorSpaceInfo* destinationVideoInfo)
{
return VideoProcessingCapiCapability::IsColorSpaceConversionSupported(sourceVideoInfo, destinationVideoInfo);
}
bool OH_VideoProcessing_IsMetadataGenerationSupported(const VideoProcessing_ColorSpaceInfo* sourceVideoInfo)
{
return VideoProcessingCapiCapability::IsMetadataGenerationSupported(sourceVideoInfo);
}
VideoProcessing_ErrorCode OH_VideoProcessing_Create(OH_VideoProcessing** videoProcessor, int type)
{
return OH_VideoProcessing::Create(videoProcessor, type, VideoProcessingCapiCapability::GetOpenGLContext());
}
VideoProcessing_ErrorCode OH_VideoProcessing_Destroy(OH_VideoProcessing* videoProcessor)
{
return OH_VideoProcessing::Destroy(videoProcessor);
}
VideoProcessing_ErrorCode OH_VideoProcessing_RegisterCallback(OH_VideoProcessing* videoProcessor,
const VideoProcessing_Callback* callback, void* userData)
{
return CallVideoProcessing(videoProcessor, [&callback, &userData](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->RegisterCallback(callback, userData);
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_SetSurface(OH_VideoProcessing* videoProcessor,
const OHNativeWindow* window)
{
return CallVideoProcessing(videoProcessor, [&window](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->SetSurface(window);
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_GetSurface(OH_VideoProcessing* videoProcessor, OHNativeWindow** window)
{
return CallVideoProcessing(videoProcessor, [&window](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->GetSurface(window);
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_SetParameter(OH_VideoProcessing* videoProcessor,
const OH_AVFormat* parameter)
{
return CallVideoProcessing(videoProcessor, [¶meter](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->SetParameter(parameter);
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_GetParameter(OH_VideoProcessing* videoProcessor, OH_AVFormat* parameter)
{
return CallVideoProcessing(videoProcessor, [¶meter](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->GetParameter(parameter);
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_Start(OH_VideoProcessing* videoProcessor)
{
return CallVideoProcessing(videoProcessor, [](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->Start();
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_Stop(OH_VideoProcessing* videoProcessor)
{
return CallVideoProcessing(videoProcessor, [](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->Stop();
});
}
VideoProcessing_ErrorCode OH_VideoProcessing_RenderOutputBuffer(OH_VideoProcessing* videoProcessor, uint32_t index)
{
return CallVideoProcessing(videoProcessor, [&index](std::shared_ptr<IVideoProcessingNative>& obj) {
return obj->RenderOutputBuffer(index);
});
}
VideoProcessing_ErrorCode OH_VideoProcessingCallback_Create(VideoProcessing_Callback** callback)
{
return VideoProcessing_Callback::Create(callback);
}
VideoProcessing_ErrorCode OH_VideoProcessingCallback_Destroy(VideoProcessing_Callback* callback)
{
return VideoProcessing_Callback::Destroy(callback);
}
VideoProcessing_ErrorCode OH_VideoProcessingCallback_BindOnError(VideoProcessing_Callback* callback,
OH_VideoProcessingCallback_OnError onError)
{
return CallVideoProcessingCallback(callback, [&onError](std::shared_ptr<VideoProcessingCallbackNative>& obj) {
return obj->BindOnError(onError);
});
}
VideoProcessing_ErrorCode OH_VideoProcessingCallback_BindOnState(VideoProcessing_Callback* callback,
OH_VideoProcessingCallback_OnState onState)
{
return CallVideoProcessingCallback(callback, [&onState](std::shared_ptr<VideoProcessingCallbackNative>& obj) {
return obj->BindOnState(onState);
});
}
VideoProcessing_ErrorCode OH_VideoProcessingCallback_BindOnNewOutputBuffer(VideoProcessing_Callback* callback,
OH_VideoProcessingCallback_OnNewOutputBuffer onNewOutputBuffer)
{
return CallVideoProcessingCallback(callback,
[&onNewOutputBuffer](std::shared_ptr<VideoProcessingCallbackNative>& obj) {
return obj->BindOnNewOutputBuffer(onNewOutputBuffer);
});
}
bool OH_VideoProcessing_IsAutoEffectSupported(uint32_t type)
{
if (access("/system/lib64/libvideoprocessingengine_ext.z.so", 0)) {
return false;
}
if (type != VIDEO_PROCESSING_TYPE_AUTOEFFECT_AISR) {
VPE_LOGE("UseAutoEffect invalid type: 0x%{public}x", type);
return false;
}
return AutoEffectAisrVideo::IsProductSupported();
}
VideoProcessing_ErrorCode OH_VideoProcessing_UseAutoEffect(uint32_t type, bool enable, const char* name)
{
if (access("/system/lib64/libvideoprocessingengine_ext.z.so", 0)) {
return VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED;
}
if (type != VIDEO_PROCESSING_TYPE_AUTOEFFECT_AISR) {
return VIDEO_PROCESSING_ERROR_INVALID_VALUE;
}
if (!AutoEffectAisrVideo::IsProductSupported()) {
VPE_LOGE("UseAutoEffect: auto effect is not supported, type: 0x%{public}x", type);
return VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED;
}
return VideoProcessingUtils::InnerErrorToCAPI(
AutoEffectAisrVideo::UseAutoEffect(VIDEO_TYPE_AUTO_EFFECT_AISR, enable, name));
}
VideoProcessing_ErrorCode OH_VideoProcessing_SetAutoEffectParam(
uint32_t type, const char* name, const OH_AVFormat* param)
{
if (access("/system/lib64/libvideoprocessingengine_ext.z.so", 0)) {
return VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED;
}
VPE_LOGI("OH_VideoProcessing_SetAutoEffectParam start");
if (type != VIDEO_PROCESSING_TYPE_AUTOEFFECT_AISR) {
return VIDEO_PROCESSING_ERROR_INVALID_VALUE;
}
if (!AutoEffectAisrVideo::IsProductSupported()) {
VPE_LOGE("SetAutoEffectParam: auto effect is not supported, type: 0x%{public}x", type);
return VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED;
}
CHECK_AND_RETURN_RET_LOG(name != nullptr, VIDEO_PROCESSING_ERROR_INVALID_VALUE, "name is null!");
CHECK_AND_RETURN_RET_LOG(param != nullptr, VIDEO_PROCESSING_ERROR_INVALID_VALUE, "param is null!");
auto* mutableParam = const_cast<OH_AVFormat*>(param);
int32_t enable = 0;
bool hasEnable = OH_AVFormat_GetIntValue(mutableParam, VIDEO_AUTOEFFECT_ENABLE, &enable);
if (!hasEnable) {
enable = 0;
}
float strength = -1.0f;
bool hasStrength = OH_AVFormat_GetFloatValue(mutableParam, VIDEO_AUTOEFFECT_AISR_STRENGTH, &strength);
if (strength > 1.0f || strength < 0.0f) {
VPE_LOGE("SetAutoEffectParam: invalid strength %{public}f, must be in [0.0, 1.0]", strength);
return VIDEO_PROCESSING_ERROR_INVALID_VALUE;
}
return VideoProcessingUtils::InnerErrorToCAPI(
AutoEffectAisrVideo::SetAutoEffectEnabled(static_cast<bool>(enable), hasEnable, name, strength, hasStrength));
}