• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
17 #include <string>
18 #include <charconv>
19 
20 #include "common_utils.h"
21 #include "image_log.h"
22 #include "image_receiver_native.h"
23 #include "image_kits.h"
24 #include "image_receiver.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 struct OH_ImageReceiverNative {
31     std::shared_ptr<OHOS::Media::ImageReceiver> ptrImgRcv;
32 };
33 
34 struct OH_ImageReceiverOptions {
35     /* Default width of the image received by the consumer, in pixels. */
36     int32_t width = 0;
37     /* Default height of the image received by the consumer, in pixels. */
38     int32_t height = 0;
39     /* Image format {@link OHOS_IMAGE_FORMAT_JPEG} created by using the receiver. */
40     int32_t format = 0;
41     /* Maximum number of images that can be cached. */
42     int32_t capacity = 0;
43 };
44 
45 namespace OHOS {
46 namespace Media {
47     class ImageReceiverListener : public SurfaceBufferAvaliableListener {
48     public:
ImageReceiverListener(OH_ImageReceiverNative * receiver)49         explicit ImageReceiverListener(OH_ImageReceiverNative* receiver) : receiver_(receiver), callback_(nullptr) {}
50 
~ImageReceiverListener()51         ~ImageReceiverListener() override
52         {
53             callback_ = nullptr;
54         }
55 
OnSurfaceBufferAvaliable()56         void OnSurfaceBufferAvaliable() __attribute__((no_sanitize("cfi"))) override
57         {
58             if (nullptr != callback_) {
59                 callback_(receiver_);
60             }
61         }
62 
63         OH_ImageReceiverNative* receiver_;
64         OH_ImageReceiver_OnCallback callback_;
65     };
66 } // namespace Media
67 } // namespace OHOS
68 
69 MIDK_EXPORT
OH_ImageReceiverOptions_Create(OH_ImageReceiverOptions ** options)70 Image_ErrorCode OH_ImageReceiverOptions_Create(OH_ImageReceiverOptions** options)
71 {
72     if (nullptr == options) {
73         IMAGE_LOGE("Invalid parameter: options=null.");
74         return IMAGE_BAD_PARAMETER;
75     }
76     auto rst = new OH_ImageReceiverOptions;
77     if (nullptr == rst) {
78         IMAGE_LOGE("OH_ImageReceiverOptions create failed.");
79         return IMAGE_ALLOC_FAILED;
80     }
81     *options = rst;
82     IMAGE_LOGI("OH_ImageReceiverOptions Create.");
83     return IMAGE_SUCCESS;
84 }
85 
86 MIDK_EXPORT
OH_ImageReceiverOptions_GetSize(OH_ImageReceiverOptions * options,Image_Size * size)87 Image_ErrorCode OH_ImageReceiverOptions_GetSize(OH_ImageReceiverOptions* options, Image_Size* size)
88 {
89     if (nullptr == size) {
90         IMAGE_LOGE("Invalid parameter: size=null.");
91         return IMAGE_BAD_PARAMETER;
92     }
93     if (nullptr == options) {
94         IMAGE_LOGE("Invalid parameter: options=null.");
95         return IMAGE_BAD_PARAMETER;
96     }
97     size->width = static_cast<uint32_t>(options->width);
98     size->height = static_cast<uint32_t>(options->height);
99     return IMAGE_SUCCESS;
100 }
101 
102 MIDK_EXPORT
OH_ImageReceiverOptions_SetSize(OH_ImageReceiverOptions * options,Image_Size size)103 Image_ErrorCode OH_ImageReceiverOptions_SetSize(OH_ImageReceiverOptions* options, Image_Size size)
104 {
105     if (nullptr == options) {
106         IMAGE_LOGE("Invalid parameter: options=null.");
107         return IMAGE_BAD_PARAMETER;
108     }
109     options->width = static_cast<int32_t>(size.width);
110     options->height = static_cast<int32_t>(size.height);
111     return IMAGE_SUCCESS;
112 }
113 
114 MIDK_EXPORT
OH_ImageReceiverOptions_GetCapacity(OH_ImageReceiverOptions * options,int32_t * capacity)115 Image_ErrorCode OH_ImageReceiverOptions_GetCapacity(OH_ImageReceiverOptions* options, int32_t* capacity)
116 {
117     if (nullptr == capacity) {
118         IMAGE_LOGE("Invalid parameter: capacity=null.");
119         return IMAGE_BAD_PARAMETER;
120     }
121     if (nullptr == options) {
122         IMAGE_LOGE("Invalid parameter: options=null.");
123         return IMAGE_BAD_PARAMETER;
124     }
125     *capacity = options->capacity;
126     return IMAGE_SUCCESS;
127 }
128 
129 MIDK_EXPORT
OH_ImageReceiverOptions_SetCapacity(OH_ImageReceiverOptions * options,int32_t capacity)130 Image_ErrorCode OH_ImageReceiverOptions_SetCapacity(OH_ImageReceiverOptions* options, int32_t capacity)
131 {
132     if (nullptr == options) {
133         IMAGE_LOGE("Invalid parameter: options=null.");
134         return IMAGE_BAD_PARAMETER;
135     }
136     options->capacity = capacity;
137     return IMAGE_SUCCESS;
138 }
139 
140 MIDK_EXPORT
OH_ImageReceiverOptions_Release(OH_ImageReceiverOptions * options)141 Image_ErrorCode OH_ImageReceiverOptions_Release(OH_ImageReceiverOptions* options)
142 {
143     if (nullptr != options) {
144         IMAGE_LOGI("OH_ImageReceiverOptions Release.");
145         delete options;
146     }
147     return IMAGE_SUCCESS;
148 }
149 
150 MIDK_EXPORT
OH_ImageReceiverNative_Create(OH_ImageReceiverOptions * options,OH_ImageReceiverNative ** receiver)151 Image_ErrorCode OH_ImageReceiverNative_Create(OH_ImageReceiverOptions* options, OH_ImageReceiverNative** receiver)
152 {
153     if (nullptr == options || nullptr == receiver) {
154         IMAGE_LOGE("OH_ImageReceiverNative_Create: Invalid parameter");
155         return IMAGE_BAD_PARAMETER;
156     }
157 
158     auto rst = new OH_ImageReceiverNative;
159     if (nullptr == rst) {
160         IMAGE_LOGE("OH_ImageReceiverNative create failed.");
161         return IMAGE_ALLOC_FAILED;
162     }
163 
164     rst->ptrImgRcv = OHOS::Media::ImageReceiver::CreateImageReceiver(
165         options->width, options->height, options->format, options->capacity);
166     if (!(rst->ptrImgRcv)) {
167         delete rst;
168         IMAGE_LOGE("OH_ImageReceiverNative data create failed.");
169         return IMAGE_UNKNOWN_ERROR;
170     }
171 
172     *receiver = rst;
173     IMAGE_LOGI("OH_ImageReceiverNative Create.");
174     return IMAGE_SUCCESS;
175 }
176 
ConvertToUint64(const std::string & str,uint64_t & value)177 static bool ConvertToUint64(const std::string& str, uint64_t& value)
178 {
179     auto [ptr, errCode] = std::from_chars(str.data(), str.data() + str.size(), value);
180     bool ret = errCode == std::errc{} && (ptr == str.data() + str.size());
181     return ret;
182 }
183 
184 MIDK_EXPORT
OH_ImageReceiverNative_GetReceivingSurfaceId(OH_ImageReceiverNative * receiver,uint64_t * surfaceId)185 Image_ErrorCode OH_ImageReceiverNative_GetReceivingSurfaceId(OH_ImageReceiverNative* receiver, uint64_t* surfaceId)
186 {
187     if (nullptr == surfaceId) {
188         IMAGE_LOGE("Invalid parameter: surfaceId=null.");
189         return IMAGE_BAD_PARAMETER;
190     }
191     if (nullptr == receiver) {
192         IMAGE_LOGE("Invalid parameter: receiver=null.");
193         return IMAGE_BAD_PARAMETER;
194     }
195     if (nullptr == receiver->ptrImgRcv || nullptr == receiver->ptrImgRcv->iraContext_) {
196         IMAGE_LOGE("Bad parameter: receiver data empty.");
197         return IMAGE_BAD_PARAMETER;
198     }
199 
200     std::string strKey = receiver->ptrImgRcv->iraContext_->GetReceiverKey();
201     if (strKey.empty()) {
202         IMAGE_LOGE("Bad data: key string empty.");
203         return IMAGE_UNKNOWN_ERROR;
204     }
205     IMAGE_LOGD("OH_ImageReceiverNative_GetReceivingSurfaceId Receiver key = %{public}s", strKey.c_str());
206 
207     if (!ConvertToUint64(strKey, *surfaceId)) {
208         IMAGE_LOGI("strKey = %{public}s convert string to uint64_t failed", strKey.c_str());
209         return IMAGE_UNKNOWN_ERROR;
210     }
211     return IMAGE_SUCCESS;
212 }
213 
214 MIDK_EXPORT
OH_ImageReceiverNative_ReadLatestImage(OH_ImageReceiverNative * receiver,OH_ImageNative ** image)215 Image_ErrorCode OH_ImageReceiverNative_ReadLatestImage(OH_ImageReceiverNative* receiver, OH_ImageNative** image)
216 {
217     if (nullptr == image) {
218         IMAGE_LOGE("Invalid parameter: image=null.");
219         return IMAGE_BAD_PARAMETER;
220     }
221     if (nullptr == receiver) {
222         IMAGE_LOGE("Invalid parameter: receiver=null.");
223         return IMAGE_BAD_PARAMETER;
224     }
225     if (nullptr == receiver->ptrImgRcv) {
226         IMAGE_LOGE("Bad parameter: receiver data empty.");
227         return IMAGE_BAD_PARAMETER;
228     }
229 
230     auto bufferProcessor = receiver->ptrImgRcv->GetBufferProcessor();
231     if (nullptr == bufferProcessor) {
232         IMAGE_LOGE("Bad data: buffer processor empty.");
233         return IMAGE_UNKNOWN_ERROR;
234     }
235 
236     int64_t timestamp = 0;
237     auto surfaceBuffer = receiver->ptrImgRcv->ReadLastImage(timestamp);
238     if (nullptr == surfaceBuffer) {
239         IMAGE_LOGE("Bad data: surfacebuffer empty.");
240         return IMAGE_UNKNOWN_ERROR;
241     }
242 
243     auto rst = new OH_ImageNative;
244     if (nullptr == rst) {
245         IMAGE_LOGE("OH_ImageNative create failed.");
246         return IMAGE_ALLOC_FAILED;
247     }
248 
249     rst->imgNative = new OHOS::Media::NativeImage(surfaceBuffer, bufferProcessor, timestamp);
250     if (!(rst->imgNative)) {
251         delete rst;
252         IMAGE_LOGE("OH_ImageNative data create failed.");
253         return IMAGE_UNKNOWN_ERROR;
254     }
255 
256     *image = rst;
257     IMAGE_LOGD("OH_ImageNative ReadLatestImage.");
258     return IMAGE_SUCCESS;
259 }
260 
261 MIDK_EXPORT
OH_ImageReceiverNative_ReadNextImage(OH_ImageReceiverNative * receiver,OH_ImageNative ** image)262 Image_ErrorCode OH_ImageReceiverNative_ReadNextImage(OH_ImageReceiverNative* receiver, OH_ImageNative** image)
263 {
264     if (nullptr == image) {
265         IMAGE_LOGE("Invalid parameter: image=null.");
266         return IMAGE_BAD_PARAMETER;
267     }
268     if (nullptr == receiver) {
269         IMAGE_LOGE("Invalid parameter: receiver=null.");
270         return IMAGE_BAD_PARAMETER;
271     }
272     if (nullptr == receiver->ptrImgRcv) {
273         IMAGE_LOGE("Bad parameter: receiver data empty.");
274         return IMAGE_BAD_PARAMETER;
275     }
276 
277     auto bufferProcessor = receiver->ptrImgRcv->GetBufferProcessor();
278     if (nullptr == bufferProcessor) {
279         IMAGE_LOGE("Bad data: buffer processor empty.");
280         return IMAGE_UNKNOWN_ERROR;
281     }
282 
283     int64_t timestamp = 0;
284     auto surfaceBuffer = receiver->ptrImgRcv->ReadNextImage(timestamp);
285     if (nullptr == surfaceBuffer) {
286         IMAGE_LOGE("Bad data: surfacebuffer empty.");
287         return IMAGE_UNKNOWN_ERROR;
288     }
289 
290     auto rst = new OH_ImageNative;
291     if (nullptr == rst) {
292         IMAGE_LOGE("OH_ImageNative create failed.");
293         return IMAGE_ALLOC_FAILED;
294     }
295 
296     rst->imgNative = new OHOS::Media::NativeImage(surfaceBuffer, bufferProcessor, timestamp);
297     if (!(rst->imgNative)) {
298         delete rst;
299         IMAGE_LOGE("OH_ImageNative data create failed.");
300         return IMAGE_UNKNOWN_ERROR;
301     }
302 
303     *image = rst;
304     IMAGE_LOGI("OH_ImageNative ReadNextImage.");
305     return IMAGE_SUCCESS;
306 }
307 
308 MIDK_EXPORT
OH_ImageReceiverNative_On(OH_ImageReceiverNative * receiver,OH_ImageReceiver_OnCallback callback)309 Image_ErrorCode OH_ImageReceiverNative_On(OH_ImageReceiverNative* receiver, OH_ImageReceiver_OnCallback callback)
310 {
311     if (nullptr == receiver || nullptr == callback) {
312         IMAGE_LOGE("OH_ImageReceiverNative_On: Invalid parameter");
313         return IMAGE_BAD_PARAMETER;
314     }
315     if (nullptr == receiver->ptrImgRcv) {
316         IMAGE_LOGE("Bad parameter: receiver data empty.");
317         return IMAGE_BAD_PARAMETER;
318     }
319 
320     auto listener = std::make_shared<OHOS::Media::ImageReceiverListener>(receiver);
321     listener->callback_ = callback;
322     receiver->ptrImgRcv->RegisterBufferAvaliableListener(listener);
323     return IMAGE_SUCCESS;
324 }
325 
326 MIDK_EXPORT
OH_ImageReceiverNative_Off(OH_ImageReceiverNative * receiver)327 Image_ErrorCode OH_ImageReceiverNative_Off(OH_ImageReceiverNative* receiver)
328 {
329     if (nullptr == receiver) {
330         IMAGE_LOGE("Invalid parameter: receiver=null.");
331         return IMAGE_BAD_PARAMETER;
332     }
333     if (nullptr == receiver->ptrImgRcv) {
334         IMAGE_LOGE("Bad parameter: receiver data empty.");
335         return IMAGE_BAD_PARAMETER;
336     }
337 
338     receiver->ptrImgRcv->UnRegisterBufferAvaliableListener();
339     return IMAGE_SUCCESS;
340 }
341 
342 MIDK_EXPORT
OH_ImageReceiverNative_GetSize(OH_ImageReceiverNative * receiver,Image_Size * size)343 Image_ErrorCode OH_ImageReceiverNative_GetSize(OH_ImageReceiverNative* receiver, Image_Size* size)
344 {
345     if (nullptr == receiver || nullptr == size) {
346         IMAGE_LOGE("OH_ImageReceiverNative_GetSize: Invalid parameter");
347         return IMAGE_BAD_PARAMETER;
348     }
349     if (nullptr == receiver->ptrImgRcv || nullptr == receiver->ptrImgRcv->iraContext_) {
350         IMAGE_LOGE("Bad parameter: receiver data empty.");
351         return IMAGE_BAD_PARAMETER;
352     }
353 
354     size->width = static_cast<uint32_t>(receiver->ptrImgRcv->iraContext_->GetWidth());
355     size->height = static_cast<uint32_t>(receiver->ptrImgRcv->iraContext_->GetHeight());
356     return IMAGE_SUCCESS;
357 }
358 
359 MIDK_EXPORT
OH_ImageReceiverNative_GetCapacity(OH_ImageReceiverNative * receiver,int32_t * capacity)360 Image_ErrorCode OH_ImageReceiverNative_GetCapacity(OH_ImageReceiverNative* receiver, int32_t* capacity)
361 {
362     if (nullptr == receiver || nullptr == capacity) {
363         IMAGE_LOGE("OH_ImageReceiverNative_GetCapacity: Invalid parameter");
364         return IMAGE_BAD_PARAMETER;
365     }
366     if (nullptr == receiver->ptrImgRcv || nullptr == receiver->ptrImgRcv->iraContext_) {
367         IMAGE_LOGE("Bad parameter: receiver data empty.");
368         return IMAGE_BAD_PARAMETER;
369     }
370 
371     *capacity = receiver->ptrImgRcv->iraContext_->GetCapicity();
372     return IMAGE_SUCCESS;
373 }
374 
375 MIDK_EXPORT
OH_ImageReceiverNative_Release(OH_ImageReceiverNative * receiver)376 Image_ErrorCode OH_ImageReceiverNative_Release(OH_ImageReceiverNative* receiver)
377 {
378     if (nullptr == receiver) {
379         IMAGE_LOGE("Invalid parameter: receiver=null.");
380         return IMAGE_BAD_PARAMETER;
381     }
382     receiver->ptrImgRcv.reset();
383     IMAGE_LOGI("OH_ImageReceiverNative Release.");
384     delete receiver;
385     return IMAGE_SUCCESS;
386 }
387 
388 MIDK_EXPORT
OH_ImageReceiverNative_OnImageArrive(OH_ImageReceiverNative * receiver,OH_ImageReceiver_ImageArriveCallback callback,void * userdata)389 Image_ErrorCode OH_ImageReceiverNative_OnImageArrive(OH_ImageReceiverNative* receiver,
390     OH_ImageReceiver_ImageArriveCallback callback, void* userdata)
391 {
392     if (nullptr == receiver || nullptr == callback) {
393         IMAGE_LOGE("OH_ImageReceiverNative_OnImageArrive: Invalid parameter");
394         return IMAGE_RECEIVER_INVALID_PARAMETER;
395     }
396     if (nullptr == receiver->ptrImgRcv) {
397         IMAGE_LOGE("Bad parameter: receiver data empty.");
398         return IMAGE_RECEIVER_INVALID_PARAMETER;
399     }
400     if (receiver->ptrImgRcv->surfaceBufferAvaliableArriveListener_ == nullptr) {
401         receiver->ptrImgRcv->surfaceBufferAvaliableArriveListener_ =
402             std::make_shared<OHOS::Media::ImageReceiverArriveListener>(receiver);
403     }
404     bool ret = receiver->ptrImgRcv->surfaceBufferAvaliableArriveListener_->RegisterCallback(callback, userdata);
405     if (!ret) {
406         IMAGE_LOGD("callback has registered.");
407     }
408     return IMAGE_SUCCESS;
409 }
410 
OH_ImageReceiverNative_OffImageArrive(OH_ImageReceiverNative * receiver,OH_ImageReceiver_ImageArriveCallback callback)411 Image_ErrorCode OH_ImageReceiverNative_OffImageArrive(OH_ImageReceiverNative *receiver,
412     OH_ImageReceiver_ImageArriveCallback callback)
413 {
414     if (nullptr == receiver) {
415         IMAGE_LOGE("Invalid parameter: receiver=null.");
416         return IMAGE_RECEIVER_INVALID_PARAMETER;
417     }
418     if (nullptr == receiver->ptrImgRcv) {
419         IMAGE_LOGE("Bad parameter: receiver data empty.");
420         return IMAGE_RECEIVER_INVALID_PARAMETER;
421     }
422     if (nullptr == callback) {
423         receiver->ptrImgRcv->surfaceBufferAvaliableArriveListener_.reset();
424         return IMAGE_SUCCESS;
425     }
426     if (receiver->ptrImgRcv->surfaceBufferAvaliableArriveListener_ == nullptr) {
427         IMAGE_LOGE("listener is nullptr. not registered.");
428         return IMAGE_RECEIVER_INVALID_PARAMETER;
429     }
430     if (!receiver->ptrImgRcv->surfaceBufferAvaliableArriveListener_->UnregisterCallback(callback)) {
431         IMAGE_LOGE("callback is not registered.");
432         return IMAGE_RECEIVER_INVALID_PARAMETER;
433     }
434     return IMAGE_SUCCESS;
435 }
436 
437 #ifdef __cplusplus
438 };
439 #endif