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 "video_processing.h"
17 
18 #include <atomic>
19 #include <functional>
20 
21 #include "vpe_log.h"
22 
23 #include "video_processing_callback_impl.h"
24 #include "video_processing_capability.h"
25 #include "video_processing_impl.h"
26 #include "video_processing_loader.h"
27 
28 using namespace OHOS::Media::VideoProcessingEngine;
29 
30 const int32_t VIDEO_PROCESSING_TYPE_COLOR_SPACE_CONVERSION = 0x1;
31 const int32_t VIDEO_PROCESSING_TYPE_METADATA_GENERATION = 0x2;
32 const int32_t VIDEO_PROCESSING_TYPE_DETAIL_ENHANCER = 0x4;
33 const char* VIDEO_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL = "QualityLevel";
34 
35 namespace {
36 std::atomic<bool> g_isInit = false;
37 
CallVideoProcessingSupport(std::function<bool (void)> && operation,std::function<bool (VideoProcessingNdkLoader &)> && operationLoader)38 bool CallVideoProcessingSupport(std::function<bool(void)>&& operation,
39     std::function<bool(VideoProcessingNdkLoader&)>&& operationLoader)
40 {
41     if (VideoProcessingNdkLoader::Get().LoadLibrary()) {
42         auto support = operationLoader(VideoProcessingNdkLoader::Get());
43         VideoProcessingNdkLoader::Get().UnloadLibrary();
44         return support;
45     }
46     return operation();
47 }
48 
CallVideoProcessing(OH_VideoProcessing * instance,std::function<VideoProcessing_ErrorCode (std::shared_ptr<VideoProcessingNative> &)> && operation,std::function<VideoProcessing_ErrorCode (VideoProcessingNdkLoader &)> && operationLoader)49 VideoProcessing_ErrorCode CallVideoProcessing(OH_VideoProcessing* instance,
50     std::function<VideoProcessing_ErrorCode(std::shared_ptr<VideoProcessingNative>&)>&& operation,
51     std::function<VideoProcessing_ErrorCode(VideoProcessingNdkLoader&)>&& operationLoader)
52 {
53     if (VideoProcessingNdkLoader::Get().IsValid()) {
54         return operationLoader(VideoProcessingNdkLoader::Get());
55     }
56     if (instance == nullptr) {
57         VPE_LOGE("instance is null!");
58         return VIDEO_PROCESSING_ERROR_INVALID_INSTANCE;
59     }
60     auto obj = instance->GetObj();
61     if (obj == nullptr) {
62         VPE_LOGE("instance is invalid!");
63         return VIDEO_PROCESSING_ERROR_INVALID_INSTANCE;
64     }
65     return operation(obj);
66 }
67 
CallVideoProcessingCallback(VideoProcessing_Callback * callback,std::function<VideoProcessing_ErrorCode (std::shared_ptr<VideoProcessingCallbackNative> &)> && operation,std::function<VideoProcessing_ErrorCode (VideoProcessingNdkLoader &)> && operationLoader)68 VideoProcessing_ErrorCode CallVideoProcessingCallback(VideoProcessing_Callback* callback,
69     std::function<VideoProcessing_ErrorCode(std::shared_ptr<VideoProcessingCallbackNative>&)>&& operation,
70     std::function<VideoProcessing_ErrorCode(VideoProcessingNdkLoader&)>&& operationLoader)
71 {
72     if (VideoProcessingNdkLoader::Get().IsValid()) {
73         return operationLoader(VideoProcessingNdkLoader::Get());
74     }
75     if (callback == nullptr) {
76         VPE_LOGE("callback is null!");
77         return VIDEO_PROCESSING_ERROR_INVALID_PARAMETER;
78     }
79     auto obj = callback->GetObj();
80     if (obj == nullptr) {
81         VPE_LOGE("callback is invalid!");
82         return VIDEO_PROCESSING_ERROR_INVALID_PARAMETER;
83     }
84     return operation(obj);
85 }
86 
CallVideoProcessingWithLoad(std::function<VideoProcessing_ErrorCode (void)> && operation,std::function<VideoProcessing_ErrorCode (VideoProcessingNdkLoader &)> && operationLoader)87 VideoProcessing_ErrorCode CallVideoProcessingWithLoad(
88     std::function<VideoProcessing_ErrorCode(void)>&& operation,
89     std::function<VideoProcessing_ErrorCode(VideoProcessingNdkLoader&)>&& operationLoader)
90 {
91     if (VideoProcessingNdkLoader::Get().LoadLibrary()) {
92         return operationLoader(VideoProcessingNdkLoader::Get());
93     }
94     return operation();
95 }
96 
CallVideoProcessingWithUnload(std::function<VideoProcessing_ErrorCode (void)> && operation,std::function<VideoProcessing_ErrorCode (VideoProcessingNdkLoader &)> && operationLoader)97 VideoProcessing_ErrorCode CallVideoProcessingWithUnload(
98     std::function<VideoProcessing_ErrorCode(void)>&& operation,
99     std::function<VideoProcessing_ErrorCode(VideoProcessingNdkLoader&)>&& operationLoader)
100 {
101     if (VideoProcessingNdkLoader::Get().IsValid()) {
102         auto ret = operationLoader(VideoProcessingNdkLoader::Get());
103         if (ret == VIDEO_PROCESSING_SUCCESS) {
104             VideoProcessingNdkLoader::Get().UnloadLibrary();
105         }
106         return ret;
107     }
108     return operation();
109 }
110 }
111 
OH_VideoProcessing_InitializeEnvironment(void)112 VideoProcessing_ErrorCode OH_VideoProcessing_InitializeEnvironment(void)
113 {
114     return CallVideoProcessingWithLoad(
115         []() {
116             g_isInit = true;
117             return VIDEO_PROCESSING_SUCCESS;
118         },
119         [](VideoProcessingNdkLoader& loader) { return loader.InitializeEnvironment(); });
120 }
121 
OH_VideoProcessing_DeinitializeEnvironment(void)122 VideoProcessing_ErrorCode OH_VideoProcessing_DeinitializeEnvironment(void)
123 {
124     return CallVideoProcessingWithUnload(
125         []() {
126             if (!g_isInit.load()) {
127                 return VIDEO_PROCESSING_ERROR_OPERATION_NOT_PERMITTED;
128             }
129             g_isInit = false;
130             return VIDEO_PROCESSING_SUCCESS;
131         },
132         [](VideoProcessingNdkLoader& loader) { return loader.DeinitializeEnvironment(); });
133 }
134 
OH_VideoProcessing_IsColorSpaceConversionSupported(const VideoProcessing_ColorSpaceInfo * sourceVideoInfo,const VideoProcessing_ColorSpaceInfo * destinationVideoInfo)135 bool OH_VideoProcessing_IsColorSpaceConversionSupported(const VideoProcessing_ColorSpaceInfo* sourceVideoInfo,
136     const VideoProcessing_ColorSpaceInfo* destinationVideoInfo)
137 {
138     return CallVideoProcessingSupport([sourceVideoInfo, destinationVideoInfo]() {
139         return VideoProcessingCapability::IsColorSpaceConversionSupported(sourceVideoInfo, destinationVideoInfo);
140         }, [sourceVideoInfo, destinationVideoInfo](VideoProcessingNdkLoader& loader) {
141         return loader.IsColorSpaceConversionSupported(sourceVideoInfo, destinationVideoInfo);
142     });
143 }
144 
OH_VideoProcessing_IsMetadataGenerationSupported(const VideoProcessing_ColorSpaceInfo * sourceVideoInfo)145 bool OH_VideoProcessing_IsMetadataGenerationSupported(const VideoProcessing_ColorSpaceInfo* sourceVideoInfo)
146 {
147     return CallVideoProcessingSupport([sourceVideoInfo]() {
148         return VideoProcessingCapability::IsMetadataGenerationSupported(sourceVideoInfo);
149         }, [sourceVideoInfo](VideoProcessingNdkLoader& loader) {
150         return loader.IsMetadataGenerationSupported(sourceVideoInfo);
151     });
152 }
153 
OH_VideoProcessing_Create(OH_VideoProcessing ** videoProcessor,int type)154 VideoProcessing_ErrorCode OH_VideoProcessing_Create(OH_VideoProcessing** videoProcessor, int type)
155 {
156     return CallVideoProcessingWithLoad(
157         [videoProcessor, type]() { return OH_VideoProcessing::Create(videoProcessor, type); },
158         [videoProcessor, type](VideoProcessingNdkLoader& loader) { return loader.Create(videoProcessor, type); }
159     );
160 }
161 
OH_VideoProcessing_Destroy(OH_VideoProcessing * videoProcessor)162 VideoProcessing_ErrorCode OH_VideoProcessing_Destroy(OH_VideoProcessing* videoProcessor)
163 {
164     return CallVideoProcessingWithUnload([videoProcessor]() { return OH_VideoProcessing::Destroy(videoProcessor); },
165         [videoProcessor](VideoProcessingNdkLoader& loader) { return loader.Destroy(videoProcessor); });
166 }
167 
OH_VideoProcessing_RegisterCallback(OH_VideoProcessing * videoProcessor,const VideoProcessing_Callback * callback,void * userData)168 VideoProcessing_ErrorCode OH_VideoProcessing_RegisterCallback(OH_VideoProcessing* videoProcessor,
169     const VideoProcessing_Callback* callback, void* userData)
170 {
171     return CallVideoProcessing(videoProcessor,
172         [callback, userData](std::shared_ptr<VideoProcessingNative>& obj) {
173         return obj->RegisterCallback(callback, userData);
174     }, [videoProcessor, callback, userData](VideoProcessingNdkLoader& loader) {
175         return loader.RegisterCallback(videoProcessor, callback, userData);
176     });
177 }
178 
OH_VideoProcessing_SetSurface(OH_VideoProcessing * videoProcessor,const OHNativeWindow * window)179 VideoProcessing_ErrorCode OH_VideoProcessing_SetSurface(OH_VideoProcessing* videoProcessor,
180     const OHNativeWindow* window)
181 {
182     return CallVideoProcessing(videoProcessor,
183         [window](std::shared_ptr<VideoProcessingNative>& obj) {
184         return obj->SetSurface(window);
185     }, [videoProcessor, window](VideoProcessingNdkLoader& loader) {
186         return loader.SetSurface(videoProcessor, window);
187     });
188 }
189 
OH_VideoProcessing_GetSurface(OH_VideoProcessing * videoProcessor,OHNativeWindow ** window)190 VideoProcessing_ErrorCode OH_VideoProcessing_GetSurface(OH_VideoProcessing* videoProcessor, OHNativeWindow** window)
191 {
192     return CallVideoProcessing(videoProcessor,
193         [window](std::shared_ptr<VideoProcessingNative>& obj) {
194         return obj->GetSurface(window);
195     }, [videoProcessor, window](VideoProcessingNdkLoader& loader) {
196         return loader.GetSurface(videoProcessor, window);
197     });
198 }
199 
OH_VideoProcessing_SetParameter(OH_VideoProcessing * videoProcessor,const OH_AVFormat * parameter)200 VideoProcessing_ErrorCode OH_VideoProcessing_SetParameter(OH_VideoProcessing* videoProcessor,
201     const OH_AVFormat* parameter)
202 {
203     return CallVideoProcessing(videoProcessor,
204         [parameter](std::shared_ptr<VideoProcessingNative>& obj) {
205         return obj->SetParameter(parameter);
206     }, [videoProcessor, parameter](VideoProcessingNdkLoader& loader) {
207         return loader.SetParameter(videoProcessor, parameter);
208     });
209 }
210 
OH_VideoProcessing_GetParameter(OH_VideoProcessing * videoProcessor,OH_AVFormat * parameter)211 VideoProcessing_ErrorCode OH_VideoProcessing_GetParameter(OH_VideoProcessing* videoProcessor, OH_AVFormat* parameter)
212 {
213     return CallVideoProcessing(videoProcessor,
214         [parameter](std::shared_ptr<VideoProcessingNative>& obj) {
215         return obj->GetParameter(parameter);
216     }, [videoProcessor, parameter](VideoProcessingNdkLoader& loader) {
217         return loader.GetParameter(videoProcessor, parameter);
218     });
219 }
220 
OH_VideoProcessing_Start(OH_VideoProcessing * videoProcessor)221 VideoProcessing_ErrorCode OH_VideoProcessing_Start(OH_VideoProcessing* videoProcessor)
222 {
223     return CallVideoProcessing(videoProcessor,
224         [](std::shared_ptr<VideoProcessingNative>& obj) {
225         return obj->Start();
226     }, [videoProcessor](VideoProcessingNdkLoader& loader) {
227         return loader.Start(videoProcessor);
228     });
229 }
230 
OH_VideoProcessing_Stop(OH_VideoProcessing * videoProcessor)231 VideoProcessing_ErrorCode OH_VideoProcessing_Stop(OH_VideoProcessing* videoProcessor)
232 {
233     return CallVideoProcessing(videoProcessor,
234         [](std::shared_ptr<VideoProcessingNative>& obj) {
235             return obj->Stop();
236         }, [videoProcessor](VideoProcessingNdkLoader& loader) {
237             return loader.Stop(videoProcessor);
238         });
239 }
240 
OH_VideoProcessing_RenderOutputBuffer(OH_VideoProcessing * videoProcessor,uint32_t index)241 VideoProcessing_ErrorCode OH_VideoProcessing_RenderOutputBuffer(OH_VideoProcessing* videoProcessor, uint32_t index)
242 {
243     return CallVideoProcessing(videoProcessor,
244         [index](std::shared_ptr<VideoProcessingNative>& obj) {
245             return obj->RenderOutputBuffer(index);
246         }, [videoProcessor, index](VideoProcessingNdkLoader& loader) {
247             return loader.RenderOutputBuffer(videoProcessor, index);
248         });
249 }
250 
OH_VideoProcessingCallback_Create(VideoProcessing_Callback ** callback)251 VideoProcessing_ErrorCode OH_VideoProcessingCallback_Create(VideoProcessing_Callback** callback)
252 {
253     return CallVideoProcessingWithLoad([callback]() { return VideoProcessing_Callback::Create(callback); },
254         [callback](VideoProcessingNdkLoader& loader) { return loader.Create(callback); });
255 }
256 
OH_VideoProcessingCallback_Destroy(VideoProcessing_Callback * callback)257 VideoProcessing_ErrorCode OH_VideoProcessingCallback_Destroy(VideoProcessing_Callback* callback)
258 {
259     return CallVideoProcessingWithUnload([callback]() { return VideoProcessing_Callback::Destroy(callback); },
260         [callback](VideoProcessingNdkLoader& loader) { return loader.Destroy(callback); });
261 }
262 
OH_VideoProcessingCallback_BindOnError(VideoProcessing_Callback * callback,OH_VideoProcessingCallback_OnError onError)263 VideoProcessing_ErrorCode OH_VideoProcessingCallback_BindOnError(VideoProcessing_Callback* callback,
264     OH_VideoProcessingCallback_OnError onError)
265 {
266     return CallVideoProcessingCallback(callback,
267         [onError](std::shared_ptr<VideoProcessingCallbackNative>& obj) {
268             return obj->BindOnError(onError);
269         }, [callback, onError](VideoProcessingNdkLoader& loader) {
270             return loader.BindOnError(callback, onError);
271         });
272 }
273 
OH_VideoProcessingCallback_BindOnState(VideoProcessing_Callback * callback,OH_VideoProcessingCallback_OnState onState)274 VideoProcessing_ErrorCode OH_VideoProcessingCallback_BindOnState(VideoProcessing_Callback* callback,
275     OH_VideoProcessingCallback_OnState onState)
276 {
277     return CallVideoProcessingCallback(callback,
278         [onState](std::shared_ptr<VideoProcessingCallbackNative>& obj) {
279             return obj->BindOnState(onState);
280         }, [callback, onState](VideoProcessingNdkLoader& loader) {
281             return loader.BindOnState(callback, onState);
282         });
283 }
284 
OH_VideoProcessingCallback_BindOnNewOutputBuffer(VideoProcessing_Callback * callback,OH_VideoProcessingCallback_OnNewOutputBuffer onNewOutputBuffer)285 VideoProcessing_ErrorCode OH_VideoProcessingCallback_BindOnNewOutputBuffer(VideoProcessing_Callback* callback,
286     OH_VideoProcessingCallback_OnNewOutputBuffer onNewOutputBuffer)
287 {
288     return CallVideoProcessingCallback(callback,
289         [onNewOutputBuffer](std::shared_ptr<VideoProcessingCallbackNative>& obj) {
290             return obj->BindOnNewOutputBuffer(onNewOutputBuffer);
291         }, [callback, onNewOutputBuffer](VideoProcessingNdkLoader& loader) {
292             return loader.BindOnNewOutputBuffer(callback, onNewOutputBuffer);
293         });
294 }
295