• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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