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.UnmarshallingSelf(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 std::lock_guard<std::mutex> lock(mutex_);
179 if (state_ != state) {
180 state_ = state;
181 std::string stateStr;
182 if (IsValidState(state, stateStr)) {
183 if (stateChangeCallback == nullptr) {
184 MEDIA_LOGW("can not find state change callback!");
185 return;
186 }
187
188 int32_t reason = StateChangeReason::USER;
189 if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
190 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
191 }
192 stateChangeCallback(stateStr, reason);
193 }
194 }
195 }
196
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)197 void CJAVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
198 {
199 (void)extra;
200 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
201 float volumeLevel = 0.0;
202 (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
203
204 isSetVolume_ = false;
205 MEDIA_LOGD("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
206 if (volumeChangeCallback == nullptr) {
207 MEDIA_LOGD("can not find vol change callback!");
208 return;
209 }
210 volumeChangeCallback(volumeLevel);
211 }
212
OnSeekDoneCb(const int32_t extra,const Format & infoBody)213 void CJAVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
214 {
215 (void)infoBody;
216 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
217 int32_t currentPositon = extra;
218 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSeekDone is called, currentPositon: %{public}d", FAKE_POINTER(this),
219 currentPositon);
220 if (seekDoneCallback == nullptr) {
221 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find seekdone callback!", FAKE_POINTER(this));
222 return;
223 }
224 seekDoneCallback(currentPositon);
225 }
226
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)227 void CJAVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
228 {
229 (void)infoBody;
230 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
231 int32_t speedMode = extra;
232 MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
233 if (speedDoneCallback == nullptr) {
234 MEDIA_LOGW("can not find speeddone callback!");
235 return;
236 }
237 speedDoneCallback(speedMode);
238 }
239
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)240 void CJAVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
241 {
242 (void)infoBody;
243 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
244 int32_t bitRate = extra;
245 MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
246 if (bitRateDoneCallback == nullptr) {
247 MEDIA_LOGW("can not find bitrate callback!");
248 return;
249 }
250 bitRateDoneCallback(bitRate);
251 }
252
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)253 void CJAVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
254 {
255 (void)infoBody;
256 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
257 int32_t position = extra;
258 MEDIA_LOGD("OnPositionUpdateCb is called, position: %{public}d", position);
259
260 if (listener_ != nullptr) {
261 listener_->NotifyPosition(position);
262 }
263
264 if (timeUpdateCallback == nullptr) {
265 MEDIA_LOGD("can not find timeupdate callback!");
266 return;
267 }
268 timeUpdateCallback(position);
269 }
270
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)271 void CJAVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
272 {
273 (void)infoBody;
274 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
275 int32_t duration = extra;
276 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnDurationUpdateCb is called, duration: %{public}d", FAKE_POINTER(this),
277 duration);
278
279 if (listener_ != nullptr) {
280 listener_->NotifyDuration(duration);
281 }
282
283 if (durationUpdateCallback == nullptr) {
284 MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find duration update callback!", FAKE_POINTER(this));
285 return;
286 }
287 durationUpdateCallback(duration);
288 }
289
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)290 void CJAVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
291 {
292 (void)extra;
293 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
294 if (bufferingUpdateCallback == nullptr) {
295 MEDIA_LOGD("can not find buffering update callback!");
296 return;
297 }
298
299 int32_t val = 0;
300 int32_t bufferingType = -1;
301 if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
302 bufferingType = BUFFERING_START;
303 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), val);
304 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
305 bufferingType = BUFFERING_END;
306 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), val);
307 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
308 bufferingType = BUFFERING_PERCENT;
309 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), val);
310 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
311 bufferingType = CACHED_DURATION;
312 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), val);
313 } else {
314 return;
315 }
316 bufferingUpdateCallback(bufferingType, val);
317 }
318
OnMessageCb(const int32_t extra,const Format & infoBody)319 void CJAVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
320 {
321 (void)infoBody;
322 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
323 MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
324 if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
325 CJAVPlayerCallback::OnStartRenderFrameCb();
326 }
327 }
328
OnStartRenderFrameCb() const329 void CJAVPlayerCallback::OnStartRenderFrameCb() const
330 {
331 MEDIA_LOGI("OnStartRenderFrameCb is called");
332 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
333 if (startRenderFrameCallback == nullptr) {
334 MEDIA_LOGW("can not find start render callback!");
335 return;
336 }
337 startRenderFrameCallback();
338 }
339
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)340 void CJAVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
341 {
342 (void)extra;
343 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
344 int32_t width = 0;
345 int32_t height = 0;
346 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
347 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
348 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d",
349 FAKE_POINTER(this), width, height);
350
351 if (listener_ != nullptr) {
352 listener_->NotifyVideoSize(width, height);
353 }
354
355 if (videoSizeChangeCallback == nullptr) {
356 MEDIA_LOGW("can not find video size changed callback!");
357 return;
358 }
359 videoSizeChangeCallback(width, height);
360 }
361
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)362 void CJAVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
363 {
364 (void)extra;
365 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
366 if (audioInterruptCallback == nullptr) {
367 MEDIA_LOGW("can not find audio interrupt callback!");
368 return;
369 }
370 int32_t eventType = 0;
371 int32_t forceType = 0;
372 int32_t hintType = 0;
373 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
374 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
375 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
376 MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
377 eventType, forceType, hintType);
378 audioInterruptCallback(eventType, forceType, hintType);
379 }
380
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)381 void CJAVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
382 {
383 (void)extra;
384 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
385 if (availableBitratesCallback == nullptr) {
386 MEDIA_LOGW("can not find bitrate collected callback!");
387 return;
388 }
389
390 std::vector<int32_t> bitrateVec;
391 if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES))) {
392 uint8_t *addr = nullptr;
393 size_t size = 0;
394 infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES), &addr, size);
395 CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
396
397 MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
398 while (size > 0) {
399 if (size < sizeof(uint32_t)) {
400 break;
401 }
402
403 uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
404 MEDIA_LOGI("bitrate = %{public}u", bitrate);
405 addr += sizeof(uint32_t);
406 size -= sizeof(uint32_t);
407 bitrateVec.push_back(static_cast<int32_t>(bitrate));
408 }
409 }
410 availableBitratesCallback(bitrateVec);
411 }
412
OnMaxAmplitudeCollectedCb(const int32_t extra,const Format & infoBody)413 void CJAVPlayerCallback::OnMaxAmplitudeCollectedCb(const int32_t extra, const Format &infoBody)
414 {
415 (void)extra;
416 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
417 if (amplitudeUpdateCallback == nullptr) {
418 MEDIA_LOGD("can not find max amplitude collected callback!");
419 return;
420 }
421
422 std::vector<float> MaxAmplitudeVec;
423 if (infoBody.ContainKey(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE))) {
424 uint8_t *addr = nullptr;
425 size_t size = 0;
426 infoBody.GetBuffer(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE), &addr, size);
427 CHECK_AND_RETURN_LOG(addr != nullptr, "max amplitude addr is nullptr");
428
429 MEDIA_LOGD("max amplitude size = %{public}zu", size / sizeof(float));
430 while (size > 0) {
431 if (size < sizeof(float)) {
432 break;
433 }
434
435 float maxAmplitude = *(static_cast<float *>(static_cast<void *>(addr)));
436 MEDIA_LOGD("maxAmplitude = %{public}f", maxAmplitude);
437 addr += sizeof(float);
438 size -= sizeof(float);
439 MaxAmplitudeVec.push_back(static_cast<float>(maxAmplitude));
440 }
441 }
442
443 amplitudeUpdateCallback(MaxAmplitudeVec);
444 }
445
SetDrmInfoData(const uint8_t * drmInfoAddr,int32_t infoCount,std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)446 int32_t CJAVPlayerCallback::SetDrmInfoData(const uint8_t *drmInfoAddr, int32_t infoCount,
447 std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
448 {
449 DrmInfoItem *drmInfos = reinterpret_cast<DrmInfoItem *>(const_cast<uint8_t *>(drmInfoAddr));
450 CHECK_AND_RETURN_RET_LOG(drmInfos != nullptr, MSERR_INVALID_VAL, "cast drmInfos nullptr");
451 for (int32_t i = 0; i < infoCount; i++) {
452 DrmInfoItem temp = drmInfos[i];
453 std::stringstream ssConverter;
454 std::string uuid;
455 for (uint32_t index = 0; index < DrmConstant::DRM_MAX_M3U8_DRM_UUID_LEN; index++) {
456 int32_t singleUuid = static_cast<int32_t>(temp.uuid[index]);
457 ssConverter << std::hex << std::setfill('0') << std::setw(2) << singleUuid; // 2:w
458 uuid = ssConverter.str();
459 }
460 if (temp.psshLen <= 0 || temp.psshLen > DrmConstant::DRM_MAX_M3U8_DRM_PSSH_LEN) {
461 MEDIA_LOGW("drmInfoItem psshLen is invalid");
462 continue;
463 }
464 std::vector<uint8_t> pssh(temp.pssh, temp.pssh + temp.psshLen);
465 drmInfoMap.insert({uuid, pssh});
466 }
467
468 if (listener_ != nullptr) {
469 listener_->NotifyDrmInfoUpdated(drmInfoMap);
470 }
471 return MSERR_OK;
472 }
473
Convert2CMediaKeySystemInfo(std::string uuid,std::vector<uint8_t> pssh)474 CMediaKeySystemInfo Convert2CMediaKeySystemInfo(std::string uuid, std::vector<uint8_t> pssh)
475 {
476 CMediaKeySystemInfo result = CMediaKeySystemInfo{0};
477 result.uuid = MallocCString(uuid);
478 if (pssh.size() == 0) {
479 return result;
480 }
481 uint8_t *head = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * pssh.size()));
482 if (head == nullptr) {
483 return result;
484 }
485 for (size_t i = 0; i < pssh.size(); i++) {
486 head[i] = pssh[i];
487 }
488 result.pssh = CArrUI8{.head = head, .size = pssh.size()};
489 return result;
490 }
491
Convert2CArrCMediaKeySystemInfo(const std::multimap<std::string,std::vector<uint8_t>> drmInfoMap)492 CArrCMediaKeySystemInfo Convert2CArrCMediaKeySystemInfo(const std::multimap<std::string,
493 std::vector<uint8_t>> drmInfoMap)
494 {
495 if (drmInfoMap.size() == 0) {
496 return CArrCMediaKeySystemInfo{0};
497 }
498 CMediaKeySystemInfo *head =
499 static_cast<CMediaKeySystemInfo *>(malloc(sizeof(CMediaKeySystemInfo) * drmInfoMap.size()));
500 if (head == nullptr) {
501 return CArrCMediaKeySystemInfo{0};
502 }
503 int64_t index = 0;
504 for (auto iter = drmInfoMap.begin(); iter != drmInfoMap.end(); iter++) {
505 head[index] = Convert2CMediaKeySystemInfo(iter->first, iter->second);
506 index++;
507 }
508 return CArrCMediaKeySystemInfo{.head = head, .size = drmInfoMap.size()};
509 }
510
OnDrmInfoUpdatedCb(const int32_t extra,const Format & infoBody)511 void CJAVPlayerCallback::OnDrmInfoUpdatedCb(const int32_t extra, const Format &infoBody)
512 {
513 (void)extra;
514 MEDIA_LOGI("CJAVPlayerCallback OnDrmInfoUpdatedCb is called");
515 if (mediaKeySystemInfoUpdateCallback == nullptr) {
516 MEDIA_LOGW("can not find drm info updated callback!");
517 return;
518 }
519 if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR))) {
520 MEDIA_LOGW("there's no drminfo-update drm_info_addr key");
521 return;
522 }
523 if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT))) {
524 MEDIA_LOGW("there's no drminfo-update drm_info_count key");
525 return;
526 }
527
528 uint8_t *drmInfoAddr = nullptr;
529 size_t size = 0;
530 int32_t infoCount = 0;
531 infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR), &drmInfoAddr, size);
532 CHECK_AND_RETURN_LOG(drmInfoAddr != nullptr && size > 0, "get drminfo buffer failed");
533 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT), infoCount);
534 CHECK_AND_RETURN_LOG(infoCount > 0, "get drminfo count is illegal");
535
536 std::multimap<std::string, std::vector<uint8_t>> drmInfoMap;
537 int32_t ret = SetDrmInfoData(drmInfoAddr, infoCount, drmInfoMap);
538 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetDrmInfoData err");
539 CArrCMediaKeySystemInfo cArrCMediaKeySystemInfo = Convert2CArrCMediaKeySystemInfo(drmInfoMap);
540 mediaKeySystemInfoUpdateCallback(cArrCMediaKeySystemInfo);
541 if (cArrCMediaKeySystemInfo.head != nullptr) {
542 for (int64_t i = 0; i < cArrCMediaKeySystemInfo.size; i++) {
543 free(cArrCMediaKeySystemInfo.head[i].uuid);
544 free(cArrCMediaKeySystemInfo.head[i].pssh.head);
545 }
546 free(cArrCMediaKeySystemInfo.head);
547 }
548 }
549
OnSubtitleInfoCb(const int32_t extra,const Format & infoBody)550 void CJAVPlayerCallback::OnSubtitleInfoCb(const int32_t extra, const Format &infoBody)
551 {
552 (void)infoBody;
553 int32_t pts = -1;
554 int32_t duration = -1;
555 std::string text;
556 infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, text);
557 infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_PTS), pts);
558 infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_DURATION), duration);
559 MEDIA_LOGI("OnSubtitleInfoCb pts %{public}d, duration = %{public}d", pts, duration);
560
561 CHECK_AND_RETURN_LOG(subtitleUpdateCallback != nullptr, "can not find Subtitle callback!");
562
563 subtitleUpdateCallback(text, pts, duration);
564 }
565
OnEosCb(const int32_t extra,const Format & infoBody)566 void CJAVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
567 {
568 (void)infoBody;
569 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
570 int32_t isLooping = extra;
571 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnEndOfStream is called, isloop: %{public}d", FAKE_POINTER(this), isLooping);
572 if (endOfStreamCallback == nullptr) {
573 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find EndOfStream callback!", FAKE_POINTER(this));
574 return;
575 }
576 endOfStreamCallback();
577 }
578
OnTrackChangedCb(const int32_t extra,const Format & infoBody)579 void CJAVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
580 {
581 (void)extra;
582 int32_t index = -1;
583 int32_t isSelect = -1;
584 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
585 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
586 MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
587
588 CHECK_AND_RETURN_LOG(trackChangeCallback != nullptr, "can not find trackChange callback!");
589
590 trackChangeCallback(index, isSelect);
591 }
592
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)593 void CJAVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
594 {
595 (void)extra;
596 std::vector<Format> trackInfo;
597 (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
598
599 MEDIA_LOGI("OnTrackInfoUpdate callback");
600
601 CHECK_AND_RETURN_LOG(trackInfoUpdateCallback != nullptr, "can not find trackInfoUpdate callback!");
602
603 trackInfoUpdateCallback(Convert2CArrCMediaDescription(trackInfo));
604 }
605
Start()606 void CJAVPlayerCallback::Start()
607 {
608 isloaded_ = true;
609 }
610
Pause()611 void CJAVPlayerCallback::Pause()
612 {
613 isloaded_ = false;
614 }
615
Release()616 void CJAVPlayerCallback::Release()
617 {
618 std::lock_guard<std::mutex> lock(mutex_);
619
620 Format infoBody;
621 CJAVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
622 listener_ = nullptr;
623 }
624
625 } // namespace Media
626 } // namespace OHOS
627