1 /*
2 * Copyright (C) 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 <iomanip>
17 #include <sstream>
18 #include "cj_avplayer_callback.h"
19
20 #include "media_errors.h"
21 #include "media_log.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "CJAVPlayerCallback"};
25 }
26
27 namespace OHOS {
28 namespace Media {
CJAVPlayerCallback(CJAVPlayerNotify * listener)29 CJAVPlayerCallback::CJAVPlayerCallback(CJAVPlayerNotify *listener) : listener_(listener)
30 {
31 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
32 onInfoFuncs_ = {
33 {INFO_TYPE_STATE_CHANGE,
34 [this](const int32_t extra, const Format &infoBody) { OnStateChangeCb(extra, infoBody); }},
35 {INFO_TYPE_VOLUME_CHANGE,
36 [this](const int32_t extra, const Format &infoBody) { OnVolumeChangeCb(extra, infoBody); }},
37 {INFO_TYPE_SEEKDONE, [this](const int32_t extra, const Format &infoBody) { OnSeekDoneCb(extra, infoBody); }},
38 {INFO_TYPE_SPEEDDONE, [this](const int32_t extra, const Format &infoBody) { OnSpeedDoneCb(extra, infoBody); }},
39 {INFO_TYPE_BITRATEDONE,
40 [this](const int32_t extra, const Format &infoBody) { OnBitRateDoneCb(extra, infoBody); }},
41 {INFO_TYPE_POSITION_UPDATE,
42 [this](const int32_t extra, const Format &infoBody) { OnPositionUpdateCb(extra, infoBody); }},
43 {INFO_TYPE_DURATION_UPDATE,
44 [this](const int32_t extra, const Format &infoBody) { OnDurationUpdateCb(extra, infoBody); }},
45 {INFO_TYPE_BUFFERING_UPDATE,
46 [this](const int32_t extra, const Format &infoBody) { OnBufferingUpdateCb(extra, infoBody); }},
47 {INFO_TYPE_MESSAGE, [this](const int32_t extra, const Format &infoBody) { OnMessageCb(extra, infoBody); }},
48 {INFO_TYPE_RESOLUTION_CHANGE,
49 [this](const int32_t extra, const Format &infoBody) { OnVideoSizeChangedCb(extra, infoBody); }},
50 {INFO_TYPE_INTERRUPT_EVENT,
51 [this](const int32_t extra, const Format &infoBody) { OnAudioInterruptCb(extra, infoBody); }},
52 {INFO_TYPE_BITRATE_COLLECT,
53 [this](const int32_t extra, const Format &infoBody) { OnBitRateCollectedCb(extra, infoBody); }},
54 {INFO_TYPE_EOS, [this](const int32_t extra, const Format &infoBody) { OnEosCb(extra, infoBody); }},
55 {INFO_TYPE_TRACKCHANGE,
56 [this](const int32_t extra, const Format &infoBody) { OnTrackChangedCb(extra, infoBody); }},
57 {INFO_TYPE_TRACK_INFO_UPDATE,
58 [this](const int32_t extra, const Format &infoBody) { OnTrackInfoUpdate(extra, infoBody); }},
59 {INFO_TYPE_DRM_INFO_UPDATED,
60 [this](const int32_t extra, const Format &infoBody) { OnDrmInfoUpdatedCb(extra, infoBody); }},
61 {INFO_TYPE_SUBTITLE_UPDATE_INFO,
62 [this](const int32_t extra, const Format &infoBody) { OnSubtitleInfoCb(extra, infoBody); }},
63 {INFO_TYPE_AUDIO_DEVICE_CHANGE,
64 [this](const int32_t extra, const Format &infoBody) { OnAudioDeviceChangeCb(extra, infoBody); }},
65 {INFO_TYPE_MAX_AMPLITUDE_COLLECT,
66 [this](const int32_t extra, const Format &infoBody) { OnMaxAmplitudeCollectedCb(extra, infoBody); }},
67 };
68 }
69
OnAudioDeviceChangeCb(const int32_t extra,const Format & infoBody)70 void CJAVPlayerCallback::OnAudioDeviceChangeCb(const int32_t extra, const Format &infoBody)
71 {
72 (void)extra;
73 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
74 if (audioDeviceChangeCallback == nullptr) {
75 MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find audio AudioDeviceChange callback!", FAKE_POINTER(this));
76 return;
77 }
78
79 uint8_t *parcelBuffer = nullptr;
80 size_t parcelSize;
81 infoBody.GetBuffer(PlayerKeys::AUDIO_DEVICE_CHANGE, &parcelBuffer, parcelSize);
82 Parcel parcel;
83 parcel.WriteBuffer(parcelBuffer, parcelSize);
84 AudioStandard::AudioDeviceDescriptor deviceInfo(AudioStandard::AudioDeviceDescriptor::DEVICE_INFO);
85 deviceInfo.Unmarshalling(parcel);
86
87 int32_t reason;
88 infoBody.GetIntValue(PlayerKeys::AUDIO_DEVICE_CHANGE_REASON, reason);
89
90 audioDeviceChangeCallback(deviceInfo, reason);
91 }
92
~CJAVPlayerCallback()93 CJAVPlayerCallback::~CJAVPlayerCallback()
94 {
95 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
96 }
97
OnError(int32_t errorCode,const std::string & errorMsg)98 void CJAVPlayerCallback::OnError(int32_t errorCode, const std::string &errorMsg)
99 {
100 MediaServiceExtErrCodeAPI9 errorCodeApi9 = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errorCode));
101 if (errorCodeApi9 == MSERR_EXT_API9_NO_PERMISSION || errorCodeApi9 == MSERR_EXT_API9_NO_MEMORY ||
102 errorCodeApi9 == MSERR_EXT_API9_TIMEOUT || errorCodeApi9 == MSERR_EXT_API9_SERVICE_DIED ||
103 errorCodeApi9 == MSERR_EXT_API9_UNSUPPORT_FORMAT) {
104 Format infoBody;
105 CJAVPlayerCallback::OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, infoBody);
106 }
107 CJAVPlayerCallback::OnErrorCb(errorCodeApi9, errorMsg);
108 }
109
OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode,const std::string & errorMsg)110 void CJAVPlayerCallback::OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg)
111 {
112 std::string message = MSExtAVErrorToString(errorCode) + errorMsg;
113 MEDIA_LOGE("OnErrorCb:errorCode %{public}d, errorMsg %{public}s", errorCode, message.c_str());
114 if (errorCallback == nullptr) {
115 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find error callback!", FAKE_POINTER(this));
116 return;
117 }
118 errorCallback(errorCode, errorMsg);
119 }
120
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)121 void CJAVPlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
122 {
123 std::lock_guard<std::mutex> lock(mutex_);
124 MEDIA_LOGD("OnInfo is called, PlayerOnInfoType: %{public}d", type);
125 if (onInfoFuncs_.count(type) > 0) {
126 onInfoFuncs_[type](extra, infoBody);
127 } else {
128 MEDIA_LOGD("0x%{public}06" PRIXPTR " OnInfo: no member func supporting, %{public}d", FAKE_POINTER(this), type);
129 }
130 }
131
IsValidState(PlayerStates state,std::string & stateStr)132 bool CJAVPlayerCallback::IsValidState(PlayerStates state, std::string &stateStr)
133 {
134 switch (state) {
135 case PlayerStates::PLAYER_IDLE:
136 stateStr = AVPlayerState::STATE_IDLE;
137 break;
138 case PlayerStates::PLAYER_INITIALIZED:
139 stateStr = AVPlayerState::STATE_INITIALIZED;
140 break;
141 case PlayerStates::PLAYER_PREPARED:
142 stateStr = AVPlayerState::STATE_PREPARED;
143 break;
144 case PlayerStates::PLAYER_STARTED:
145 stateStr = AVPlayerState::STATE_PLAYING;
146 break;
147 case PlayerStates::PLAYER_PAUSED:
148 stateStr = AVPlayerState::STATE_PAUSED;
149 break;
150 case PlayerStates::PLAYER_STOPPED:
151 stateStr = AVPlayerState::STATE_STOPPED;
152 break;
153 case PlayerStates::PLAYER_PLAYBACK_COMPLETE:
154 stateStr = AVPlayerState::STATE_COMPLETED;
155 break;
156 case PlayerStates::PLAYER_RELEASED:
157 stateStr = AVPlayerState::STATE_RELEASED;
158 break;
159 case PlayerStates::PLAYER_STATE_ERROR:
160 stateStr = AVPlayerState::STATE_ERROR;
161 break;
162 default:
163 return false;
164 }
165 return true;
166 }
167
OnStateChangeCb(const int32_t extra,const Format & infoBody)168 void CJAVPlayerCallback::OnStateChangeCb(const int32_t extra, const Format &infoBody)
169 {
170 PlayerStates state = static_cast<PlayerStates>(extra);
171 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instance OnStateChanged is called, current state: %{public}d",
172 FAKE_POINTER(this), state);
173
174 if (listener_ != nullptr) {
175 listener_->NotifyState(state);
176 }
177
178 if (state_ != state) {
179 state_ = state;
180 std::string stateStr;
181 if (IsValidState(state, stateStr)) {
182 if (stateChangeCallback == nullptr) {
183 MEDIA_LOGW("can not find state change callback!");
184 return;
185 }
186
187 int32_t reason = StateChangeReason::USER;
188 if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
189 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
190 }
191 stateChangeCallback(stateStr, reason);
192 }
193 }
194 }
195
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)196 void CJAVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
197 {
198 (void)extra;
199 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
200 float volumeLevel = 0.0;
201 (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
202
203 isSetVolume_ = false;
204 MEDIA_LOGD("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
205 if (volumeChangeCallback == nullptr) {
206 MEDIA_LOGD("can not find vol change callback!");
207 return;
208 }
209 volumeChangeCallback(volumeLevel);
210 }
211
OnSeekDoneCb(const int32_t extra,const Format & infoBody)212 void CJAVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
213 {
214 (void)infoBody;
215 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
216 int32_t currentPositon = extra;
217 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSeekDone is called, currentPositon: %{public}d", FAKE_POINTER(this),
218 currentPositon);
219 if (seekDoneCallback == nullptr) {
220 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find seekdone callback!", FAKE_POINTER(this));
221 return;
222 }
223 seekDoneCallback(currentPositon);
224 }
225
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)226 void CJAVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
227 {
228 (void)infoBody;
229 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
230 int32_t speedMode = extra;
231 MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
232 if (speedDoneCallback == nullptr) {
233 MEDIA_LOGW("can not find speeddone callback!");
234 return;
235 }
236 speedDoneCallback(speedMode);
237 }
238
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)239 void CJAVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
240 {
241 (void)infoBody;
242 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
243 int32_t bitRate = extra;
244 MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
245 if (bitRateDoneCallback == nullptr) {
246 MEDIA_LOGW("can not find bitrate callback!");
247 return;
248 }
249 bitRateDoneCallback(bitRate);
250 }
251
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)252 void CJAVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
253 {
254 (void)infoBody;
255 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
256 int32_t position = extra;
257 MEDIA_LOGD("OnPositionUpdateCb is called, position: %{public}d", position);
258
259 if (listener_ != nullptr) {
260 listener_->NotifyPosition(position);
261 }
262
263 if (timeUpdateCallback == nullptr) {
264 MEDIA_LOGD("can not find timeupdate callback!");
265 return;
266 }
267 timeUpdateCallback(position);
268 }
269
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)270 void CJAVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
271 {
272 (void)infoBody;
273 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
274 int32_t duration = extra;
275 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnDurationUpdateCb is called, duration: %{public}d", FAKE_POINTER(this),
276 duration);
277
278 if (listener_ != nullptr) {
279 listener_->NotifyDuration(duration);
280 }
281
282 if (durationUpdateCallback == nullptr) {
283 MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find duration update callback!", FAKE_POINTER(this));
284 return;
285 }
286 durationUpdateCallback(duration);
287 }
288
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)289 void CJAVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
290 {
291 (void)extra;
292 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
293 if (bufferingUpdateCallback == nullptr) {
294 MEDIA_LOGD("can not find buffering update callback!");
295 return;
296 }
297
298 int32_t val = 0;
299 int32_t bufferingType = -1;
300 if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
301 bufferingType = BUFFERING_START;
302 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), val);
303 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
304 bufferingType = BUFFERING_END;
305 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), val);
306 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
307 bufferingType = BUFFERING_PERCENT;
308 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), val);
309 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
310 bufferingType = CACHED_DURATION;
311 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), val);
312 } else {
313 return;
314 }
315 bufferingUpdateCallback(bufferingType, val);
316 }
317
OnMessageCb(const int32_t extra,const Format & infoBody)318 void CJAVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
319 {
320 (void)infoBody;
321 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
322 MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
323 if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
324 CJAVPlayerCallback::OnStartRenderFrameCb();
325 }
326 }
327
OnStartRenderFrameCb() const328 void CJAVPlayerCallback::OnStartRenderFrameCb() const
329 {
330 MEDIA_LOGI("OnStartRenderFrameCb is called");
331 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
332 if (startRenderFrameCallback == nullptr) {
333 MEDIA_LOGW("can not find start render callback!");
334 return;
335 }
336 startRenderFrameCallback();
337 }
338
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)339 void CJAVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
340 {
341 (void)extra;
342 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
343 int32_t width = 0;
344 int32_t height = 0;
345 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
346 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
347 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d",
348 FAKE_POINTER(this), width, height);
349
350 if (listener_ != nullptr) {
351 listener_->NotifyVideoSize(width, height);
352 }
353
354 if (videoSizeChangeCallback == nullptr) {
355 MEDIA_LOGW("can not find video size changed callback!");
356 return;
357 }
358 videoSizeChangeCallback(width, height);
359 }
360
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)361 void CJAVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
362 {
363 (void)extra;
364 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
365 if (audioInterruptCallback == nullptr) {
366 MEDIA_LOGW("can not find audio interrupt callback!");
367 return;
368 }
369 int32_t eventType = 0;
370 int32_t forceType = 0;
371 int32_t hintType = 0;
372 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
373 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
374 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
375 MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
376 eventType, forceType, hintType);
377 audioInterruptCallback(eventType, forceType, hintType);
378 }
379
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)380 void CJAVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
381 {
382 (void)extra;
383 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
384 if (availableBitratesCallback == nullptr) {
385 MEDIA_LOGW("can not find bitrate collected callback!");
386 return;
387 }
388
389 std::vector<int32_t> bitrateVec;
390 if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES))) {
391 uint8_t *addr = nullptr;
392 size_t size = 0;
393 infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES), &addr, size);
394 CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
395
396 MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
397 while (size > 0) {
398 if (size < sizeof(uint32_t)) {
399 break;
400 }
401
402 uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
403 MEDIA_LOGI("bitrate = %{public}u", bitrate);
404 addr += sizeof(uint32_t);
405 size -= sizeof(uint32_t);
406 bitrateVec.push_back(static_cast<int32_t>(bitrate));
407 }
408 }
409 availableBitratesCallback(bitrateVec);
410 }
411
OnMaxAmplitudeCollectedCb(const int32_t extra,const Format & infoBody)412 void CJAVPlayerCallback::OnMaxAmplitudeCollectedCb(const int32_t extra, const Format &infoBody)
413 {
414 (void)extra;
415 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
416 if (amplitudeUpdateCallback == nullptr) {
417 MEDIA_LOGD("can not find max amplitude collected callback!");
418 return;
419 }
420
421 std::vector<float> MaxAmplitudeVec;
422 if (infoBody.ContainKey(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE))) {
423 uint8_t *addr = nullptr;
424 size_t size = 0;
425 infoBody.GetBuffer(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE), &addr, size);
426 CHECK_AND_RETURN_LOG(addr != nullptr, "max amplitude addr is nullptr");
427
428 MEDIA_LOGD("max amplitude size = %{public}zu", size / sizeof(float));
429 while (size > 0) {
430 if (size < sizeof(float)) {
431 break;
432 }
433
434 float maxAmplitude = *(static_cast<float *>(static_cast<void *>(addr)));
435 MEDIA_LOGD("maxAmplitude = %{public}f", maxAmplitude);
436 addr += sizeof(float);
437 size -= sizeof(float);
438 MaxAmplitudeVec.push_back(static_cast<float>(maxAmplitude));
439 }
440 }
441
442 amplitudeUpdateCallback(MaxAmplitudeVec);
443 }
444
SetDrmInfoData(const uint8_t * drmInfoAddr,int32_t infoCount,std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)445 int32_t CJAVPlayerCallback::SetDrmInfoData(const uint8_t *drmInfoAddr, int32_t infoCount,
446 std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
447 {
448 DrmInfoItem *drmInfos = reinterpret_cast<DrmInfoItem *>(const_cast<uint8_t *>(drmInfoAddr));
449 CHECK_AND_RETURN_RET_LOG(drmInfos != nullptr, MSERR_INVALID_VAL, "cast drmInfos nullptr");
450 for (int32_t i = 0; i < infoCount; i++) {
451 DrmInfoItem temp = drmInfos[i];
452 std::stringstream ssConverter;
453 std::string uuid;
454 for (uint32_t index = 0; index < DrmConstant::DRM_MAX_M3U8_DRM_UUID_LEN; index++) {
455 int32_t singleUuid = static_cast<int32_t>(temp.uuid[index]);
456 ssConverter << std::hex << std::setfill('0') << std::setw(2) << singleUuid; // 2:w
457 uuid = ssConverter.str();
458 }
459 std::vector<uint8_t> pssh(temp.pssh, temp.pssh + temp.psshLen);
460 drmInfoMap.insert({uuid, pssh});
461 }
462
463 if (listener_ != nullptr) {
464 listener_->NotifyDrmInfoUpdated(drmInfoMap);
465 }
466 return MSERR_OK;
467 }
468
Convert2CMediaKeySystemInfo(std::string uuid,std::vector<uint8_t> pssh)469 CMediaKeySystemInfo Convert2CMediaKeySystemInfo(std::string uuid, std::vector<uint8_t> pssh)
470 {
471 CMediaKeySystemInfo result = CMediaKeySystemInfo{0};
472 result.uuid = MallocCString(uuid);
473 if (pssh.size() == 0) {
474 return result;
475 }
476 uint8_t *head = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * pssh.size()));
477 if (head == nullptr) {
478 return result;
479 }
480 for (size_t i = 0; i < pssh.size(); i++) {
481 head[i] = pssh[i];
482 }
483 result.pssh = CArrUI8{.head = head, .size = pssh.size()};
484 return result;
485 }
486
Convert2CArrCMediaKeySystemInfo(const std::multimap<std::string,std::vector<uint8_t>> drmInfoMap)487 CArrCMediaKeySystemInfo Convert2CArrCMediaKeySystemInfo(const std::multimap<std::string,
488 std::vector<uint8_t>> drmInfoMap)
489 {
490 if (drmInfoMap.size() == 0) {
491 return CArrCMediaKeySystemInfo{0};
492 }
493 CMediaKeySystemInfo *head =
494 static_cast<CMediaKeySystemInfo *>(malloc(sizeof(CMediaKeySystemInfo) * drmInfoMap.size()));
495 if (head == nullptr) {
496 return CArrCMediaKeySystemInfo{0};
497 }
498 int64_t index = 0;
499 for (auto iter = drmInfoMap.begin(); iter != drmInfoMap.end(); iter++) {
500 head[index] = Convert2CMediaKeySystemInfo(iter->first, iter->second);
501 index++;
502 }
503 return CArrCMediaKeySystemInfo{.head = head, .size = drmInfoMap.size()};
504 }
505
OnDrmInfoUpdatedCb(const int32_t extra,const Format & infoBody)506 void CJAVPlayerCallback::OnDrmInfoUpdatedCb(const int32_t extra, const Format &infoBody)
507 {
508 (void)extra;
509 MEDIA_LOGI("CJAVPlayerCallback OnDrmInfoUpdatedCb is called");
510 if (mediaKeySystemInfoUpdateCallback == nullptr) {
511 MEDIA_LOGW("can not find drm info updated callback!");
512 return;
513 }
514 if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR))) {
515 MEDIA_LOGW("there's no drminfo-update drm_info_addr key");
516 return;
517 }
518 if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT))) {
519 MEDIA_LOGW("there's no drminfo-update drm_info_count key");
520 return;
521 }
522
523 uint8_t *drmInfoAddr = nullptr;
524 size_t size = 0;
525 int32_t infoCount = 0;
526 infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR), &drmInfoAddr, size);
527 CHECK_AND_RETURN_LOG(drmInfoAddr != nullptr && size > 0, "get drminfo buffer failed");
528 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT), infoCount);
529 CHECK_AND_RETURN_LOG(infoCount > 0, "get drminfo count is illegal");
530
531 std::multimap<std::string, std::vector<uint8_t>> drmInfoMap;
532 int32_t ret = SetDrmInfoData(drmInfoAddr, infoCount, drmInfoMap);
533 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetDrmInfoData err");
534 CArrCMediaKeySystemInfo cArrCMediaKeySystemInfo = Convert2CArrCMediaKeySystemInfo(drmInfoMap);
535 mediaKeySystemInfoUpdateCallback(cArrCMediaKeySystemInfo);
536 if (cArrCMediaKeySystemInfo.head != nullptr) {
537 for (int64_t i = 0; i < cArrCMediaKeySystemInfo.size; i++) {
538 free(cArrCMediaKeySystemInfo.head[i].uuid);
539 free(cArrCMediaKeySystemInfo.head[i].pssh.head);
540 }
541 free(cArrCMediaKeySystemInfo.head);
542 }
543 }
544
OnSubtitleInfoCb(const int32_t extra,const Format & infoBody)545 void CJAVPlayerCallback::OnSubtitleInfoCb(const int32_t extra, const Format &infoBody)
546 {
547 (void)infoBody;
548 int32_t pts = -1;
549 int32_t duration = -1;
550 std::string text;
551 infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, text);
552 infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_PTS), pts);
553 infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_DURATION), duration);
554 MEDIA_LOGI("OnSubtitleInfoCb pts %{public}d, duration = %{public}d", pts, duration);
555
556 CHECK_AND_RETURN_LOG(subtitleUpdateCallback != nullptr, "can not find Subtitle callback!");
557
558 subtitleUpdateCallback(text, pts, duration);
559 }
560
OnEosCb(const int32_t extra,const Format & infoBody)561 void CJAVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
562 {
563 (void)infoBody;
564 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
565 int32_t isLooping = extra;
566 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnEndOfStream is called, isloop: %{public}d", FAKE_POINTER(this), isLooping);
567 if (endOfStreamCallback == nullptr) {
568 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find EndOfStream callback!", FAKE_POINTER(this));
569 return;
570 }
571 endOfStreamCallback();
572 }
573
OnTrackChangedCb(const int32_t extra,const Format & infoBody)574 void CJAVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
575 {
576 (void)extra;
577 int32_t index = -1;
578 int32_t isSelect = -1;
579 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
580 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
581 MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
582
583 CHECK_AND_RETURN_LOG(trackChangeCallback != nullptr, "can not find trackChange callback!");
584
585 trackChangeCallback(index, isSelect);
586 }
587
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)588 void CJAVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
589 {
590 (void)extra;
591 std::vector<Format> trackInfo;
592 (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
593
594 MEDIA_LOGI("OnTrackInfoUpdate callback");
595
596 CHECK_AND_RETURN_LOG(trackInfoUpdateCallback != nullptr, "can not find trackInfoUpdate callback!");
597
598 trackInfoUpdateCallback(Convert2CArrCMediaDescription(trackInfo));
599 }
600
Start()601 void CJAVPlayerCallback::Start()
602 {
603 isloaded_ = true;
604 }
605
Pause()606 void CJAVPlayerCallback::Pause()
607 {
608 isloaded_ = false;
609 }
610
Release()611 void CJAVPlayerCallback::Release()
612 {
613 std::lock_guard<std::mutex> lock(mutex_);
614
615 Format infoBody;
616 CJAVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
617 listener_ = nullptr;
618 }
619
620 } // namespace Media
621 } // namespace OHOS
622