• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 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 <map>
17 #include <iostream>
18 #include <sstream>
19 #include <iomanip>
20 #include <uv.h>
21 #include "avplayer_napi.h"
22 #include "media_errors.h"
23 #include "media_log.h"
24 #include "player.h"
25 #include "scope_guard.h"
26 #include "event_queue.h"
27 #include "avplayer_callback.h"
28 
29 
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "AVPlayerCallback" };
32 constexpr int32_t ARGS_TWO = 2;
33 }
34 
35 namespace OHOS {
36 namespace Media {
37 class NapiCallback {
38 public:
39     struct Base {
40         std::weak_ptr<AutoRef> callback;
41         std::string callbackName = "unknown";
42         Base() = default;
43         virtual ~Base() = default;
UvWorkOHOS::Media::NapiCallback::Base44         virtual void UvWork()
45         {
46             std::shared_ptr<AutoRef> ref = callback.lock();
47             CHECK_AND_RETURN_LOG(ref != nullptr,
48                 "%{public}s AutoRef is nullptr", callbackName.c_str());
49 
50             napi_handle_scope scope = nullptr;
51             napi_open_handle_scope(ref->env_, &scope);
52             CHECK_AND_RETURN_LOG(scope != nullptr,
53                 "%{public}s scope is nullptr", callbackName.c_str());
54             ON_SCOPE_EXIT(0) {
55                 napi_close_handle_scope(ref->env_, scope);
56             };
57 
58             napi_value jsCallback = nullptr;
59             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
60             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
61                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
62 
63             // Call back function
64             napi_value result = nullptr;
65             status = napi_call_function(ref->env_, nullptr, jsCallback, 0, nullptr, &result);
66             CHECK_AND_RETURN_LOG(status == napi_ok,
67                 "%{public}s failed to napi_call_function", callbackName.c_str());
68         }
JsCallbackOHOS::Media::NapiCallback::Base69         virtual void JsCallback()
70         {
71             UvWork();
72             delete this;
73         }
74     };
75 
76     struct Error : public Base {
77         std::string errorMsg = "unknown";
78         MediaServiceExtErrCodeAPI9 errorCode = MSERR_EXT_API9_UNSUPPORT_FORMAT;
UvWorkOHOS::Media::NapiCallback::Error79         void UvWork() override
80         {
81             std::shared_ptr<AutoRef> errorRef = callback.lock();
82             CHECK_AND_RETURN_LOG(errorRef != nullptr,
83                 "%{public}s AutoRef is nullptr", callbackName.c_str());
84 
85             napi_handle_scope scope = nullptr;
86             napi_open_handle_scope(errorRef->env_, &scope);
87             CHECK_AND_RETURN_LOG(scope != nullptr,
88                 "%{public}s scope is nullptr", callbackName.c_str());
89             ON_SCOPE_EXIT(0) {
90                 napi_close_handle_scope(errorRef->env_, scope);
91             };
92 
93             napi_value jsCallback = nullptr;
94             napi_status napiStatus = napi_get_reference_value(errorRef->env_, errorRef->cb_, &jsCallback);
95             CHECK_AND_RETURN_LOG(napiStatus == napi_ok && jsCallback != nullptr,
96                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
97 
98             napi_value args[1] = {nullptr};
99             (void)CommonNapi::CreateError(errorRef->env_, errorCode, errorMsg, args[0]);
100 
101             // Call back function
102             napi_value result = nullptr;
103             napiStatus = napi_call_function(errorRef->env_, nullptr, jsCallback, 1, args, &result);
104             CHECK_AND_RETURN_LOG(napiStatus == napi_ok,
105                 "%{public}s failed to napi_call_function", callbackName.c_str());
106         }
107     };
108 
109     struct Int : public Base {
110         int32_t value = 0;
UvWorkOHOS::Media::NapiCallback::Int111         void UvWork() override
112         {
113             std::shared_ptr<AutoRef> intRef = callback.lock();
114             CHECK_AND_RETURN_LOG(intRef != nullptr,
115                 "%{public}s AutoRef is nullptr", callbackName.c_str());
116 
117             napi_handle_scope scope = nullptr;
118             napi_open_handle_scope(intRef->env_, &scope);
119             CHECK_AND_RETURN_LOG(scope != nullptr,
120                 "%{public}s scope is nullptr", callbackName.c_str());
121             ON_SCOPE_EXIT(0) {
122                 napi_close_handle_scope(intRef->env_, scope);
123             };
124 
125             napi_value jsCallback = nullptr;
126             napi_status status = napi_get_reference_value(intRef->env_, intRef->cb_, &jsCallback);
127             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
128                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
129 
130             napi_value args[1] = {nullptr}; // callback: (int)
131             (void)napi_create_int32(intRef->env_, value, &args[0]);
132 
133             napi_value result = nullptr;
134             status = napi_call_function(intRef->env_, nullptr, jsCallback, 1, args, &result);
135             CHECK_AND_RETURN_LOG(status == napi_ok,
136                 "%{public}s failed to napi_call_function", callbackName.c_str());
137         }
138     };
139 
140     struct IntVec : public Base {
141         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntVec142         void UvWork() override
143         {
144             std::shared_ptr<AutoRef> intVecRef = callback.lock();
145             CHECK_AND_RETURN_LOG(intVecRef != nullptr,
146                 "%{public}s AutoRef is nullptr", callbackName.c_str());
147 
148             napi_handle_scope scope = nullptr;
149             napi_open_handle_scope(intVecRef->env_, &scope);
150             CHECK_AND_RETURN_LOG(scope != nullptr,
151                 "%{public}s scope is nullptr", callbackName.c_str());
152             ON_SCOPE_EXIT(0) {
153                 napi_close_handle_scope(intVecRef->env_, scope);
154             };
155 
156             napi_value jsCallback = nullptr;
157             napi_status status = napi_get_reference_value(intVecRef->env_, intVecRef->cb_, &jsCallback);
158             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
159                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
160 
161             napi_value args[2] = {nullptr}; // callback: (int, int)
162             (void)napi_create_int32(intVecRef->env_, valueVec[0], &args[0]);
163             (void)napi_create_int32(intVecRef->env_, valueVec[1], &args[1]);
164 
165             const int32_t argCount = static_cast<int32_t>(valueVec.size());
166             napi_value result = nullptr;
167             status = napi_call_function(intVecRef->env_, nullptr, jsCallback, argCount, args, &result);
168             CHECK_AND_RETURN_LOG(status == napi_ok,
169                 "%{public}s failed to napi_call_function", callbackName.c_str());
170         }
171     };
172 
173     struct IntArray : public Base {
174         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntArray175         void UvWork() override
176         {
177             std::shared_ptr<AutoRef> intArrayRef = callback.lock();
178             CHECK_AND_RETURN_LOG(intArrayRef != nullptr,
179                 "%{public}s AutoRef is nullptr", callbackName.c_str());
180 
181             napi_handle_scope scope = nullptr;
182             napi_open_handle_scope(intArrayRef->env_, &scope);
183             CHECK_AND_RETURN_LOG(scope != nullptr,
184                 "%{public}s scope is nullptr", callbackName.c_str());
185             ON_SCOPE_EXIT(0) {
186                 napi_close_handle_scope(intArrayRef->env_, scope);
187             };
188 
189             napi_value jsCallback = nullptr;
190             napi_status status = napi_get_reference_value(intArrayRef->env_, intArrayRef->cb_, &jsCallback);
191             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
192                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
193 
194             napi_value array = nullptr;
195             (void)napi_create_array_with_length(intArrayRef->env_, valueVec.size(), &array);
196 
197             for (uint32_t i = 0; i < valueVec.size(); i++) {
198                 napi_value number = nullptr;
199                 (void)napi_create_int32(intArrayRef->env_, valueVec.at(i), &number);
200                 (void)napi_set_element(intArrayRef->env_, array, i, number);
201             }
202 
203             napi_value result = nullptr;
204             napi_value args[1] = {array};
205             status = napi_call_function(intArrayRef->env_, nullptr, jsCallback, 1, args, &result);
206             CHECK_AND_RETURN_LOG(status == napi_ok,
207                 "%{public}s failed to napi_call_function", callbackName.c_str());
208         }
209     };
210 
211     struct Double : public Base {
212         double value = 0.0;
UvWorkOHOS::Media::NapiCallback::Double213         void UvWork() override
214         {
215             std::shared_ptr<AutoRef> doubleRef = callback.lock();
216             CHECK_AND_RETURN_LOG(doubleRef != nullptr,
217                 "%{public}s AutoRef is nullptr", callbackName.c_str());
218 
219             napi_handle_scope scope = nullptr;
220             napi_open_handle_scope(doubleRef->env_, &scope);
221             CHECK_AND_RETURN_LOG(scope != nullptr,
222                 "%{public}s scope is nullptr", callbackName.c_str());
223             ON_SCOPE_EXIT(0) {
224                 napi_close_handle_scope(doubleRef->env_, scope);
225             };
226 
227             napi_value jsCallback = nullptr;
228             napi_status status = napi_get_reference_value(doubleRef->env_, doubleRef->cb_, &jsCallback);
229             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
230                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
231 
232             napi_value args[1] = {nullptr};
233             (void)napi_create_double(doubleRef->env_, value, &args[0]);
234 
235             napi_value result = nullptr;
236             status = napi_call_function(doubleRef->env_, nullptr, jsCallback, 1, args, &result);
237             CHECK_AND_RETURN_LOG(status == napi_ok,
238                 "%{public}s failed to napi_call_function", callbackName.c_str());
239         }
240     };
241 
242     struct FloatArray : public Base {
243         std::vector<float>valueVec;
UvWorkOHOS::Media::NapiCallback::FloatArray244         void UvWork() override
245         {
246             std::shared_ptr<AutoRef> floatArrayRef = callback.lock();
247             CHECK_AND_RETURN_LOG(floatArrayRef != nullptr,
248                 "%{public}s AutoRef is nullptr", callbackName.c_str());
249 
250             napi_handle_scope scope = nullptr;
251             napi_open_handle_scope(floatArrayRef->env_, &scope);
252             CHECK_AND_RETURN_LOG(scope != nullptr,
253                 "%{public}s scope is nullptr", callbackName.c_str());
254             ON_SCOPE_EXIT(0) {
255                 napi_close_handle_scope(floatArrayRef->env_, scope);
256             };
257 
258             napi_value jsCallback = nullptr;
259             napi_status status = napi_get_reference_value(floatArrayRef->env_, floatArrayRef->cb_, &jsCallback);
260             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
261                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
262 
263             napi_value array = nullptr;
264             (void)napi_create_array_with_length(floatArrayRef->env_, valueVec.size(), &array);
265 
266             for (uint32_t i = 0; i < valueVec.size(); i++) {
267                 napi_value number = nullptr;
268                 (void)napi_create_double(floatArrayRef->env_, valueVec.at(i), &number);
269                 (void)napi_set_element(floatArrayRef->env_, array, i, number);
270             }
271 
272             napi_value result = nullptr;
273             napi_value args[1] = {array};
274             status = napi_call_function(floatArrayRef->env_, nullptr, jsCallback, 1, args, &result);
275             CHECK_AND_RETURN_LOG(status == napi_ok,
276                 "%{public}s failed to napi_call_function", callbackName.c_str());
277         }
278     };
279 
280     struct Bool : public Base {
281         bool value = false;
UvWorkOHOS::Media::NapiCallback::Bool282         void UvWork() override
283         {
284             std::shared_ptr<AutoRef> boolRef = callback.lock();
285             CHECK_AND_RETURN_LOG(boolRef != nullptr,
286                 "%{public}s AutoRef is nullptr", callbackName.c_str());
287 
288             napi_handle_scope scope = nullptr;
289             napi_open_handle_scope(boolRef->env_, &scope);
290             CHECK_AND_RETURN_LOG(scope != nullptr,
291                 "%{public}s scope is nullptr", callbackName.c_str());
292             ON_SCOPE_EXIT(0) {
293                 napi_close_handle_scope(boolRef->env_, scope);
294             };
295 
296             napi_value jsCallback = nullptr;
297             napi_status status = napi_get_reference_value(boolRef->env_, boolRef->cb_, &jsCallback);
298             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
299                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
300 
301             napi_value args[1] = {nullptr}; // callback: (boolean)
302             (void)napi_get_boolean(boolRef->env_, value, &args[0]);
303 
304             napi_value result = nullptr;
305             status = napi_call_function(boolRef->env_, nullptr, jsCallback, 1, args, &result);
306             CHECK_AND_RETURN_LOG(status == napi_ok,
307                 "%{public}s failed to napi_call_function", callbackName.c_str());
308         }
309     };
310 
311     struct SubtitleProperty : public Base {
312         std::string text;
UvWorkOHOS::Media::NapiCallback::SubtitleProperty313         void UvWork() override
314         {
315             std::shared_ptr<AutoRef> subtitleRef = callback.lock();
316             CHECK_AND_RETURN_LOG(subtitleRef != nullptr,
317                 "%{public}s AutoRef is nullptr", callbackName.c_str());
318 
319             napi_handle_scope scope = nullptr;
320             napi_open_handle_scope(subtitleRef->env_, &scope);
321             CHECK_AND_RETURN_LOG(scope != nullptr,
322                 "%{public}s scope is nullptr", callbackName.c_str());
323             ON_SCOPE_EXIT(0) {
324                 napi_close_handle_scope(subtitleRef->env_, scope);
325             };
326 
327             napi_value jsCallback = nullptr;
328             napi_status status = napi_get_reference_value(subtitleRef->env_, subtitleRef->cb_, &jsCallback);
329             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
330                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
331 
332             // callback: (textInfo: TextInfoDescriptor)
333             napi_value args[1] = {nullptr};
334             napi_create_object(subtitleRef->env_, &args[0]);
335             (void)CommonNapi::SetPropertyString(subtitleRef->env_, args[0], "text", text);
336             napi_value result = nullptr;
337             status = napi_call_function(subtitleRef->env_, nullptr, jsCallback, 1, args, &result);
338             CHECK_AND_RETURN_LOG(status == napi_ok,
339                 "%{public}s fail to napi_call_function", callbackName.c_str());
340         }
341     };
342 
343     struct ObjectArray : public Base {
344         std::multimap<std::string, std::vector<uint8_t>> infoMap;
UvWorkOHOS::Media::NapiCallback::ObjectArray345         void UvWork() override
346         {
347             std::shared_ptr<AutoRef> mapRef = callback.lock();
348             CHECK_AND_RETURN_LOG(mapRef != nullptr,
349                 "%{public}s AutoRef is nullptr", callbackName.c_str());
350 
351             napi_handle_scope scope = nullptr;
352             napi_open_handle_scope(mapRef->env_, &scope);
353             CHECK_AND_RETURN_LOG(scope != nullptr,
354                 "%{public}s scope is nullptr", callbackName.c_str());
355             ON_SCOPE_EXIT(0) {
356                 napi_close_handle_scope(mapRef->env_, scope);
357             };
358 
359             napi_value jsCallback = nullptr;
360             napi_status status = napi_get_reference_value(mapRef->env_, mapRef->cb_, &jsCallback);
361             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
362                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
363 
364             uint32_t index = 0;
365             napi_value napiMap;
366             napi_create_array_with_length(mapRef->env_, infoMap.size(), &napiMap);
367             for (auto item : infoMap) {
368                 napi_value jsObject;
369                 napi_value jsUuid;
370                 napi_value jsPssh;
371                 napi_create_object(mapRef->env_, &jsObject);
372                 napi_create_string_utf8(mapRef->env_, item.first.c_str(), NAPI_AUTO_LENGTH, &jsUuid);
373                 napi_set_named_property(mapRef->env_, jsObject, "uuid", jsUuid);
374 
375                 status = napi_create_array_with_length(mapRef->env_, item.second.size(), &jsPssh);
376                 for (uint32_t i = 0; i < item.second.size(); i++) {
377                     napi_value number = nullptr;
378                     (void)napi_create_uint32(mapRef->env_, item.second[i], &number);
379                     (void)napi_set_element(mapRef->env_, jsPssh, i, number);
380                 }
381                 napi_set_named_property(mapRef->env_, jsObject, "pssh", jsPssh);
382                 napi_set_element(mapRef->env_, napiMap, index, jsObject);
383                 index++;
384             }
385 
386             const int32_t argCount = 1;
387             napi_value args[argCount] = { napiMap };
388             napi_value result = nullptr;
389             status = napi_call_function(mapRef->env_, nullptr, jsCallback, argCount, args, &result);
390             CHECK_AND_RETURN_LOG(status == napi_ok,
391                 "%{public}s failed to napi_call_function", callbackName.c_str());
392         }
393     };
394 
395     struct PropertyInt : public Base {
396         std::map<std::string, int32_t> valueMap;
UvWorkOHOS::Media::NapiCallback::PropertyInt397         void UvWork() override
398         {
399             std::shared_ptr<AutoRef> propertyIntRef = callback.lock();
400             CHECK_AND_RETURN_LOG(propertyIntRef != nullptr,
401                 "%{public}s AutoRef is nullptr", callbackName.c_str());
402 
403             napi_handle_scope scope = nullptr;
404             napi_open_handle_scope(propertyIntRef->env_, &scope);
405             CHECK_AND_RETURN_LOG(scope != nullptr,
406                 "%{public}s scope is nullptr", callbackName.c_str());
407             ON_SCOPE_EXIT(0) {
408                 napi_close_handle_scope(propertyIntRef->env_, scope);
409             };
410 
411             napi_value jsCallback = nullptr;
412             napi_status status = napi_get_reference_value(propertyIntRef->env_, propertyIntRef->cb_, &jsCallback);
413             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
414                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
415 
416             napi_value args[1] = {nullptr};
417             napi_create_object(propertyIntRef->env_, &args[0]);
418             for (auto &it : valueMap) {
419                 CommonNapi::SetPropertyInt32(propertyIntRef->env_, args[0], it.first, it.second);
420             }
421 
422             napi_value result = nullptr;
423             status = napi_call_function(propertyIntRef->env_, nullptr, jsCallback, 1, args, &result);
424             CHECK_AND_RETURN_LOG(status == napi_ok,
425                 "%{public}s fail to napi_call_function", callbackName.c_str());
426         }
427     };
428 
429     struct StateChange : public Base {
430         std::string state = "";
431         int32_t reason = 0;
UvWorkOHOS::Media::NapiCallback::StateChange432         void UvWork() override
433         {
434             std::shared_ptr<AutoRef> stateChangeRef = callback.lock();
435             CHECK_AND_RETURN_LOG(stateChangeRef != nullptr,
436                 "%{public}s AutoRef is nullptr", callbackName.c_str());
437 
438             napi_handle_scope scope = nullptr;
439             napi_open_handle_scope(stateChangeRef->env_, &scope);
440             CHECK_AND_RETURN_LOG(scope != nullptr,
441                 "%{public}s scope is nullptr", callbackName.c_str());
442             ON_SCOPE_EXIT(0) {
443                 napi_close_handle_scope(stateChangeRef->env_, scope);
444             };
445 
446             napi_value jsCallback = nullptr;
447             napi_status status = napi_get_reference_value(stateChangeRef->env_, stateChangeRef->cb_, &jsCallback);
448             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
449                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
450 
451             const int32_t argCount = 2;
452             // callback: (state: AVPlayerState, reason: StateChangeReason)
453             napi_value args[argCount] = {nullptr};
454             (void)napi_create_string_utf8(stateChangeRef->env_, state.c_str(), NAPI_AUTO_LENGTH, &args[0]);
455             (void)napi_create_int32(stateChangeRef->env_, reason, &args[1]);
456 
457             napi_value result = nullptr;
458             status = napi_call_function(stateChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
459             CHECK_AND_RETURN_LOG(status == napi_ok,
460                 "%{public}s fail to napi_call_function", callbackName.c_str());
461         }
462     };
463 
CompleteCallback(napi_env env,NapiCallback::Base * jsCb)464     static void CompleteCallback(napi_env env, NapiCallback::Base *jsCb)
465     {
466         CHECK_AND_RETURN_LOG(jsCb != nullptr, "jsCb is nullptr");
467         napi_status ret = napi_send_event(env, [jsCb] () {
468             CHECK_AND_RETURN_LOG(jsCb != nullptr, "Work thread is nullptr");
469             MEDIA_LOGD("JsCallBack %{public}s start", jsCb->callbackName.c_str());
470             jsCb->UvWork();
471             delete jsCb;
472         }, napi_eprio_immediate);
473         if (ret != napi_ok) {
474             MEDIA_LOGE("Failed to execute libuv work queue, ret = %{public}d", ret);
475             delete jsCb;
476         }
477     }
478 
479     struct TrackChange : public Base {
480         int32_t number = 0;
481         bool isSelect = false;
UvWorkOHOS::Media::NapiCallback::TrackChange482         void UvWork() override
483         {
484             std::shared_ptr<AutoRef> trackChangeRef = callback.lock();
485             CHECK_AND_RETURN_LOG(trackChangeRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
486 
487             napi_handle_scope scope = nullptr;
488             napi_open_handle_scope(trackChangeRef->env_, &scope);
489             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
490             ON_SCOPE_EXIT(0) {
491                 napi_close_handle_scope(trackChangeRef->env_, scope);
492             };
493 
494             napi_value jsCallback = nullptr;
495             napi_status status = napi_get_reference_value(trackChangeRef->env_, trackChangeRef->cb_, &jsCallback);
496             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
497                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
498 
499             const int32_t argCount = 2; // 2 prapm, callback: (index: number, isSelect: boolean)
500             napi_value args[argCount] = {nullptr};
501             (void)napi_create_int32(trackChangeRef->env_, number, &args[0]);
502             (void)napi_get_boolean(trackChangeRef->env_, isSelect, &args[1]);
503 
504             napi_value result = nullptr;
505             status = napi_call_function(trackChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
506             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
507         }
508     };
509 
510     struct SubtitleInfo : public Base {
511         struct SubtitleParam {
512             std::string text;
513             int32_t pts;
514             int32_t duration;
515         } valueMap;
UvWorkOHOS::Media::NapiCallback::SubtitleInfo516         void UvWork() override
517         {
518             std::shared_ptr<AutoRef> subtitleRef = callback.lock();
519             CHECK_AND_RETURN_LOG(subtitleRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
520 
521             napi_handle_scope scope = nullptr;
522             napi_open_handle_scope(subtitleRef->env_, &scope);
523             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
524             ON_SCOPE_EXIT(0) {
525                 napi_close_handle_scope(subtitleRef->env_, scope);
526             };
527 
528             napi_value jsCallback = nullptr;
529             napi_status status = napi_get_reference_value(subtitleRef->env_, subtitleRef->cb_, &jsCallback);
530             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
531                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
532 
533             napi_value args[1] = {nullptr};
534             napi_create_object(subtitleRef->env_, &args[0]);
535             CommonNapi::SetPropertyString(subtitleRef->env_, args[0], "text", valueMap.text);
536             CommonNapi::SetPropertyInt32(subtitleRef->env_, args[0], "startTime", valueMap.pts);
537             CommonNapi::SetPropertyInt32(subtitleRef->env_, args[0], "duration", valueMap.duration);
538             napi_value result = nullptr;
539             status = napi_call_function(subtitleRef->env_, nullptr, jsCallback, 1, args, &result);
540             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
541         }
542     };
543 
544     struct DeviceChangeNapi : public Base {
545         AudioStandard::AudioDeviceDescriptor deviceInfo =
546             AudioStandard::AudioDeviceDescriptor(AudioStandard::AudioDeviceDescriptor::DEVICE_INFO);
547         int32_t reason;
UvWorkOHOS::Media::NapiCallback::DeviceChangeNapi548         void UvWork() override
549         {
550             std::shared_ptr<AutoRef> deviceChangeRef = callback.lock();
551             CHECK_AND_RETURN_LOG(deviceChangeRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
552 
553             napi_handle_scope scope = nullptr;
554             napi_open_handle_scope(deviceChangeRef->env_, &scope);
555             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
556             ON_SCOPE_EXIT(0) {
557                 napi_close_handle_scope(deviceChangeRef->env_, scope);
558             };
559 
560             napi_value jsCallback = nullptr;
561             napi_status status = napi_get_reference_value(deviceChangeRef->env_, deviceChangeRef->cb_, &jsCallback);
562             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
563                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
564 
565             constexpr size_t argCount = 1;
566             napi_value args[argCount] = {};
567             napi_create_object(deviceChangeRef->env_, &args[0]);
568             napi_value deviceObj = nullptr;
569             status = CommonNapi::SetValueDeviceInfo(deviceChangeRef->env_, deviceInfo, deviceObj);
570             CHECK_AND_RETURN_LOG(status == napi_ok && deviceObj != nullptr,
571                 " fail to convert to jsobj");
572             napi_set_named_property(deviceChangeRef->env_, args[0], "devices", deviceObj);
573 
574             bool res = CommonNapi::SetPropertyInt32(deviceChangeRef->env_, args[0], "changeReason",
575                 static_cast<const int32_t> (reason));
576             CHECK_AND_RETURN_LOG(res && deviceObj != nullptr,
577                 " fail to convert to jsobj");
578 
579             napi_value result = nullptr;
580             status = napi_call_function(deviceChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
581             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
582         }
583     };
584 
585     struct TrackInfoUpdate : public Base {
586         std::vector<Format> trackInfo;
UvWorkOHOS::Media::NapiCallback::TrackInfoUpdate587         void UvWork() override
588         {
589             std::shared_ptr<AutoRef> trackInfoRef = callback.lock();
590             CHECK_AND_RETURN_LOG(trackInfoRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
591 
592             napi_handle_scope scope = nullptr;
593             napi_open_handle_scope(trackInfoRef->env_, &scope);
594             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
595             ON_SCOPE_EXIT(0) {
596                 napi_close_handle_scope(trackInfoRef->env_, scope);
597             };
598 
599             napi_value jsCallback = nullptr;
600             napi_status status = napi_get_reference_value(trackInfoRef->env_, trackInfoRef->cb_, &jsCallback);
601             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
602                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
603 
604             napi_value array = nullptr;
605             (void)napi_create_array_with_length(trackInfoRef->env_, trackInfo.size(), &array);
606 
607             for (uint32_t i = 0; i < trackInfo.size(); i++) {
608                 napi_value trackDescription = nullptr;
609                 trackDescription = CommonNapi::CreateFormatBuffer(trackInfoRef->env_, trackInfo[i]);
610                 (void)napi_set_element(trackInfoRef->env_, array, i, trackDescription);
611             }
612 
613             napi_value result = nullptr;
614             napi_value args[1] = {array};
615             status = napi_call_function(trackInfoRef->env_, nullptr, jsCallback, 1, args, &result);
616             CHECK_AND_RETURN_LOG(status == napi_ok,
617                 "%{public}s failed to napi_call_function", callbackName.c_str());
618         }
619     };
620 
621     struct SeiInfoUpadte : public Base {
622         int32_t playbackPosition;
623         std::vector<Format> payloadGroup;
624 
UvWorkOHOS::Media::NapiCallback::SeiInfoUpadte625         void UvWork() override
626         {
627             std::shared_ptr<AutoRef> seiInfoRef = callback.lock();
628             CHECK_AND_RETURN_LOG(seiInfoRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
629 
630             napi_handle_scope scope = nullptr;
631             napi_open_handle_scope(seiInfoRef->env_, &scope);
632             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
633             ON_SCOPE_EXIT(0) {
634                 napi_close_handle_scope(seiInfoRef->env_, scope);
635             };
636 
637             napi_value jsCallback = nullptr;
638             napi_status status = napi_get_reference_value(seiInfoRef->env_, seiInfoRef->cb_, &jsCallback);
639             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
640                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
641 
642             napi_value position = nullptr;
643             status = napi_create_int32(seiInfoRef->env_, playbackPosition, &position);
644             CHECK_AND_RETURN_LOG(status == napi_ok, "failed to create js number %{public}d", playbackPosition);
645 
646             napi_value array = nullptr;
647             status = napi_create_array_with_length(seiInfoRef->env_, payloadGroup.size(), &array);
648             CHECK_AND_RETURN_LOG(status == napi_ok, "failed to create js array len %{public}zu", payloadGroup.size());
649             for (uint32_t i = 0; i < payloadGroup.size(); i++) {
650                 napi_value seiPayload = nullptr;
651                 seiPayload = CommonNapi::CreateFormatBuffer(seiInfoRef->env_, payloadGroup[i]);
652                 status = napi_set_element(seiInfoRef->env_, array, i, seiPayload);
653                 CHECK_AND_RETURN_LOG(status == napi_ok, "failed to set sei element %{public}d", i);
654             }
655 
656             napi_value args[ARGS_TWO] = { array, position };
657             napi_value result = nullptr;
658             status = napi_call_function(seiInfoRef->env_, nullptr, jsCallback, ARGS_TWO, args, &result);
659             CHECK_AND_RETURN_LOG(status == napi_ok,
660                 "%{public}s failed to napi_call_function", callbackName.c_str());
661         }
662     };
663 };
664 
AVPlayerCallback(napi_env env,AVPlayerNotify * listener)665 AVPlayerCallback::AVPlayerCallback(napi_env env, AVPlayerNotify *listener)
666     : env_(env), listener_(listener)
667 {
668     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
669     InitInfoFuncsPart1();
670     InitInfoFuncsPart2();
671 }
672 
InitInfoFuncsPart1()673 void AVPlayerCallback::InitInfoFuncsPart1()
674 {
675     onInfoFuncs_ = {
676         { INFO_TYPE_STATE_CHANGE,
677             [this](const int32_t extra, const Format &infoBody) { OnStateChangeCb(extra, infoBody); } },
678         { INFO_TYPE_VOLUME_CHANGE,
679             [this](const int32_t extra, const Format &infoBody) { OnVolumeChangeCb(extra, infoBody); } },
680         { INFO_TYPE_SEEKDONE,
681             [this](const int32_t extra, const Format &infoBody) { OnSeekDoneCb(extra, infoBody); } },
682         { INFO_TYPE_SPEEDDONE,
683             [this](const int32_t extra, const Format &infoBody) { OnSpeedDoneCb(extra, infoBody); } },
684         { INFO_TYPE_BITRATEDONE,
685             [this](const int32_t extra, const Format &infoBody) { OnBitRateDoneCb(extra, infoBody); } },
686         { INFO_TYPE_POSITION_UPDATE,
687             [this](const int32_t extra, const Format &infoBody) { OnPositionUpdateCb(extra, infoBody); } },
688         { INFO_TYPE_DURATION_UPDATE,
689             [this](const int32_t extra, const Format &infoBody) { OnDurationUpdateCb(extra, infoBody); } },
690         { INFO_TYPE_BUFFERING_UPDATE,
691             [this](const int32_t extra, const Format &infoBody) { OnBufferingUpdateCb(extra, infoBody); } },
692         { INFO_TYPE_MESSAGE,
693             [this](const int32_t extra, const Format &infoBody) { OnMessageCb(extra, infoBody);} },
694         { INFO_TYPE_RESOLUTION_CHANGE,
695             [this](const int32_t extra, const Format &infoBody) { OnVideoSizeChangedCb(extra, infoBody); } },
696         { INFO_TYPE_INTERRUPT_EVENT,
697             [this](const int32_t extra, const Format &infoBody) { OnAudioInterruptCb(extra, infoBody); } },
698         { INFO_TYPE_BITRATE_COLLECT,
699              [this](const int32_t extra, const Format &infoBody) { OnBitRateCollectedCb(extra, infoBody); } },
700         { INFO_TYPE_EOS,
701             [this](const int32_t extra, const Format &infoBody) { OnEosCb(extra, infoBody); } },
702         { INFO_TYPE_IS_LIVE_STREAM,
703             [this](const int32_t extra, const Format &infoBody) { NotifyIsLiveStream(extra, infoBody); } },
704         { INFO_TYPE_SUBTITLE_UPDATE,
705             [this](const int32_t extra, const Format &infoBody) { OnSubtitleUpdateCb(extra, infoBody); } },
706         { INFO_TYPE_TRACKCHANGE,
707             [this](const int32_t extra, const Format &infoBody) { OnTrackChangedCb(extra, infoBody); } },
708         { INFO_TYPE_TRACK_INFO_UPDATE,
709             [this](const int32_t extra, const Format &infoBody) { OnTrackInfoUpdate(extra, infoBody); } },
710         { INFO_TYPE_DRM_INFO_UPDATED,
711             [this](const int32_t extra, const Format &infoBody) { OnDrmInfoUpdatedCb(extra, infoBody); } },
712         { INFO_TYPE_SET_DECRYPT_CONFIG_DONE,
713             [this](const int32_t extra, const Format &infoBody) { OnSetDecryptConfigDoneCb(extra, infoBody); } },
714         { INFO_TYPE_SUBTITLE_UPDATE_INFO,
715             [this](const int32_t extra, const Format &infoBody) { OnSubtitleInfoCb(extra, infoBody); } },
716         { INFO_TYPE_AUDIO_DEVICE_CHANGE,
717             [this](const int32_t extra, const Format &infoBody) { OnAudioDeviceChangeCb(extra, infoBody); } },
718         { INFO_TYPE_MAX_AMPLITUDE_COLLECT,
719             [this](const int32_t extra, const Format &infoBody) { OnMaxAmplitudeCollectedCb(extra, infoBody); } },
720         { INFO_TYPE_SEI_UPDATE_INFO,
721             [this](const int32_t extra, const Format &infoBody) { OnSeiInfoCb(extra, infoBody); } },
722     };
723 }
724 
InitInfoFuncsPart2()725 void AVPlayerCallback::InitInfoFuncsPart2()
726 {
727     onInfoFuncs_[INFO_TYPE_SUPER_RESOLUTION_CHANGED] =
728         [this](const int32_t extra, const Format &infoBody) { OnSuperResolutionChangedCb(extra, infoBody); };
729 }
730 
OnAudioDeviceChangeCb(const int32_t extra,const Format & infoBody)731 void AVPlayerCallback::OnAudioDeviceChangeCb(const int32_t extra, const Format &infoBody)
732 {
733     (void)extra;
734     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
735     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE) == refMap_.end()) {
736         MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find audio AudioDeviceChange callback!", FAKE_POINTER(this));
737         return;
738     }
739 
740     NapiCallback::DeviceChangeNapi *cb = new(std::nothrow) NapiCallback::DeviceChangeNapi();
741     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new DeviceChangeNapi");
742 
743     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE);
744     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE;
745 
746     uint8_t *parcelBuffer = nullptr;
747     size_t parcelSize;
748     infoBody.GetBuffer(PlayerKeys::AUDIO_DEVICE_CHANGE, &parcelBuffer, parcelSize);
749     Parcel parcel;
750     parcel.WriteBuffer(parcelBuffer, parcelSize);
751     AudioStandard::AudioDeviceDescriptor deviceInfo(AudioStandard::AudioDeviceDescriptor::DEVICE_INFO);
752     deviceInfo.Unmarshalling(parcel);
753 
754     int32_t reason;
755     infoBody.GetIntValue(PlayerKeys::AUDIO_DEVICE_CHANGE_REASON, reason);
756 
757     cb->deviceInfo = deviceInfo;
758     cb->reason = reason;
759 
760     NapiCallback::CompleteCallback(env_, cb);
761 }
762 
~AVPlayerCallback()763 AVPlayerCallback::~AVPlayerCallback()
764 {
765     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
766 }
767 
OnError(int32_t errorCode,const std::string & errorMsg)768 void AVPlayerCallback::OnError(int32_t errorCode, const std::string &errorMsg)
769 {
770     MediaServiceExtErrCodeAPI9 errorCodeApi9 = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errorCode));
771     if (errorCodeApi9 == MSERR_EXT_API9_NO_PERMISSION ||
772         errorCodeApi9 == MSERR_EXT_API9_NO_MEMORY ||
773         errorCodeApi9 == MSERR_EXT_API9_TIMEOUT ||
774         errorCodeApi9 == MSERR_EXT_API9_SERVICE_DIED ||
775         errorCodeApi9 == MSERR_EXT_API9_UNSUPPORT_FORMAT) {
776         Format infoBody;
777         AVPlayerCallback::OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, infoBody);
778     }
779     AVPlayerCallback::OnErrorCb(errorCodeApi9, errorMsg);
780 }
781 
OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode,const std::string & errorMsg)782 void AVPlayerCallback::OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg)
783 {
784     std::string message = MSExtAVErrorToString(errorCode) + errorMsg;
785     MEDIA_LOGE("OnErrorCb:errorCode %{public}d, errorMsg %{public}s", errorCode, message.c_str());
786     std::lock_guard<std::mutex> lock(mutex_);
787     if (refMap_.find(AVPlayerEvent::EVENT_ERROR) == refMap_.end()) {
788         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find error callback!", FAKE_POINTER(this));
789         return;
790     }
791 
792     NapiCallback::Error *cb = new(std::nothrow) NapiCallback::Error();
793     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Error");
794 
795     cb->callback = refMap_.at(AVPlayerEvent::EVENT_ERROR);
796     cb->callbackName = AVPlayerEvent::EVENT_ERROR;
797     cb->errorCode = errorCode;
798     cb->errorMsg = message;
799     NapiCallback::CompleteCallback(env_, cb);
800 }
801 
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)802 void AVPlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
803 {
804     std::lock_guard<std::mutex> lock(mutex_);
805     MEDIA_LOGD("OnInfo is called, PlayerOnInfoType: %{public}d", type);
806     if (onInfoFuncs_.count(type) > 0) {
807         onInfoFuncs_[type](extra, infoBody);
808     } else {
809         MEDIA_LOGD("0x%{public}06" PRIXPTR " OnInfo: no member func supporting, %{public}d",
810             FAKE_POINTER(this), type);
811     }
812 }
813 
NotifyIsLiveStream(const int32_t extra,const Format & infoBody)814 void AVPlayerCallback::NotifyIsLiveStream(const int32_t extra, const Format &infoBody)
815 {
816     (void)extra;
817     (void)infoBody;
818     if (listener_ != nullptr) {
819         listener_->NotifyIsLiveStream();
820     }
821 }
822 
IsValidState(PlayerStates state,std::string & stateStr)823 bool AVPlayerCallback::IsValidState(PlayerStates state, std::string &stateStr)
824 {
825     switch (state) {
826         case PlayerStates::PLAYER_IDLE:
827             stateStr = AVPlayerState::STATE_IDLE;
828             break;
829         case PlayerStates::PLAYER_INITIALIZED:
830             stateStr = AVPlayerState::STATE_INITIALIZED;
831             break;
832         case PlayerStates::PLAYER_PREPARED:
833             stateStr = AVPlayerState::STATE_PREPARED;
834             break;
835         case PlayerStates::PLAYER_STARTED:
836             stateStr = AVPlayerState::STATE_PLAYING;
837             break;
838         case PlayerStates::PLAYER_PAUSED:
839             stateStr = AVPlayerState::STATE_PAUSED;
840             break;
841         case PlayerStates::PLAYER_STOPPED:
842             stateStr = AVPlayerState::STATE_STOPPED;
843             break;
844         case PlayerStates::PLAYER_PLAYBACK_COMPLETE:
845             stateStr = AVPlayerState::STATE_COMPLETED;
846             break;
847         case PlayerStates::PLAYER_RELEASED:
848             stateStr = AVPlayerState::STATE_RELEASED;
849             break;
850         case PlayerStates::PLAYER_STATE_ERROR:
851             stateStr = AVPlayerState::STATE_ERROR;
852             break;
853         default:
854             return false;
855     }
856     return true;
857 }
858 
OnStateChangeCb(const int32_t extra,const Format & infoBody)859 void AVPlayerCallback::OnStateChangeCb(const int32_t extra, const Format &infoBody)
860 {
861     PlayerStates state = static_cast<PlayerStates>(extra);
862     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instance OnStateChanged is called, current state: %{public}d",
863         FAKE_POINTER(this), state);
864 
865     if (listener_ != nullptr) {
866         listener_->NotifyState(state);
867     }
868 
869     if (state_ != state) {
870         state_ = state;
871         std::string stateStr;
872         if (IsValidState(state, stateStr)) {
873             if (refMap_.find(AVPlayerEvent::EVENT_STATE_CHANGE) == refMap_.end()) {
874                 MEDIA_LOGW("can not find state change callback!");
875                 return;
876             }
877             NapiCallback::StateChange *cb = new(std::nothrow) NapiCallback::StateChange();
878             CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new StateChange");
879 
880             int32_t reason = StateChangeReason::USER;
881             if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
882                 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
883             }
884             cb->callback = refMap_.at(AVPlayerEvent::EVENT_STATE_CHANGE);
885             cb->callbackName = AVPlayerEvent::EVENT_STATE_CHANGE;
886             cb->state = stateStr;
887             cb->reason = reason;
888             NapiCallback::CompleteCallback(env_, cb);
889         }
890     }
891 }
892 
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)893 void AVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
894 {
895     (void)extra;
896     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
897     float volumeLevel = 0.0;
898     (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
899 
900     isSetVolume_ = false;
901     MEDIA_LOGD("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
902     if (refMap_.find(AVPlayerEvent::EVENT_VOLUME_CHANGE) == refMap_.end()) {
903         MEDIA_LOGD("can not find vol change callback!");
904         return;
905     }
906 
907     NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double();
908     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Double");
909     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VOLUME_CHANGE);
910     cb->callbackName = AVPlayerEvent::EVENT_VOLUME_CHANGE;
911     cb->value = static_cast<double>(volumeLevel);
912     NapiCallback::CompleteCallback(env_, cb);
913 }
914 
OnSeekDoneCb(const int32_t extra,const Format & infoBody)915 void AVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
916 {
917     (void)infoBody;
918     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
919     int32_t currentPositon = extra;
920     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSeekDone is called, currentPositon: %{public}d",
921         FAKE_POINTER(this), currentPositon);
922     if (refMap_.find(AVPlayerEvent::EVENT_SEEK_DONE) == refMap_.end()) {
923         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find seekdone callback!", FAKE_POINTER(this));
924         return;
925     }
926     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
927     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
928 
929     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEEK_DONE);
930     cb->callbackName = AVPlayerEvent::EVENT_SEEK_DONE;
931     cb->value = currentPositon;
932     NapiCallback::CompleteCallback(env_, cb);
933 }
934 
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)935 void AVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
936 {
937     (void)infoBody;
938     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
939     int32_t speedMode = extra;
940     MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
941     if (refMap_.find(AVPlayerEvent::EVENT_SPEED_DONE) == refMap_.end()) {
942         MEDIA_LOGW("can not find speeddone callback!");
943         return;
944     }
945 
946     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
947     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
948 
949     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SPEED_DONE);
950     cb->callbackName = AVPlayerEvent::EVENT_SPEED_DONE;
951     cb->value = speedMode;
952     NapiCallback::CompleteCallback(env_, cb);
953 }
954 
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)955 void AVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
956 {
957     (void)infoBody;
958     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
959     int32_t bitRate = extra;
960     MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
961     if (refMap_.find(AVPlayerEvent::EVENT_BITRATE_DONE) == refMap_.end()) {
962         MEDIA_LOGW("can not find bitrate callback!");
963         return;
964     }
965 
966     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
967     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
968 
969     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BITRATE_DONE);
970     cb->callbackName = AVPlayerEvent::EVENT_BITRATE_DONE;
971     cb->value = bitRate;
972     NapiCallback::CompleteCallback(env_, cb);
973 }
974 
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)975 void AVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
976 {
977     (void)infoBody;
978     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
979     int32_t position = extra;
980     MEDIA_LOGD("OnPositionUpdateCb is called, position: %{public}d", position);
981 
982     if (listener_ != nullptr) {
983         listener_->NotifyPosition(position);
984     }
985 
986     if (refMap_.find(AVPlayerEvent::EVENT_TIME_UPDATE) == refMap_.end()) {
987         MEDIA_LOGD("can not find timeupdate callback!");
988         return;
989     }
990     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
991     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
992 
993     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TIME_UPDATE);
994     cb->callbackName = AVPlayerEvent::EVENT_TIME_UPDATE;
995     cb->value = position;
996     NapiCallback::CompleteCallback(env_, cb);
997 }
998 
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)999 void AVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
1000 {
1001     (void)infoBody;
1002     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1003     int32_t duration = extra;
1004     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnDurationUpdateCb is called, duration: %{public}d",
1005         FAKE_POINTER(this), duration);
1006 
1007     if (listener_ != nullptr) {
1008         listener_->NotifyDuration(duration);
1009     }
1010 
1011     if (refMap_.find(AVPlayerEvent::EVENT_DURATION_UPDATE) == refMap_.end()) {
1012         MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find duration update callback!", FAKE_POINTER(this));
1013         return;
1014     }
1015 
1016     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
1017     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
1018 
1019     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DURATION_UPDATE);
1020     cb->callbackName = AVPlayerEvent::EVENT_DURATION_UPDATE;
1021     cb->value = duration;
1022     NapiCallback::CompleteCallback(env_, cb);
1023 }
1024 
OnSubtitleUpdateCb(const int32_t extra,const Format & infoBody)1025 void AVPlayerCallback::OnSubtitleUpdateCb(const int32_t extra, const Format &infoBody)
1026 {
1027     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1028     if (refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE) == refMap_.end()) {
1029         MEDIA_LOGW("can not find subtitle update callback!");
1030         return;
1031     }
1032     NapiCallback::SubtitleProperty *cb = new(std::nothrow) NapiCallback::SubtitleProperty();
1033     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new SubtitleProperty");
1034     if (infoBody.ContainKey(PlayerKeys::SUBTITLE_TEXT)) {
1035         (void)infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, cb->text);
1036     }
1037     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE);
1038     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE;
1039     NapiCallback::CompleteCallback(env_, cb);
1040 }
1041 
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)1042 void AVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
1043 {
1044     (void)extra;
1045     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1046     if (refMap_.find(AVPlayerEvent::EVENT_BUFFERING_UPDATE) == refMap_.end()) {
1047         MEDIA_LOGD("can not find buffering update callback!");
1048         return;
1049     }
1050 
1051     int32_t val = 0;
1052     int32_t bufferingType = -1;
1053     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
1054         bufferingType = BUFFERING_START;
1055         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), val);
1056     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
1057         bufferingType = BUFFERING_END;
1058         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), val);
1059     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
1060         bufferingType = BUFFERING_PERCENT;
1061         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), val);
1062     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
1063         bufferingType = CACHED_DURATION;
1064         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), val);
1065     } else {
1066         return;
1067     }
1068 
1069     MEDIA_LOGD("OnBufferingUpdateCb is called, buffering type: %{public}d value: %{public}d", bufferingType, val);
1070     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1071     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1072 
1073     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BUFFERING_UPDATE);
1074     cb->callbackName = AVPlayerEvent::EVENT_BUFFERING_UPDATE;
1075     cb->valueVec.push_back(bufferingType);
1076     cb->valueVec.push_back(val);
1077     NapiCallback::CompleteCallback(env_, cb);
1078 }
1079 
OnMessageCb(const int32_t extra,const Format & infoBody)1080 void AVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
1081 {
1082     (void)infoBody;
1083     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1084     MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
1085     if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
1086         AVPlayerCallback::OnStartRenderFrameCb();
1087     }
1088 }
1089 
OnStartRenderFrameCb() const1090 void AVPlayerCallback::OnStartRenderFrameCb() const
1091 {
1092     MEDIA_LOGI("OnStartRenderFrameCb is called");
1093     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1094     if (refMap_.find(AVPlayerEvent::EVENT_START_RENDER_FRAME) == refMap_.end()) {
1095         MEDIA_LOGW("can not find start render callback!");
1096         return;
1097     }
1098 
1099     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1100     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1101 
1102     cb->callback = refMap_.at(AVPlayerEvent::EVENT_START_RENDER_FRAME);
1103     cb->callbackName = AVPlayerEvent::EVENT_START_RENDER_FRAME;
1104     NapiCallback::CompleteCallback(env_, cb);
1105 }
1106 
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)1107 void AVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
1108 {
1109     (void)extra;
1110     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1111     int32_t width = 0;
1112     int32_t height = 0;
1113     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
1114     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
1115     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d",
1116         FAKE_POINTER(this), width, height);
1117 
1118     if (listener_ != nullptr) {
1119         listener_->NotifyVideoSize(width, height);
1120     }
1121 
1122     if (refMap_.find(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE) == refMap_.end()) {
1123         MEDIA_LOGW("can not find video size changed callback!");
1124         return;
1125     }
1126     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1127     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1128 
1129     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE);
1130     cb->callbackName = AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE;
1131     cb->valueVec.push_back(width);
1132     cb->valueVec.push_back(height);
1133     NapiCallback::CompleteCallback(env_, cb);
1134 }
1135 
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)1136 void AVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
1137 {
1138     (void)extra;
1139     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1140     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_INTERRUPT) == refMap_.end()) {
1141         MEDIA_LOGW("can not find audio interrupt callback!");
1142         return;
1143     }
1144 
1145     NapiCallback::PropertyInt *cb = new(std::nothrow) NapiCallback::PropertyInt();
1146     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new PropertyInt");
1147 
1148     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_INTERRUPT);
1149     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_INTERRUPT;
1150     int32_t eventType = 0;
1151     int32_t forceType = 0;
1152     int32_t hintType = 0;
1153     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
1154     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
1155     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
1156     MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
1157         eventType, forceType, hintType);
1158     // ohos.multimedia.audio.d.ts interface InterruptEvent
1159     cb->valueMap["eventType"] = eventType;
1160     cb->valueMap["forceType"] = forceType;
1161     cb->valueMap["hintType"] = hintType;
1162     NapiCallback::CompleteCallback(env_, cb);
1163 }
1164 
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)1165 void AVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
1166 {
1167     (void)extra;
1168     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1169     if (refMap_.find(AVPlayerEvent::EVENT_AVAILABLE_BITRATES) == refMap_.end()) {
1170         MEDIA_LOGW("can not find bitrate collected callback!");
1171         return;
1172     }
1173 
1174     std::vector<int32_t> bitrateVec;
1175     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES))) {
1176         uint8_t *addr = nullptr;
1177         size_t size  = 0;
1178         infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES), &addr, size);
1179         CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
1180 
1181         MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
1182         while (size > 0) {
1183             if (size < sizeof(uint32_t)) {
1184                 break;
1185             }
1186 
1187             uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
1188             MEDIA_LOGI("bitrate = %{public}u", bitrate);
1189             addr += sizeof(uint32_t);
1190             size -= sizeof(uint32_t);
1191             bitrateVec.push_back(static_cast<int32_t>(bitrate));
1192         }
1193     }
1194 
1195     NapiCallback::IntArray *cb = new(std::nothrow) NapiCallback::IntArray();
1196     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1197 
1198     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AVAILABLE_BITRATES);
1199     cb->callbackName = AVPlayerEvent::EVENT_AVAILABLE_BITRATES;
1200     cb->valueVec = bitrateVec;
1201     NapiCallback::CompleteCallback(env_, cb);
1202 }
1203 
OnMaxAmplitudeCollectedCb(const int32_t extra,const Format & infoBody)1204 void AVPlayerCallback::OnMaxAmplitudeCollectedCb(const int32_t extra, const Format &infoBody)
1205 {
1206     (void)extra;
1207     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1208     if (refMap_.find(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE) == refMap_.end()) {
1209         MEDIA_LOGD("can not find max amplitude collected callback!");
1210         return;
1211     }
1212 
1213     std::vector<float> MaxAmplitudeVec;
1214     if (infoBody.ContainKey(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE))) {
1215         uint8_t *addr = nullptr;
1216         size_t size  = 0;
1217         infoBody.GetBuffer(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE), &addr, size);
1218         CHECK_AND_RETURN_LOG(addr != nullptr, "max amplitude addr is nullptr");
1219 
1220         MEDIA_LOGD("max amplitude size = %{public}zu", size / sizeof(float));
1221         while (size > 0) {
1222             if (size < sizeof(float)) {
1223                 break;
1224             }
1225 
1226             float maxAmplitude = *(static_cast<float *>(static_cast<void *>(addr)));
1227             MEDIA_LOGD("maxAmplitude = %{public}f", maxAmplitude);
1228             addr += sizeof(float);
1229             size -= sizeof(float);
1230             MaxAmplitudeVec.push_back(static_cast<float>(maxAmplitude));
1231         }
1232     }
1233 
1234     NapiCallback::FloatArray *cb = new(std::nothrow) NapiCallback::FloatArray();
1235     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1236 
1237     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE);
1238     cb->callbackName = AVPlayerEvent::EVENT_AMPLITUDE_UPDATE;
1239     cb->valueVec = MaxAmplitudeVec;
1240     NapiCallback::CompleteCallback(env_, cb);
1241 }
1242 
OnSeiInfoCb(const int32_t extra,const Format & infoBody)1243 void AVPlayerCallback::OnSeiInfoCb(const int32_t extra, const Format &infoBody)
1244 {
1245     CHECK_AND_RETURN_LOG(
1246         refMap_.find(AVPlayerEvent::EVENT_SEI_MESSAGE_INFO) != refMap_.end(), "can not find on sei message callback!");
1247 
1248     (void)extra;
1249     int32_t playbackPosition = 0;
1250     bool res = infoBody.GetIntValue(Tag::AV_PLAYER_SEI_PLAYBACK_POSITION, playbackPosition);
1251     CHECK_AND_RETURN_LOG(res, "get playback position failed");
1252 
1253     std::vector<Format> formatVec;
1254     res = infoBody.GetFormatVector(Tag::AV_PLAYER_SEI_PLAYBACK_GROUP, formatVec);
1255     CHECK_AND_RETURN_LOG(res, "get sei payload group failed");
1256 
1257     NapiCallback::SeiInfoUpadte *cb = new(std::nothrow) NapiCallback::SeiInfoUpadte();
1258     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1259 
1260     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEI_MESSAGE_INFO);
1261     cb->callbackName = AVPlayerEvent::EVENT_SEI_MESSAGE_INFO;
1262     cb->playbackPosition = playbackPosition;
1263     cb->payloadGroup = formatVec;
1264     NapiCallback::CompleteCallback(env_, cb);
1265 }
1266 
OnSuperResolutionChangedCb(const int32_t extra,const Format & infoBody)1267 void AVPlayerCallback::OnSuperResolutionChangedCb(const int32_t extra, const Format &infoBody)
1268 {
1269     (void)extra;
1270     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1271     int32_t enabled = 0;
1272     (void)infoBody.GetIntValue(PlayerKeys::SUPER_RESOLUTION_ENABLED, enabled);
1273     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSuperResolutionChangedCb is called, enabled = %{public}d",
1274         FAKE_POINTER(this), enabled);
1275 
1276     if (refMap_.find(AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED) == refMap_.end()) {
1277         MEDIA_LOGW("can not find super resolution changed callback!");
1278         return;
1279     }
1280     NapiCallback::Bool *cb = new(std::nothrow) NapiCallback::Bool();
1281     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Bool");
1282 
1283     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED);
1284     cb->callbackName = AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED;
1285     cb->value = enabled ? true : false;
1286     NapiCallback::CompleteCallback(env_, cb);
1287 }
1288 
SetDrmInfoData(const uint8_t * drmInfoAddr,int32_t infoCount,std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)1289 int32_t AVPlayerCallback::SetDrmInfoData(const uint8_t *drmInfoAddr, int32_t infoCount,
1290     std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
1291 {
1292     DrmInfoItem *drmInfos = reinterpret_cast<DrmInfoItem*>(const_cast<uint8_t *>(drmInfoAddr));
1293     CHECK_AND_RETURN_RET_LOG(drmInfos != nullptr, MSERR_INVALID_VAL, "cast drmInfos nullptr");
1294     for (int32_t i = 0; i < infoCount; i++) {
1295         DrmInfoItem temp = drmInfos[i];
1296         std::stringstream ssConverter;
1297         std::string uuid;
1298         for (uint32_t index = 0; index < DrmConstant::DRM_MAX_M3U8_DRM_UUID_LEN; index++) {
1299             int32_t singleUuid = static_cast<int32_t>(temp.uuid[index]);
1300             ssConverter << std::hex << std::setfill('0') << std::setw(2) << singleUuid; // 2:w
1301             uuid = ssConverter.str();
1302         }
1303         std::vector<uint8_t> pssh(temp.pssh, temp.pssh + temp.psshLen);
1304         drmInfoMap.insert({ uuid, pssh });
1305     }
1306 
1307     if (listener_ != nullptr) {
1308         listener_->NotifyDrmInfoUpdated(drmInfoMap);
1309     }
1310     return MSERR_OK;
1311 }
1312 
OnDrmInfoUpdatedCb(const int32_t extra,const Format & infoBody)1313 void AVPlayerCallback::OnDrmInfoUpdatedCb(const int32_t extra, const Format &infoBody)
1314 {
1315     (void)extra;
1316     MEDIA_LOGI("AVPlayerCallback OnDrmInfoUpdatedCb is called");
1317     if (refMap_.find(AVPlayerEvent::EVENT_DRM_INFO_UPDATE) == refMap_.end()) {
1318         MEDIA_LOGW("can not find drm info updated callback!");
1319         return;
1320     }
1321     if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR))) {
1322         MEDIA_LOGW("there's no drminfo-update drm_info_addr key");
1323         return;
1324     }
1325     if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT))) {
1326         MEDIA_LOGW("there's no drminfo-update drm_info_count key");
1327         return;
1328     }
1329 
1330     uint8_t *drmInfoAddr = nullptr;
1331     size_t size  = 0;
1332     int32_t infoCount = 0;
1333     infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR), &drmInfoAddr, size);
1334     CHECK_AND_RETURN_LOG(drmInfoAddr != nullptr && size > 0, "get drminfo buffer failed");
1335     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT), infoCount);
1336     CHECK_AND_RETURN_LOG(infoCount > 0, "get drminfo count is illegal");
1337 
1338     std::multimap<std::string, std::vector<uint8_t>> drmInfoMap;
1339     int32_t ret = SetDrmInfoData(drmInfoAddr, infoCount, drmInfoMap);
1340     CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetDrmInfoData err");
1341     NapiCallback::ObjectArray *cb = new(std::nothrow) NapiCallback::ObjectArray();
1342     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new ObjectArray");
1343     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DRM_INFO_UPDATE);
1344     cb->callbackName = AVPlayerEvent::EVENT_DRM_INFO_UPDATE;
1345     cb->infoMap = drmInfoMap;
1346     NapiCallback::CompleteCallback(env_, cb);
1347 }
1348 
OnSetDecryptConfigDoneCb(const int32_t extra,const Format & infoBody)1349 void AVPlayerCallback::OnSetDecryptConfigDoneCb(const int32_t extra, const Format &infoBody)
1350 {
1351     (void)extra;
1352     MEDIA_LOGI("AVPlayerCallback OnSetDecryptConfigDoneCb is called");
1353     if (refMap_.find(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE) == refMap_.end()) {
1354         MEDIA_LOGW("can not find SetDecryptConfig Done callback!");
1355         return;
1356     }
1357 
1358     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1359     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1360 
1361     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE);
1362     cb->callbackName = AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE;
1363     NapiCallback::CompleteCallback(env_, cb);
1364 }
1365 
OnSubtitleInfoCb(const int32_t extra,const Format & infoBody)1366 void AVPlayerCallback::OnSubtitleInfoCb(const int32_t extra, const Format &infoBody)
1367 {
1368     (void)infoBody;
1369     int32_t pts = -1;
1370     int32_t duration = -1;
1371     std::string text;
1372     infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, text);
1373     infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_PTS), pts);
1374     infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_DURATION), duration);
1375     MEDIA_LOGI("OnSubtitleInfoCb pts %{public}d, duration = %{public}d", pts, duration);
1376 
1377     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_UPDATE) != refMap_.end(),
1378         "can not find Subtitle callback!");
1379 
1380     NapiCallback::SubtitleInfo *cb = new(std::nothrow) NapiCallback::SubtitleInfo();
1381     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Subtitle");
1382 
1383     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_UPDATE);
1384     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_UPDATE;
1385     cb->valueMap.text = text;
1386     cb->valueMap.pts = pts;
1387     cb->valueMap.duration = duration;
1388 
1389     NapiCallback::CompleteCallback(env_, cb);
1390 }
1391 
OnEosCb(const int32_t extra,const Format & infoBody)1392 void AVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
1393 {
1394     (void)infoBody;
1395     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1396     int32_t isLooping = extra;
1397     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnEndOfStream is called, isloop: %{public}d", FAKE_POINTER(this), isLooping);
1398     if (refMap_.find(AVPlayerEvent::EVENT_END_OF_STREAM) == refMap_.end()) {
1399         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find EndOfStream callback!", FAKE_POINTER(this));
1400         return;
1401     }
1402 
1403     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1404     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1405 
1406     cb->callback = refMap_.at(AVPlayerEvent::EVENT_END_OF_STREAM);
1407     cb->callbackName = AVPlayerEvent::EVENT_END_OF_STREAM;
1408     NapiCallback::CompleteCallback(env_, cb);
1409 }
1410 
OnTrackChangedCb(const int32_t extra,const Format & infoBody)1411 void AVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
1412 {
1413     (void)extra;
1414     int32_t index = -1;
1415     int32_t isSelect = -1;
1416     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
1417     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
1418     MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
1419 
1420     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACKCHANGE) != refMap_.end(),
1421         "can not find trackChange callback!");
1422 
1423     NapiCallback::TrackChange *cb = new(std::nothrow) NapiCallback::TrackChange();
1424     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackChange");
1425 
1426     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACKCHANGE);
1427     cb->callbackName = AVPlayerEvent::EVENT_TRACKCHANGE;
1428     cb->number = index;
1429     cb->isSelect = isSelect ? true : false;
1430     NapiCallback::CompleteCallback(env_, cb);
1431 }
1432 
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)1433 void AVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
1434 {
1435     (void)extra;
1436     std::vector<Format> trackInfo;
1437     (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
1438     MEDIA_LOGI("OnTrackInfoUpdate callback");
1439 
1440     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE) != refMap_.end(),
1441         "can not find trackInfoUpdate callback!");
1442 
1443     NapiCallback::TrackInfoUpdate *cb = new(std::nothrow) NapiCallback::TrackInfoUpdate();
1444     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackInfoUpdate");
1445 
1446     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE);
1447     cb->callbackName = AVPlayerEvent::EVENT_TRACK_INFO_UPDATE;
1448     cb->trackInfo = trackInfo;
1449     NapiCallback::CompleteCallback(env_, cb);
1450 }
1451 
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)1452 void AVPlayerCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
1453 {
1454     std::lock_guard<std::mutex> lock(mutex_);
1455     refMap_[name] = ref;
1456 }
1457 
ClearCallbackReference()1458 void AVPlayerCallback::ClearCallbackReference()
1459 {
1460     std::lock_guard<std::mutex> lock(mutex_);
1461     refMap_.clear();
1462 }
1463 
ClearCallbackReference(const std::string & name)1464 void AVPlayerCallback::ClearCallbackReference(const std::string &name)
1465 {
1466     std::lock_guard<std::mutex> lock(mutex_);
1467     refMap_.erase(name);
1468 }
1469 
Start()1470 void AVPlayerCallback::Start()
1471 {
1472     isloaded_ = true;
1473 }
1474 
Pause()1475 void AVPlayerCallback::Pause()
1476 {
1477     isloaded_ = false;
1478 }
1479 
Release()1480 void AVPlayerCallback::Release()
1481 {
1482     std::lock_guard<std::mutex> lock(mutex_);
1483 
1484     Format infoBody;
1485     AVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
1486     listener_ = nullptr;
1487 }
1488 } // namespace Media
1489 } // namespace OHOS
1490