1 /*
2 * Copyright (c) 2023 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 "metadata_generator_fwk.h"
17 #include "video_processing_client.h"
18 #include "extension_manager.h"
19 #include "native_buffer.h"
20 #include "surface_buffer.h"
21 #include "vpe_trace.h"
22 #include "vpe_log.h"
23 #include "EGL/egl.h"
24
25 namespace OHOS {
26 namespace Media {
27 namespace VideoProcessingEngine {
MetadataGeneratorFwk()28 MetadataGeneratorFwk::MetadataGeneratorFwk()
29 {
30 OpenGLInit();
31 OHOS::Media::VideoProcessingEngine::VideoProcessingManager::GetInstance().Connect();
32 VPE_LOGI("VPE Framework connect and load SA!");
33 OHOS::Media::VideoProcessingEngine::VideoProcessingManager::GetInstance().Disconnect();
34 Extension::ExtensionManager::GetInstance().IncreaseInstance();
35 }
36
OpenGLInit()37 void MetadataGeneratorFwk::OpenGLInit()
38 {
39 context.glDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
40 if (context.glDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS) {
41 VPE_LOGE("MetadataGeneratorFwk Get display failed!");
42 }
43 EGLint major;
44 EGLint minor;
45 if (eglInitialize(context.glDisplay, &major, &minor) == EGL_FALSE || eglGetError() != EGL_SUCCESS) {
46 VPE_LOGE("MetadataGeneratorFwk eglInitialize failed!");
47 }
48 }
49
MetadataGeneratorFwk(std::shared_ptr<OpenGLContext> openglContext)50 MetadataGeneratorFwk::MetadataGeneratorFwk(std::shared_ptr<OpenGLContext> openglContext)
51 {
52 if (openglContext != nullptr) {
53 context.glDisplay = openglContext->display;
54 }
55 OHOS::Media::VideoProcessingEngine::VideoProcessingManager::GetInstance().Connect();
56 VPE_LOGI("VPE Framework connect and load SA!");
57 OHOS::Media::VideoProcessingEngine::VideoProcessingManager::GetInstance().Disconnect();
58 Extension::ExtensionManager::GetInstance().IncreaseInstance();
59 }
60
~MetadataGeneratorFwk()61 MetadataGeneratorFwk::~MetadataGeneratorFwk()
62 {
63 if (impl_) {
64 impl_->Deinit();
65 impl_ = nullptr;
66 }
67 if (context.glDisplay != EGL_NO_DISPLAY) {
68 eglTerminate(context.glDisplay);
69 }
70 Extension::ExtensionManager::GetInstance().DecreaseInstance();
71 }
72
SetParameter(const MetadataGeneratorParameter & parameter)73 VPEAlgoErrCode MetadataGeneratorFwk::SetParameter(const MetadataGeneratorParameter ¶meter)
74 {
75 parameter_ = parameter;
76 VPE_LOGI("MetadataGeneratorFwk SetParameter Succeed");
77 return VPE_ALGO_ERR_OK;
78 }
79
GetParameter(MetadataGeneratorParameter & parameter) const80 VPEAlgoErrCode MetadataGeneratorFwk::GetParameter(MetadataGeneratorParameter ¶meter) const
81 {
82 parameter = parameter_;
83 VPE_LOGI("MetadataGeneratorFwk GetParameter Succeed");
84 return VPE_ALGO_ERR_OK;
85 }
86
Process(const sptr<SurfaceBuffer> & input)87 VPEAlgoErrCode MetadataGeneratorFwk::Process(const sptr<SurfaceBuffer> &input)
88 {
89 CHECK_AND_RETURN_RET_LOG(input != nullptr, VPE_ALGO_ERR_INVALID_VAL, "Input is nullptr");
90 CHECK_AND_RETURN_RET_LOG((input->GetUsage() & (BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_HW_RENDER)) != 0,
91 VPE_ALGO_ERR_INVALID_VAL, "Input surfacebuffer usage need NATIVEBUFFER_USAGE_HW_RENDER");
92 VPEAlgoErrCode ret = Init(input);
93 CHECK_AND_RETURN_RET_LOG(ret == VPE_ALGO_ERR_OK, ret, "Init failed");
94
95 VPE_SYNC_TRACE;
96 ret = impl_->Process(input);
97 CHECK_AND_RETURN_RET_LOG(ret == VPE_ALGO_ERR_OK, ret, "Process failed, ret: %{public}d", ret);
98
99 return VPE_ALGO_ERR_OK;
100 }
101
Init(const sptr<SurfaceBuffer> & input)102 VPEAlgoErrCode MetadataGeneratorFwk::Init(const sptr<SurfaceBuffer> &input)
103 {
104 if (initialized_) {
105 impl_->SetParameter(parameter_);
106 return VPE_ALGO_ERR_OK;
107 }
108 auto &manager = Extension::ExtensionManager::GetInstance();
109
110 VPE_SYNC_TRACE;
111
112 FrameInfo info(input);
113 impl_ = manager.CreateMetadataGenerator(info, extensionInfo_, parameter_.algoType);
114 CHECK_AND_RETURN_RET_LOG(impl_ != nullptr, VPE_ALGO_ERR_NOT_IMPLEMENTED, "Create failed");
115
116 int32_t ret = impl_->Init(context);
117 CHECK_AND_RETURN_RET_LOG(ret == VPE_ALGO_ERR_OK, VPE_ALGO_ERR_NOT_IMPLEMENTED, "Init failed");
118 impl_->SetParameter(parameter_);
119 initialized_ = true;
120 VPE_LOGI("MetadataGeneratorFwk Init Succeed");
121
122 return VPE_ALGO_ERR_OK;
123 }
124
Create()125 std::shared_ptr<MetadataGenerator> MetadataGenerator::Create()
126 {
127 auto p = std::make_shared<MetadataGeneratorFwk>();
128 CHECK_AND_RETURN_RET_LOG(p != nullptr, nullptr, "Create MetadataGenerator failed");
129 return std::static_pointer_cast<MetadataGenerator>(p);
130 }
131
Create(std::shared_ptr<OpenGLContext> openglContext)132 std::shared_ptr<MetadataGenerator> MetadataGenerator::Create(std::shared_ptr<OpenGLContext> openglContext)
133 {
134 auto p = std::make_shared<MetadataGeneratorFwk>(openglContext);
135 CHECK_AND_RETURN_RET_LOG(p != nullptr, nullptr, "Create MetadataGenerator failed");
136 return std::static_pointer_cast<MetadataGenerator>(p);
137 }
138
MetadataGeneratorCreate(int32_t * instance)139 int32_t MetadataGeneratorCreate(int32_t* instance)
140 {
141 CHECK_AND_RETURN_RET_LOG(instance != nullptr, VPE_ALGO_ERR_INVALID_VAL, "invalid instance");
142 auto p = MetadataGenerator::Create();
143 CHECK_AND_RETURN_RET_LOG(p != nullptr, VPE_ALGO_ERR_INVALID_VAL, "cannot create instance");
144 Extension::ExtensionManager::InstanceVariableType instanceVar { p };
145 int32_t newId = Extension::ExtensionManager::GetInstance().NewInstanceId(instanceVar);
146 CHECK_AND_RETURN_RET_LOG(newId != -1, VPE_ALGO_ERR_NO_MEMORY, "cannot create more instance");
147 *instance = newId;
148 return VPE_ALGO_ERR_OK;
149 }
MetadataGeneratorProcessImage(int32_t instance,OHNativeWindowBuffer * inputImage)150 int32_t MetadataGeneratorProcessImage(int32_t instance, OHNativeWindowBuffer* inputImage)
151 {
152 CHECK_AND_RETURN_RET_LOG((inputImage != nullptr), VPE_ALGO_ERR_INVALID_VAL,
153 "invalid parameters");
154 auto someInstance = Extension::ExtensionManager::GetInstance().GetInstance(instance);
155 CHECK_AND_RETURN_RET_LOG(someInstance != std::nullopt, VPE_ALGO_ERR_INVALID_VAL, "invalid instance");
156
157 VPEAlgoErrCode ret = VPE_ALGO_ERR_INVALID_VAL;
158 auto visitFunc = [inputImage, &ret](auto&& var) {
159 using VarType = std::decay_t<decltype(var)>;
160 if constexpr (std::is_same_v<VarType, std::shared_ptr<MetadataGenerator>>) {
161 OH_NativeBuffer* inputImageNativeBuffer = nullptr;
162 CHECK_AND_RETURN_LOG(
163 (OH_NativeBuffer_FromNativeWindowBuffer(inputImage, &inputImageNativeBuffer) == GSERROR_OK),
164 "invalid input image");
165 sptr<SurfaceBuffer> inputImageSurfaceBuffer(
166 SurfaceBuffer::NativeBufferToSurfaceBuffer(inputImageNativeBuffer));
167 (void)var->SetParameter({ MetadataGeneratorAlgoType::META_GEN_ALGO_TYPE_IMAGE});
168 ret = var->Process(inputImageSurfaceBuffer);
169 } else {
170 VPE_LOGE("instance may be miss used");
171 }
172 };
173 std::visit(visitFunc, *someInstance);
174
175 return ret;
176 }
177
MetadataGeneratorDestroy(int32_t * instance)178 int32_t MetadataGeneratorDestroy(int32_t* instance)
179 {
180 CHECK_AND_RETURN_RET_LOG(instance != nullptr, VPE_ALGO_ERR_INVALID_VAL, "instance is null");
181 return Extension::ExtensionManager::GetInstance().RemoveInstanceReference(*instance);
182 }
183 } // namespace VideoProcessingEngine
184 } // namespace Media
185 } // namespace OHOS
186