1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "detail_enhancer_video_native.h"
17
18 #include <unordered_map>
19
20 #include "vpe_log.h"
21 #include "video_processing_utils.h"
22
23 using namespace OHOS;
24 using namespace OHOS::Media::VideoProcessingEngine;
25
26 namespace {
27 const std::unordered_map<int, int> LEVEL_MAP = {
28 { VIDEO_DETAIL_ENHANCER_QUALITY_LEVEL_NONE, DETAIL_ENH_LEVEL_NONE },
29 { VIDEO_DETAIL_ENHANCER_QUALITY_LEVEL_LOW, DETAIL_ENH_LEVEL_LOW },
30 { VIDEO_DETAIL_ENHANCER_QUALITY_LEVEL_MEDIUM, DETAIL_ENH_LEVEL_MEDIUM },
31 { VIDEO_DETAIL_ENHANCER_QUALITY_LEVEL_HIGH, DETAIL_ENH_LEVEL_HIGH },
32 };
33 }
34
InitializeInner()35 VideoProcessing_ErrorCode DetailEnhancerVideoNative::InitializeInner()
36 {
37 CHECK_AND_RETURN_RET_LOG(!isInitialized_.load(), VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED,
38 "Already init!");
39
40 std::lock_guard<std::mutex> lock(lock_);
41 CHECK_AND_RETURN_RET_LOG(!isInitialized_.load(), VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED,
42 "Already init!");
43 detailEnhancer_ = DetailEnhancerVideo::Create();
44 CHECK_AND_RETURN_RET_LOG(detailEnhancer_ != nullptr, VIDEO_PROCESSING_ERROR_CREATE_FAILED,
45 "Create detail enhancement failed!");
46 isInitialized_ = true;
47 return VIDEO_PROCESSING_SUCCESS;
48 }
49
DeinitializeInner()50 VideoProcessing_ErrorCode DetailEnhancerVideoNative::DeinitializeInner()
51 {
52 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED,
53 "Already deinit!");
54
55 std::lock_guard<std::mutex> lock(lock_);
56 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED,
57 "Already deinit!");
58 detailEnhancer_ = nullptr;
59 isInitialized_ = false;
60 return VIDEO_PROCESSING_SUCCESS;
61 }
62
RegisterCallback()63 VideoProcessing_ErrorCode DetailEnhancerVideoNative::RegisterCallback()
64 {
65 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
66 "Initialization failed!");
67
68 auto callback = std::make_shared<NativeCallback>(shared_from_this());
69 CHECK_AND_RETURN_RET_LOG(callback != nullptr, VIDEO_PROCESSING_ERROR_CREATE_FAILED,
70 "Create callback failed!");
71 CHECK_AND_RETURN_RET_LOG(detailEnhancer_->RegisterCallback(callback) == VPE_ALGO_ERR_OK,
72 VIDEO_PROCESSING_ERROR_PROCESS_FAILED, "RegisterCallback failed!");
73 return VIDEO_PROCESSING_SUCCESS;
74 }
75
SetSurface(const sptr<Surface> & surface)76 VideoProcessing_ErrorCode DetailEnhancerVideoNative::SetSurface(const sptr<Surface>& surface)
77 {
78 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
79 "Initialization failed!");
80 CHECK_AND_RETURN_RET_LOG(surface != nullptr, VIDEO_PROCESSING_ERROR_INVALID_PARAMETER,
81 "surface is null!");
82 BufferRequestConfig bufferRequestConfig = surface->GetWindowConfig();
83 surface->SetRequestWidthAndHeight(bufferRequestConfig.width, bufferRequestConfig.height);
84 detailEnhancer_->SetOutputSurface(surface);
85 return VIDEO_PROCESSING_SUCCESS;
86 }
87
GetSurface()88 sptr<Surface> DetailEnhancerVideoNative::GetSurface()
89 {
90 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), nullptr, "Initialization failed!");
91 return detailEnhancer_->GetInputSurface();
92 }
93
SetParameter(const OHOS::Media::Format & parameter)94 VideoProcessing_ErrorCode DetailEnhancerVideoNative::SetParameter(const OHOS::Media::Format& parameter)
95 {
96 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
97 "Initialization failed!");
98
99 int level;
100 CHECK_AND_RETURN_RET_LOG(parameter.GetIntValue(VIDEO_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL, level),
101 VIDEO_PROCESSING_ERROR_INVALID_PARAMETER, "No quality level!");
102 int innerLevel = CAPILevelToInner(level);
103 CHECK_AND_RETURN_RET_LOG(innerLevel != -1, VIDEO_PROCESSING_ERROR_INVALID_PARAMETER, "Quality level is invalid!");
104 DetailEnhancerParameters param{};
105 param.level = static_cast<DetailEnhancerLevel>(innerLevel);
106 auto result = VideoProcessingUtils::InnerErrorToCAPI(detailEnhancer_->SetParameter(param, VIDEO));
107 if (result == VIDEO_PROCESSING_SUCCESS) {
108 level_ = level;
109 }
110 return result;
111 }
112
GetParameter(OHOS::Media::Format & parameter)113 VideoProcessing_ErrorCode DetailEnhancerVideoNative::GetParameter(OHOS::Media::Format& parameter)
114 {
115 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
116 "Initialization failed!");
117
118 int level = level_.load();
119 CHECK_AND_RETURN_RET_LOG(level != -1, VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED,
120 "No quality level set!");
121 CHECK_AND_RETURN_RET_LOG(parameter.PutIntValue(VIDEO_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL, level),
122 VIDEO_PROCESSING_ERROR_PROCESS_FAILED, "Get parameter failed!");
123 return VIDEO_PROCESSING_SUCCESS;
124 }
125
OnStart()126 VideoProcessing_ErrorCode DetailEnhancerVideoNative::OnStart()
127 {
128 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
129 "Initialization failed!");
130
131 return VideoProcessingUtils::InnerErrorToCAPI(detailEnhancer_->Start());
132 }
133
OnStop()134 VideoProcessing_ErrorCode DetailEnhancerVideoNative::OnStop()
135 {
136 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
137 "Initialization failed!");
138
139 return VideoProcessingUtils::InnerErrorToCAPI(detailEnhancer_->Stop());
140 }
141
OnRenderOutputBuffer(uint32_t index)142 VideoProcessing_ErrorCode DetailEnhancerVideoNative::OnRenderOutputBuffer(uint32_t index)
143 {
144 CHECK_AND_RETURN_RET_LOG(isInitialized_.load(), VIDEO_PROCESSING_ERROR_INITIALIZE_FAILED,
145 "Initialization failed!");
146
147 return VideoProcessingUtils::InnerErrorToCAPI(detailEnhancer_->ReleaseOutputBuffer(index, true));
148 }
149
CAPILevelToInner(int level) const150 int DetailEnhancerVideoNative::CAPILevelToInner(int level) const
151 {
152 auto it = LEVEL_MAP.find(level);
153 if (it == LEVEL_MAP.end()) [[unlikely]] {
154 VPE_LOGE("Invalid input level:%{public}d", level);
155 return -1;
156 }
157 return it->second;
158 }
159
NativeCallback(const std::shared_ptr<DetailEnhancerVideoNative> & owner)160 DetailEnhancerVideoNative::NativeCallback::NativeCallback(const std::shared_ptr<DetailEnhancerVideoNative>& owner)
161 : owner_(owner)
162 {
163 }
164
OnError(VPEAlgoErrCode errorCode)165 void DetailEnhancerVideoNative::NativeCallback::OnError(VPEAlgoErrCode errorCode)
166 {
167 SendCallback([this, &errorCode]() {
168 owner_->OnError(VideoProcessingUtils::InnerErrorToCAPI(errorCode));
169 });
170 }
171
OnState(VPEAlgoState state)172 void DetailEnhancerVideoNative::NativeCallback::OnState(VPEAlgoState state)
173 {
174 SendCallback([this, &state]() {
175 owner_->OnState(VideoProcessingUtils::InnerStateToCAPI(state));
176 });
177 }
178
OnOutputBufferAvailable(uint32_t index,DetailEnhBufferFlag flag)179 void DetailEnhancerVideoNative::NativeCallback::OnOutputBufferAvailable(uint32_t index,
180 [[maybe_unused]] DetailEnhBufferFlag flag)
181 {
182 SendCallback([this, &index]() {
183 owner_->OnNewOutputBuffer(index);
184 });
185 }
186
SendCallback(std::function<void (void)> && callback) const187 void DetailEnhancerVideoNative::NativeCallback::SendCallback(std::function<void(void)>&& callback) const
188 {
189 if (owner_ == nullptr) {
190 VPE_LOGE("owner is null!");
191 return;
192 }
193
194 callback();
195 }
196