• 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.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