Files
openharmony_ci 967b81af0d !3260 merge cherry-pick-mr-3242-1784720121552-auto into master
告警修复 IPC输入校验缺失

Created-by: xuhy2
Commit-by: xuhy2;xuhy
Merged-by: openharmony_ci
Description: ### 一、内容说明(相关的Issue)



### 二、建议测试周期和提测地址  
  建议测试完成时间:xxxx.xx.xx  
  投产上线时间:xxxx.xx.xx  
  提测地址:CI环境/压测环境  
  测试账号:  

### 三、变更内容
  * 3.1 关联PR列表

  * 3.2 数据库和部署说明  
    1. 常规更新 
    2. 重启unicorn
    3. 重启sidekiq
    4. 迁移任务:是否有迁移任务,没有写 "无"
    5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无"

  * 3.4 其他技术优化内容(做了什么,变更了什么)
    - 重构了 xxxx 代码
    - xxxx 算法优化


  * 3.5 废弃通知(什么字段、方法弃用?)



  * 3.6  后向不兼容变更(是否有无法向后兼容的变更?)


  
### 四、研发自测点(自测哪些?冒烟用例全部自测?)
  自测测试结论:


### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方)
  检查点:

| 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 |
|------|------------|----------|---------------|
| xxx  | 否          | 需要       | 不需要           |
|      |            |          |               |

  接口测试:

  性能测试:

  并发测试:

  其他:



See merge request: openharmony/multimedia_av_session!3260
2026-07-25 14:05:59 +08:00

1227 lines
53 KiB
C++

/*
* Copyright (c) 2023-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hw_cast_stream_player.h"
#include "int_wrapper.h"
#include "string_wrapper.h"
#include "avsession_log.h"
#include "avcast_player_state.h"
#include "avqueue_item.h"
#include "avmedia_description.h"
#include "avsession_errors.h"
#include "avsession_sysevent.h"
#include "avsession_event_handler.h"
#include "avsession_trace.h"
#include "avsession_radar.h"
#include "avsession_utils.h"
using namespace OHOS::CastEngine;
namespace OHOS::AVSession {
static constexpr size_t DLNA_EXTRAS_MAX_LENGTH = 40960;
HwCastStreamPlayer::~HwCastStreamPlayer()
{
SLOGI("destruct the HwCastStreamPlayer without release");
}
int32_t HwCastStreamPlayer::Init()
{
SLOGI("Init the HwCastStreamPlayer");
std::lock_guard lockGuard(streamPlayerLock_);
if (streamPlayer_) {
SLOGI("register self in streamPlayer");
return streamPlayer_->RegisterListener(shared_from_this());
}
return AVSESSION_ERROR;
}
void HwCastStreamPlayer::Release()
{
SLOGI("Release the HwCastStreamPlayer");
std::lock_guard lockGuard(streamPlayerLock_);
if (streamPlayer_) {
streamPlayer_->UnregisterListener();
streamPlayer_->Release();
streamPlayer_ = nullptr;
}
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
streamPlayerListenerList_.clear();
SLOGI("Release the HwCastStreamPlayer done");
}
int32_t HwCastStreamPlayer::CheckCastTime(int32_t castTime)
{
if (castTime < castMinTime) {
return castMinTime * castTime;
} else {
return castTime;
}
}
void HwCastStreamPlayer::SendControlCommand(const AVCastControlCommand castControlCommand)
{
int32_t commandNum = castControlCommand.GetCommand();
SLOGI("send command to streamPlayer %{public}d", static_cast<int32_t>(commandNum));
std::lock_guard lockGuard(streamPlayerLock_);
if (!streamPlayer_) {
SLOGE("streamPlayer is nullptr");
HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
"SESSION_TYPE", "cast",
"ERROR_TYPE", "INNER_ERROR",
"ERROR_INFO", "streamPlayer is nullptr");
AVSessionRadarInfo info("HwCastStreamPlayer::SendControlCommand");
info.errorCode_ = AVSessionRadar::GetRadarErrorCode(ERR_REMOTE_CONNECTION_NOT_EXIST);
AVSessionRadar::GetInstance().FailToSendControlCommand(info);
return;
}
switch (castControlCommand.GetCommand()) {
case AVCastControlCommand::CAST_CONTROL_CMD_PLAY:
streamPlayer_->Play();
break;
case AVCastControlCommand::CAST_CONTROL_CMD_PAUSE:
streamPlayer_->Pause();
break;
case AVCastControlCommand::CAST_CONTROL_CMD_STOP:
streamPlayer_->Stop();
break;
case AVCastControlCommand::CAST_CONTROL_CMD_PLAY_NEXT:
streamPlayer_->Next();
break;
case AVCastControlCommand::CAST_CONTROL_CMD_PLAY_PREVIOUS:
streamPlayer_->Previous();
break;
default:
SendControlCommandWithParams(castControlCommand);
break;
}
}
void HwCastStreamPlayer::SendCustomData(const std::string& data)
{
std::lock_guard lockGuard(streamPlayerLock_);
if (streamPlayer_ == nullptr) {
SLOGE("streamPlayer is nullptr");
return;
}
streamPlayer_->SendData(DataType::CUSTOM_DATA, data);
}
void HwCastStreamPlayer::SetSpid(uint32_t spid)
{
SLOGI("SetSpid spid %{public}u", spid);
spid_ = spid;
}
void HwCastStreamPlayer::SendControlCommandWithParams(const AVCastControlCommand castControlCommand)
{
std::lock_guard lockGuard(streamPlayerLock_);
int32_t param = 0;
switch (castControlCommand.GetCommand()) {
case AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD:
castControlCommand.GetForwardTime(param);
streamPlayer_->FastForward(CheckCastTime(param));
break;
case AVCastControlCommand::CAST_CONTROL_CMD_REWIND:
castControlCommand.GetRewindTime(param);
streamPlayer_->FastRewind(CheckCastTime(param));
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SEEK:
castControlCommand.GetSeekTime(param);
streamPlayer_->Seek(param);
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SET_VOLUME:
castControlCommand.GetVolume(param);
streamPlayer_->SetVolume(param);
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SET_SPEED:
castControlCommand.GetSpeed(param);
streamPlayer_->SetSpeed(static_cast<CastEngine::PlaybackSpeed>(param));
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SET_LOOP_MODE:
castControlCommand.GetLoopMode(param);
SLOGD("SetLoopMode int: %{public}d", param);
CHECK_AND_RETURN_LOG(intLoopModeToCastPlus_.count(param) != 0, "invalid LoopMode");
streamPlayer_->SetLoopMode(intLoopModeToCastPlus_[param]);
break;
case AVCastControlCommand::CAST_CONTROL_CMD_TOGGLE_FAVORITE:
break;
case AVCastControlCommand::CAST_CONTROL_CMD_TOGGLE_MUTE:
bool enableMute;
streamPlayer_->GetMute(enableMute);
streamPlayer_->SetMute(!enableMute);
break;
default:
SLOGE("invalid command");
HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED", "ERROR_TYPE", "INNER_ERROR", "ERROR_INFO", "invalid command");
break;
}
}
AVQueueItem HwCastStreamPlayer::GetCurrentItem()
{
SLOGI("Received GetCurrentItem request");
// do not place streamPlayerLock_ in side of curItemLock_
std::lock_guard lockGuard(curItemLock_);
return currentAVQueueItem_;
}
AVQueueItem HwCastStreamPlayer::RefreshCurrentItemDuration()
{
SLOGD("RefreshCurrentItemDuration in");
int32_t duration = 0;
GetDuration(duration);
// do not place streamPlayerLock_ in side of curItemLock_
std::lock_guard lockGuard(curItemLock_);
std::shared_ptr<AVMediaDescription> mediaDes = currentAVQueueItem_.GetDescription();
CHECK_AND_RETURN_RET_LOG(mediaDes != nullptr, currentAVQueueItem_, "AVMediaDescription get null!");
mediaDes->SetDuration(duration);
currentAVQueueItem_.SetDescription(mediaDes);
SLOGI("refresh duration:%{public}d", duration);
return currentAVQueueItem_;
}
int32_t HwCastStreamPlayer::RefreshCurrentAVQueueItem(const AVQueueItem& avQueueItem)
{
std::lock_guard lockGuard(curItemLock_);
currentAVQueueItem_ = avQueueItem;
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::Start(const AVQueueItem& avQueueItem)
{
std::shared_ptr<AVMediaDescription> mediaDescription = avQueueItem.GetDescription();
CHECK_AND_RETURN_RET_LOG(mediaDescription != nullptr, AVSESSION_ERROR, "mediaDescription is nullptr");
CastEngine::MediaInfo mediaInfo;
buildCastInfo(mediaDescription, mediaInfo);
std::lock_guard lockGuard(streamPlayerLock_);
if (!streamPlayer_) {
SLOGE("Set media info and start failed");
return AVSESSION_ERROR;
}
std::shared_ptr<AVMediaDescription> originMediaDescription = nullptr;
{
std::lock_guard lockGuard(curItemLock_);
originMediaDescription = currentAVQueueItem_.GetDescription();
}
if (originMediaDescription && originMediaDescription->GetMediaUri() != "http:" &&
originMediaDescription->GetMediaId() == mediaInfo.mediaId) {
CHECK_AND_RETURN_RET_LOG(streamPlayer_->Play() == AVSESSION_SUCCESS, AVSESSION_ERROR, "Set play failed");
} else if (streamPlayer_->Play(mediaInfo) != AVSESSION_SUCCESS) {
SLOGE("Set media info and start failed");
return AVSESSION_ERROR;
}
RefreshCurrentAVQueueItem(avQueueItem);
SLOGI("Set media info and start successfully");
return AVSESSION_SUCCESS;
}
bool HwCastStreamPlayer::RepeatPrepare(std::shared_ptr<AVMediaDescription>& mediaDescription)
{
bool hasIcon = false;
{
std::lock_guard lockGuard(curItemLock_);
if (mediaDescription != nullptr && currentAVQueueItem_.GetDescription() != nullptr &&
mediaDescription->GetIconUri() == "URI_CACHE" && mediaDescription->GetIcon() != nullptr) {
currentAVQueueItem_.GetDescription()->SetIcon(mediaDescription->GetIcon());
SLOGI("Repeat Prepare only setIcon");
hasIcon = true;
}
}
{
std::lock_guard<std::recursive_mutex> lockGuard(sessionCallbackLock_);
if (hasIcon && sessionCallbackForCastNtf_ && isPlayingState_) {
sessionCallbackForCastNtf_(true, true);
}
}
return hasIcon;
}
int32_t HwCastStreamPlayer::Prepare(const AVQueueItem& avQueueItem)
{
std::shared_ptr<AVMediaDescription> mediaDescription = avQueueItem.GetDescription();
if (RepeatPrepare(mediaDescription)) {
return AVSESSION_SUCCESS;
}
SLOGI("do Prepare with mediaId %{public}s | title %{public}s",
mediaDescription->GetMediaId().c_str(), AVSessionUtils::GetAnonyTitle(mediaDescription->GetTitle()).c_str());
CastEngine::MediaInfo mediaInfo;
buildCastInfo(mediaDescription, mediaInfo);
std::lock_guard lockGuard(streamPlayerLock_);
SLOGI("pass playerlock, check item lock, mediaInfo mediaUrl and albumCoverUrl");
if (streamPlayer_ && streamPlayer_->Load(mediaInfo) == AVSESSION_SUCCESS) {
std::lock_guard lockGuard(curItemLock_);
SLOGI("Set media info and prepare with curItemLock successed");
currentAVQueueItem_ = avQueueItem;
return AVSESSION_SUCCESS;
}
SLOGE("Set media info and prepare failed");
return AVSESSION_ERROR;
}
void HwCastStreamPlayer::buildCastInfo(std::shared_ptr<AVMediaDescription>& mediaDescription,
CastEngine::MediaInfo& mediaInfo)
{
mediaInfo.mediaId = mediaDescription->GetMediaId();
mediaInfo.mediaName = mediaDescription->GetTitle();
mediaInfo.mediaUrl = mediaDescription->GetMediaUri();
if (mediaDescription->GetMediaUri() == "") {
if (mediaDescription->GetFdSrc().fd_ <= 0) {
SLOGW("No media id and fd src");
mediaInfo.mediaUrl = "http:";
mediaDescription->SetMediaUri("http:");
} else {
mediaInfo.mediaUrl = std::to_string(mediaDescription->GetFdSrc().fd_);
}
}
mediaInfo.mediaType = mediaDescription->GetMediaType();
mediaInfo.mediaSize = static_cast<uint32_t>(mediaDescription->GetMediaSize());
mediaInfo.startPosition = static_cast<uint32_t>(mediaDescription->GetStartPosition());
int32_t mediaDuration = mediaDescription->GetDuration();
mediaInfo.duration = static_cast<uint32_t>(mediaDuration < 0 ? 0 : mediaDuration);
SLOGI("mediaDescription duration is %{public}d startPosition is %{public}d",
mediaInfo.duration, mediaInfo.startPosition);
mediaInfo.closingCreditsPosition =
static_cast<uint32_t>(std::max(mediaDescription->GetCreditsPosition(), 0));
mediaInfo.albumCoverUrl = mediaDescription->GetIconUri() == "" ?
mediaDescription->GetAlbumCoverUri() : mediaDescription->GetIconUri();
mediaInfo.albumTitle = mediaDescription->GetAlbumTitle();
mediaInfo.mediaArtist = mediaDescription->GetArtist();
mediaInfo.lrcUrl = mediaDescription->GetLyricUri();
mediaInfo.lrcContent = mediaDescription->GetLyricContent();
mediaInfo.appIconUrl = mediaDescription->GetIconUri();
mediaInfo.appName = mediaDescription->GetAppName();
mediaInfo.drmType = mediaDescription->GetDrmScheme();
if (spid_ > 0 && mediaDescription->GetLaunchClientData().length() > 0) {
mediaInfo.launchClientData = mediaDescription->GetLaunchClientData();
mediaInfo.spid = spid_;
}
AVDataSrcDescriptor dataSrc = mediaDescription->GetDataSrc();
SLOGI("has dataSrc hasCallback %{public}d", dataSrc.hasCallback);
if (dataSrc.hasCallback) {
if (castDataSrc_ == nullptr) {
castDataSrc_ = std::make_shared<AVSession::HwCastDataSourceDescriptor>();
}
castDataSrc_->SetCallback(dataSrc.callback_);
castDataSrc_->SetSize(dataSrc.fileSize);
mediaInfo.mediaUrl = "/file";
mediaInfo.dataSrc = castDataSrc_;
}
buildCastExtraInfo(mediaDescription, mediaInfo);
}
void HwCastStreamPlayer::buildCastExtraInfo(std::shared_ptr<AVMediaDescription>& mediaDescription,
CastEngine::MediaInfo& mediaInfo)
{
if (mediaDescription->GetPcmSrc() && mediaDescription->GetCastInfo() != nullptr) {
uid_t appUid = mediaDescription->GetCastInfo()->GetAppUid();
SLOGI("buildCastInfo AUDIO_PCM uid %{public}d", appUid);
mediaInfo.appUid = appUid;
mediaInfo.mediaType = "AUDIO_PCM";
}
if (mediaDescription->GetIcon() != nullptr) {
SLOGI("buildCastExtraInfo has albumPixelMap");
mediaInfo.albumPixelMap = AVSessionPixelMapAdapter::ConvertFromInner(mediaDescription->GetIcon(), false);
}
auto extras = mediaDescription->GetExtras();
CHECK_AND_RETURN_LOG(extras != nullptr, "extras is null");
mediaInfo.extrasData = GetDlnaExtrasFromWantParams(extras);
}
std::string HwCastStreamPlayer::GetDlnaExtrasFromWantParams(
const std::shared_ptr<AAFwk::WantParams>& extras)
{
CHECK_AND_RETURN_RET_LOG(extras != nullptr, "", "extras is null");
auto getExtraStr = [&extras](const std::string& key) -> std::string {
auto value = extras->GetParam(key);
CHECK_AND_RETURN_RET_LOG(value != nullptr, "", "%{public}s value is null", key.c_str());
auto* extraValue = AAFwk::IString::Query(value);
CHECK_AND_RETURN_RET_LOG(extraValue != nullptr, "", "%{public}s is not string type", key.c_str());
auto extraStr = AAFwk::String::Unbox(extraValue);
SLOGI("GetDlnaExtrasFromWantParams: %{public}s length=%{public}zu", key.c_str(), extraStr.length());
return extraStr;
};
auto didlStr = getExtraStr(ExtraKeyEvent::DIDL_LITE);
auto metadataStr = getExtraStr(ExtraKeyEvent::CURRENT_URI_METADATA);
CHECK_AND_RETURN_RET_LOG(didlStr.length() + metadataStr.length() < DLNA_EXTRAS_MAX_LENGTH, "",
"GetDlnaExtrasFromWantParams total length exceeded max");
cJSON* extrasObj = cJSON_CreateObject();
CHECK_AND_RETURN_RET_LOG(extrasObj != nullptr, "", "Failed to create cJSON object");
cJSON_AddStringToObject(extrasObj, ExtraKeyEvent::DIDL_LITE, didlStr.c_str());
cJSON_AddStringToObject(extrasObj, ExtraKeyEvent::CURRENT_URI_METADATA, metadataStr.c_str());
char* jsonStr = cJSON_PrintUnformatted(extrasObj);
std::string result = (jsonStr != nullptr) ? jsonStr : "";
cJSON_free(jsonStr);
cJSON_Delete(extrasObj);
return result;
}
int32_t HwCastStreamPlayer::GetDuration(int32_t& duration)
{
SLOGI("GetDuration begin");
std::lock_guard lockGuard(streamPlayerLock_);
if (!streamPlayer_) {
SLOGE("streamPlayer is nullptr");
return AVSESSION_ERROR;
}
streamPlayer_->GetDuration(duration);
SLOGI("GetDuration successed");
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::GetCastAVPlaybackState(AVPlaybackState& avPlaybackState)
{
SLOGI("GetCastAVPlaybackState begin");
std::lock_guard lockGuard(streamPlayerLock_);
if (!streamPlayer_) {
SLOGE("streamPlayer is nullptr");
return AVSESSION_ERROR;
}
CastEngine::PlayerStates castPlayerStates;
streamPlayer_->GetPlayerStatus(castPlayerStates);
if (castPlusStateToString_.count(castPlayerStates) != 0) {
avPlaybackState.SetState(castPlusStateToString_[castPlayerStates]);
}
CastEngine::PlaybackSpeed castPlaybackSpeed;
streamPlayer_->GetPlaySpeed(castPlaybackSpeed);
if (castPlusSpeedToDouble_.count(castPlaybackSpeed) != 0) {
avPlaybackState.SetSpeed(castPlusSpeedToDouble_[castPlaybackSpeed]);
}
int castPosition = 0;
streamPlayer_->GetPosition(castPosition);
AVPlaybackState::Position position;
position.elapsedTime_ = static_cast<int64_t>(castPosition);
avPlaybackState.SetPosition(position);
CastEngine::LoopMode castLoopMode;
streamPlayer_->GetLoopMode(castLoopMode);
if (castPlusLoopModeToInt_.count(castLoopMode) != 0) {
avPlaybackState.SetLoopMode(castPlusLoopModeToInt_[castLoopMode]);
}
int32_t castVolume = 0;
int32_t maxCastVolume = 0;
streamPlayer_->GetVolume(castVolume, maxCastVolume);
avPlaybackState.SetVolume(castVolume);
std::shared_ptr<AAFwk::WantParams> wantParams = std::make_shared<AAFwk::WantParams>();
sptr<AAFwk::IInterface> intIt = AAFwk::Integer::Box(maxCastVolume);
if (wantParams == nullptr || intIt == nullptr) {
return AVSESSION_ERROR;
}
wantParams->SetParam("maxCastVolume", intIt);
avPlaybackState.SetExtras(wantParams);
SLOGI("GetCastAVPlaybackState successed with state: %{public}d", avPlaybackState.GetState());
return AVSESSION_SUCCESS;
}
void HwCastStreamPlayer::GetMediaDecodeOfVideoFromCJSON(cJSON* videoValue)
{
CHECK_AND_RETURN_LOG(videoValue != nullptr && !cJSON_IsInvalid(videoValue), "videoValue get invalid");
if (cJSON_HasObjectItem(videoValue, decodeSupportResolutionStr_.c_str())) {
cJSON* resolutionItem = cJSON_GetObjectItem(videoValue, decodeSupportResolutionStr_.c_str());
CHECK_AND_RETURN_LOG(resolutionItem != nullptr && !cJSON_IsInvalid(resolutionItem), "resolution get invalid");
std::vector<ResolutionLevel> resolutionLevels;
std::map<std::string, std::vector<ResolutionLevel>> decodeToResolution;
int num;
if (cJSON_HasObjectItem(resolutionItem, decodeOfVideoHevcStr_.c_str())) {
cJSON* decodeOfVideoHevcArray = cJSON_GetObjectItem(resolutionItem, decodeOfVideoHevcStr_.c_str());
CHECK_AND_RETURN_LOG(decodeOfVideoHevcArray != nullptr && !cJSON_IsInvalid(decodeOfVideoHevcArray) &&
cJSON_IsArray(decodeOfVideoHevcArray), "decodeOfVideoHevc get invalid");
cJSON* valueItem = nullptr;
cJSON_ArrayForEach(valueItem, decodeOfVideoHevcArray) {
CHECK_AND_CONTINUE(valueItem != nullptr && !cJSON_IsInvalid(valueItem) && cJSON_IsNumber(valueItem));
num = valueItem->valueint;
SLOGI("decodeSupportResolution's video/hevc is %{public}d", num);
resolutionLevels.emplace_back(static_cast<ResolutionLevel>(num));
}
decodeToResolution[decodeOfVideoHevcStr_] = resolutionLevels;
}
resolutionLevels.clear();
if (cJSON_HasObjectItem(resolutionItem, decodeOfVideoAvcStr_.c_str())) {
cJSON* decodeOfVideoAvcArray = cJSON_GetObjectItem(resolutionItem, decodeOfVideoAvcStr_.c_str());
CHECK_AND_RETURN_LOG(decodeOfVideoAvcArray != nullptr && !cJSON_IsInvalid(decodeOfVideoAvcArray) &&
cJSON_IsArray(decodeOfVideoAvcArray), "decodeOfVideoAvc get invalid");
cJSON* valueItem = nullptr;
cJSON_ArrayForEach(valueItem, decodeOfVideoAvcArray) {
CHECK_AND_CONTINUE(valueItem != nullptr && !cJSON_IsInvalid(valueItem) && cJSON_IsNumber(valueItem));
num = valueItem->valueint;
SLOGI("decodeSupportResolution's video/avc is %{public}d", num);
resolutionLevels.emplace_back(static_cast<ResolutionLevel>(num));
}
jsonCapabilitiesSptr_->decoderSupportResolutions_ = decodeToResolution;
}
} else {
SLOGI("%{public}s of %{public}s no contains", videoStr_.c_str(), decodeSupportResolutionStr_.c_str());
}
}
void HwCastStreamPlayer::GetMediaCapabilitiesOfVideo(cJSON* videoValue)
{
CHECK_AND_RETURN_LOG(videoValue != nullptr && !cJSON_IsInvalid(videoValue), "videoValue get invalid");
if (cJSON_HasObjectItem(videoValue, decodeTypeStr_.c_str())) {
cJSON* decodeTypeArray = cJSON_GetObjectItem(videoValue, decodeTypeStr_.c_str());
CHECK_AND_RETURN_LOG(decodeTypeArray != nullptr && !cJSON_IsInvalid(decodeTypeArray) &&
cJSON_IsArray(decodeTypeArray), "decodeType get invalid");
cJSON* decodeTypeItem = nullptr;
cJSON_ArrayForEach(decodeTypeItem, decodeTypeArray) {
CHECK_AND_CONTINUE(decodeTypeItem != nullptr && !cJSON_IsInvalid(decodeTypeItem) &&
cJSON_IsString(decodeTypeItem));
std::string str(decodeTypeItem->valuestring);
SLOGI("get %{public}s is %{public}s", decodeTypeStr_.c_str(), str.c_str());
jsonCapabilitiesSptr_->decoderTypes_.emplace_back(str);
}
}
GetMediaDecodeOfVideoFromCJSON(videoValue);
if (cJSON_HasObjectItem(videoValue, hdrFormatStr_.c_str())) {
cJSON* hdrFormatArray = cJSON_GetObjectItem(videoValue, hdrFormatStr_.c_str());
CHECK_AND_RETURN_LOG(hdrFormatArray != nullptr && !cJSON_IsInvalid(hdrFormatArray) &&
cJSON_IsArray(hdrFormatArray), "hdrFormat get invalid");
cJSON* hdrFormatItem = nullptr;
cJSON_ArrayForEach(hdrFormatItem, hdrFormatArray) {
CHECK_AND_CONTINUE(hdrFormatItem != nullptr && !cJSON_IsInvalid(hdrFormatItem) &&
cJSON_IsNumber(hdrFormatItem));
int num = hdrFormatItem->valueint;
SLOGI("get %{public}s is %{public}d", hdrFormatStr_.c_str(), num);
jsonCapabilitiesSptr_->hdrFormats_.emplace_back(static_cast<HDRFormat>(num));
}
} else {
SLOGI("%{public}s of %{public}s no contains", videoStr_.c_str(), hdrFormatStr_.c_str());
}
}
void HwCastStreamPlayer::GetMediaCapabilitiesOfAudio(cJSON* audioValue)
{
CHECK_AND_RETURN_LOG(audioValue != nullptr && !cJSON_IsInvalid(audioValue), "audioValue get invalid");
if (cJSON_HasObjectItem(audioValue, decodeTypeStr_.c_str())) {
cJSON* decodeTypeItem = cJSON_GetObjectItem(audioValue, decodeTypeStr_.c_str());
CHECK_AND_RETURN_LOG(decodeTypeItem != nullptr && !cJSON_IsInvalid(decodeTypeItem) &&
cJSON_IsString(decodeTypeItem), "decodeType str get invalid");
std::string str(decodeTypeItem->valuestring);
SLOGI("%{public}s of %{public}s", decodeTypeStr_.c_str(), str.c_str());
jsonCapabilitiesSptr_->decoderTypes_.emplace_back(str);
}
}
void HwCastStreamPlayer::ClearJsonCapabilities()
{
SLOGI("enter ClearJsonCapabilities");
jsonCapabilitiesSptr_->decoderTypes_.clear();
jsonCapabilitiesSptr_->hdrFormats_.clear();
jsonCapabilitiesSptr_->playSpeeds_.clear();
jsonCapabilitiesSptr_->decoderSupportResolutions_.clear();
}
int32_t HwCastStreamPlayer::GetMediaCapabilities()
{
SLOGI("GetMediaCapabilities begin");
std::lock_guard lockGuard(streamPlayerLock_);
CHECK_AND_RETURN_RET_LOG(streamPlayer_, AVSESSION_ERROR, "streamPlayer_ is nullptr");
CHECK_AND_RETURN_RET_LOG(jsonCapabilitiesSptr_, AVSESSION_ERROR, "jsonCapabilitiesSptr_ is nullptr");
std::string supportCapabilities;
ClearJsonCapabilities();
streamPlayer_->GetMediaCapabilities(supportCapabilities);
cJSON* valueItem = cJSON_Parse(supportCapabilities.c_str());
CHECK_AND_RETURN_RET_LOG(valueItem != nullptr, AVSESSION_ERROR, "supportCapabilities is nullptr");
if (cJSON_IsInvalid(valueItem)) {
SLOGE("supportCapabilities is invalid");
cJSON_Delete(valueItem);
return AVSESSION_ERROR;
}
if (cJSON_HasObjectItem(valueItem, videoStr_.c_str())) {
cJSON* videoItem = cJSON_GetObjectItem(valueItem, videoStr_.c_str());
GetMediaCapabilitiesOfVideo(videoItem);
} else if (cJSON_HasObjectItem(valueItem, audioStr_.c_str())) {
cJSON* audioItem = cJSON_GetObjectItem(valueItem, audioStr_.c_str());
GetMediaCapabilitiesOfAudio(audioItem);
}
if (cJSON_HasObjectItem(valueItem, speedStr_.c_str())) {
cJSON* speedArray = cJSON_GetObjectItem(valueItem, speedStr_.c_str());
if (speedArray == nullptr || cJSON_IsInvalid(speedArray) || !cJSON_IsArray(speedArray)) {
SLOGE("speed get null or invalid");
cJSON_Delete(valueItem);
return AVSESSION_ERROR;
}
cJSON* speedItem = nullptr;
cJSON_ArrayForEach(speedItem, speedArray) {
CHECK_AND_CONTINUE(speedItem != nullptr && !cJSON_IsInvalid(speedItem) &&
cJSON_IsNumber(speedItem));
CastEngine::PlaybackSpeed num = static_cast<CastEngine::PlaybackSpeed>(speedItem->valueint);
SLOGI("support play speed is %{public}f", castPlusSpeedToDouble_[num]);
jsonCapabilitiesSptr_->playSpeeds_.emplace_back(castPlusSpeedToDouble_[num]);
}
}
cJSON_Delete(valueItem);
SLOGI("GetMediaCapabilities success");
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::GetSupportedDecoders(std::vector<std::string>& decoderTypes)
{
SLOGI("enter GetSupportedDecoders");
std::lock_guard lockGuard(streamPlayerLock_);
CHECK_AND_RETURN_RET_LOG(jsonCapabilitiesSptr_, AVSESSION_ERROR, "jsonCapabilitiesSptr_ is nullptr");
if (jsonCapabilitiesSptr_->decoderTypes_.empty()) {
GetMediaCapabilities();
}
decoderTypes = jsonCapabilitiesSptr_->decoderTypes_;
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::GetRecommendedResolutionLevel(std::string& decoderType, ResolutionLevel& resolutionLevel)
{
SLOGI("enter GetRecommendedResolutionLevel and decoderType is %{public}s", decoderType.c_str());
std::lock_guard lockGuard(streamPlayerLock_);
CHECK_AND_RETURN_RET_LOG(jsonCapabilitiesSptr_, AVSESSION_ERROR, "jsonCapabilitiesSptr_ is nullptr");
if (jsonCapabilitiesSptr_->decoderSupportResolutions_.empty()) {
GetMediaCapabilities();
}
auto it = jsonCapabilitiesSptr_->decoderSupportResolutions_.find(decoderType);
if (it != jsonCapabilitiesSptr_->decoderSupportResolutions_.end()) {
std::vector<ResolutionLevel> resolutionLevels = jsonCapabilitiesSptr_->decoderSupportResolutions_[decoderType];
CHECK_AND_RETURN_RET_LOG(!resolutionLevels.empty(), AVSESSION_ERROR, "resolutionLevels is empty");
auto maxResolutionLevel = *std::max_element(resolutionLevels.begin(), resolutionLevels.end());
SLOGI("find %{public}s map to %{public}d", decoderType.c_str(), maxResolutionLevel);
resolutionLevel = static_cast<ResolutionLevel>(maxResolutionLevel);
} else {
SLOGI("no find %{public}s map to resolutionLevel", decoderType.c_str());
return AVSESSION_ERROR;
}
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::GetSupportedHdrCapabilities(std::vector<HDRFormat>& hdrFormats)
{
SLOGI("enter GetSupportedHdrCapabilities");
std::lock_guard lockGuard(streamPlayerLock_);
CHECK_AND_RETURN_RET_LOG(jsonCapabilitiesSptr_, AVSESSION_ERROR, "jsonCapabilitiesSptr_ is nullptr");
if (jsonCapabilitiesSptr_->hdrFormats_.empty()) {
GetMediaCapabilities();
}
hdrFormats = jsonCapabilitiesSptr_->hdrFormats_;
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::GetSupportedPlaySpeeds(std::vector<float>& playSpeeds)
{
SLOGI("enter GetSupportedPlaySpeeds");
std::lock_guard lockGuard(streamPlayerLock_);
CHECK_AND_RETURN_RET_LOG(jsonCapabilitiesSptr_, AVSESSION_ERROR, "jsonCapabilitiesSptr_ is nullptr");
if (jsonCapabilitiesSptr_->playSpeeds_.empty()) {
GetMediaCapabilities();
}
playSpeeds = jsonCapabilitiesSptr_->playSpeeds_;
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::SetDisplaySurface(std::string &surfaceId)
{
SLOGI("SetDisplaySurface begin");
std::lock_guard lockGuard(streamPlayerLock_);
if (!streamPlayer_) {
SLOGE("streamPlayer is nullptr");
return AVSESSION_ERROR;
}
streamPlayer_->SetSurface(surfaceId);
SLOGI("SetDisplaySurface successed");
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::ProcessMediaKeyResponse(const std::string& assetId, const std::vector<uint8_t>& response)
{
SLOGI("ProcessMediaKeyResponse begin");
std::lock_guard lockGuard(streamPlayerLock_);
if (!streamPlayer_) {
SLOGE("streamPlayer is nullptr");
return AVSESSION_ERROR;
}
streamPlayer_->ProvideKeyResponse(assetId, response);
SLOGI("ProcessMediaKeyResponse successed");
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::RegisterControllerListener(std::shared_ptr<IAVCastControllerProxyListener> listener)
{
SLOGI("RegisterControllerListener begin");
if (listener == nullptr) {
SLOGE("RegisterControllerListener failed for the listener is nullptr");
return AVSESSION_ERROR;
}
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
if (find(streamPlayerListenerList_.begin(), streamPlayerListenerList_.end(), listener)
!= streamPlayerListenerList_.end()) {
SLOGE("listener is already in streamPlayerListenerList_");
return AVSESSION_ERROR;
}
SLOGI("RegisterControllerListener successed, and add it to streamPlayerListenerList_");
streamPlayerListenerList_.emplace_back(listener);
SLOGI("RegisterControllerListener done with size %{public}d", static_cast<int>(streamPlayerListenerList_.size()));
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::UnRegisterControllerListener(std::shared_ptr<IAVCastControllerProxyListener> listener)
{
if (listener == nullptr) {
SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr");
return AVSESSION_ERROR;
}
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto iter = streamPlayerListenerList_.begin(); iter != streamPlayerListenerList_.end();) {
if (*iter == listener) {
streamPlayerListenerList_.erase(iter);
SLOGI("UnRegisterControllerListener successed, and erase it from streamPlayerListenerList_");
return AVSESSION_SUCCESS;
} else {
++iter;
}
}
SLOGE("listener is not found in streamPlayerListenerList_, so UnRegisterControllerListener failed");
return AVSESSION_ERROR;
}
int32_t HwCastStreamPlayer::GetValidAbility(std::vector<int32_t>& validCmdList)
{
SLOGI("GetValidAbility in");
if (streamPlayer_ == nullptr) {
SLOGE("streamPlayer is nullptr");
return AVSESSION_ERROR;
}
CastEngine::StreamCapability streamCapability;
streamPlayer_->GetAvailableCapability(streamCapability);
checkCmdsFromAbility(streamCapability, validCmdList);
return AVSESSION_SUCCESS;
}
int32_t HwCastStreamPlayer::SetValidAbility(const std::vector<int32_t>& validCmdList)
{
SLOGI("SetValidAbility begin");
if (streamPlayer_ == nullptr) {
SLOGE("streamPlayer is nullptr");
return AVSESSION_ERROR;
}
CastEngine::StreamCapability streamCapability;
checkAbilityFromCmds(validCmdList, streamCapability);
streamPlayer_->SetAvailableCapability(streamCapability);
return AVSESSION_SUCCESS;
}
void HwCastStreamPlayer::SetSessionCallbackForCastCap(const std::function<void(bool, bool)>& callback)
{
std::lock_guard<std::recursive_mutex> lockGuard(sessionCallbackLock_);
sessionCallbackForCastNtf_ = callback;
}
void HwCastStreamPlayer::CheckIfCancelCastCapsule()
{
isPlayingState_ = false;
AVSessionEventHandler::GetInstance().AVSessionRemoveTask("CancelCastCapsule");
std::weak_ptr<HwCastStreamPlayer> weakSelf = shared_from_this();
AVSessionEventHandler::GetInstance().AVSessionPostTask(
[weakSelf]() {
auto shardPtr = weakSelf.lock();
CHECK_AND_RETURN_LOG(shardPtr != nullptr, "CheckIfCancelCastCapsule player is null");
std::lock_guard<std::recursive_mutex> lockGuard(shardPtr->sessionCallbackLock_);
CHECK_AND_RETURN_LOG(shardPtr->sessionCallbackForCastNtf_ && !shardPtr->isPlayingState_,
"CheckIfCancelCastCapsule return");
SLOGI("MediaCapsule delCastCapsule isPlayingState_ %{public}d", shardPtr->isPlayingState_);
shardPtr->sessionCallbackForCastNtf_(false, false);
}, "CancelCastCapsule", cancelTimeout);
}
void HwCastStreamPlayer::OnStateChanged(const CastEngine::PlayerStates playbackState, bool isPlayWhenReady)
{
AVPlaybackState avCastPlaybackState;
if (castPlusStateToString_.count(playbackState) == 0) {
SLOGE("current playbackState status is not exist in castPlusStateToString_");
avCastPlaybackState.SetState(AVPlaybackState::PLAYBACK_STATE_ERROR);
} else {
SLOGD("On state changed, get state %{public}d", castPlusStateToString_[playbackState]);
avCastPlaybackState.SetState(castPlusStateToString_[playbackState]);
}
if (avCastPlaybackState.GetState() == AVPlaybackState::PLAYBACK_STATE_PLAY) {
// play state try notify cast notification
isPlayingState_ = true;
std::lock_guard<std::recursive_mutex> lockGuard(sessionCallbackLock_);
if (sessionCallbackForCastNtf_) {
SLOGI("MediaCapsule addCastCapsule");
sessionCallbackForCastNtf_(true, false);
}
} else {
CheckIfCancelCastCapsule();
}
RefreshCurrentItemDuration();
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnCastPlaybackStateChange for registered listeners");
listener->OnCastPlaybackStateChange(avCastPlaybackState);
}
}
SLOGI("onCastStateChange with duration");
}
void HwCastStreamPlayer::OnPositionChanged(int position, int bufferPosition, int duration)
{
if (position == -1 && bufferPosition == -1 && duration == -1) { // -1 is invalid(default) value
SLOGW("Invalid position change callback");
return;
}
AVPlaybackState avCastPlaybackState;
if (position != -1) { // -1 is invalid position
AVPlaybackState::Position castPosition;
castPosition.elapsedTime_ = position;
avCastPlaybackState.SetPosition(castPosition);
SLOGD("Received elapsedTime: %{public}d", position);
}
if (bufferPosition != -1) { // -1 is invalid buffer position
avCastPlaybackState.SetBufferedTime(bufferPosition);
SLOGD("Received bufferPosition: %{public}d", bufferPosition);
}
if (duration != -1) {
std::shared_ptr<AAFwk::WantParams> wantParams = std::make_shared<AAFwk::WantParams>();
sptr<AAFwk::IInterface> intIt = AAFwk::Integer::Box(duration);
wantParams->SetParam("duration", intIt);
avCastPlaybackState.SetExtras(wantParams);
SLOGD("Received duration: %{public}d", duration);
}
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGD("trigger the OnPositionChange");
listener->OnCastPlaybackStateChange(avCastPlaybackState);
}
}
SLOGI("on cast position change done");
}
void HwCastStreamPlayer::OnMediaItemChanged(const CastEngine::MediaInfo& mediaInfo)
{
SLOGD("Stream player received mediaItemChanged event");
std::shared_ptr<AVMediaDescription> mediaDescription = std::make_shared<AVMediaDescription>();
mediaDescription->SetMediaId(mediaInfo.mediaId);
mediaDescription->SetTitle(mediaInfo.mediaName);
mediaDescription->SetMediaUri(mediaInfo.mediaUrl);
mediaDescription->SetMediaType(mediaInfo.mediaType);
mediaDescription->SetMediaSize(mediaInfo.mediaSize);
mediaDescription->SetStartPosition(static_cast<uint32_t>(mediaInfo.startPosition));
mediaDescription->SetDuration(static_cast<uint32_t>(mediaInfo.duration));
mediaDescription->SetCreditsPosition(static_cast<int32_t>(mediaInfo.closingCreditsPosition));
mediaDescription->SetAlbumCoverUri(mediaInfo.albumCoverUrl);
mediaDescription->SetAlbumTitle(mediaInfo.albumTitle);
mediaDescription->SetArtist(mediaInfo.mediaArtist);
mediaDescription->SetLyricUri(mediaInfo.lrcUrl);
mediaDescription->SetLyricContent(mediaInfo.lrcContent);
mediaDescription->SetIconUri(mediaInfo.appIconUrl);
mediaDescription->SetAppName(mediaInfo.appName);
mediaDescription->SetDrmScheme(mediaInfo.drmType);
std::shared_ptr<AVMediaDescription> originMediaDescription = nullptr;
{
std::lock_guard lockGuard(curItemLock_);
originMediaDescription = currentAVQueueItem_.GetDescription();
}
if (originMediaDescription != nullptr && originMediaDescription->GetIcon() != nullptr
&& mediaInfo.mediaId == originMediaDescription->GetMediaId()) {
SLOGI("cacheMedia:%{public}s", originMediaDescription->GetMediaId().c_str());
mediaDescription->SetIcon(originMediaDescription->GetIcon());
}
if (mediaInfo.albumPixelMap != nullptr) {
SLOGI("OnMediaItemChanged has albumPixelMap");
mediaDescription->SetIcon(AVSessionPixelMapAdapter::ConvertToInnerWithLimitedSize(mediaInfo.albumPixelMap));
}
AVQueueItem queueItem;
queueItem.SetDescription(mediaDescription);
{
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnMediaItemChange for registered listeners");
listener->OnMediaItemChange(queueItem);
}
}
}
{
std::lock_guard lockGuard(curItemLock_);
currentAVQueueItem_ = queueItem;
}
SLOGI("StreamPlayer received mediaItemChanged event done");
}
void HwCastStreamPlayer::OnNextRequest()
{
SLOGD("StreamPlayer received next request");
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnPlayNext for registered listeners");
listener->OnPlayNext();
}
}
SLOGI("StreamPlayer received next request done");
}
void HwCastStreamPlayer::OnPreviousRequest()
{
SLOGD("StreamPlayer received previous request");
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnPlayPrevious for registered listeners");
listener->OnPlayPrevious();
}
}
SLOGI("StreamPlayer received previous request done");
}
void HwCastStreamPlayer::OnVolumeChanged(int volume, int maxVolume)
{
SLOGD("StreamPlayer received volume changed event: %{public}d", volume);
AVPlaybackState avCastPlaybackState;
avCastPlaybackState.SetVolume(volume);
std::shared_ptr<AAFwk::WantParams> wantParams = std::make_shared<AAFwk::WantParams>();
sptr<AAFwk::IInterface> intIt = AAFwk::Integer::Box(maxVolume);
if (wantParams == nullptr || intIt == nullptr) {
return;
}
wantParams->SetParam("maxCastVolume", intIt);
avCastPlaybackState.SetExtras(wantParams);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnVolumeChanged for registered listeners");
listener->OnCastPlaybackStateChange(avCastPlaybackState);
}
}
SLOGI("StreamPlayer received volume changed event done: %{public}d", volume);
}
void HwCastStreamPlayer::OnLoopModeChanged(const CastEngine::LoopMode loopMode)
{
AVPlaybackState avCastPlaybackState;
if (castPlusLoopModeToInt_.count(loopMode) == 0) {
SLOGE("current playbackState status is not exist in castPlusStateToString_");
} else {
SLOGD("StreamPlayer received loop mode changed event: %{public}d", castPlusLoopModeToInt_[loopMode]);
avCastPlaybackState.SetLoopMode(castPlusLoopModeToInt_[loopMode]);
}
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnLoopModeChanged for registered listeners");
listener->OnCastPlaybackStateChange(avCastPlaybackState);
}
}
SLOGI("loop mode changed event done: %{public}d", castPlusLoopModeToInt_[loopMode]);
}
void HwCastStreamPlayer::OnPlaySpeedChanged(const CastEngine::PlaybackSpeed speed)
{
AVPlaybackState avCastPlaybackState;
if (castPlusSpeedToDouble_.count(speed) == 0) {
SLOGE("current speed is not exist in castPlusSpeedToDouble_");
return;
}
SLOGD("StreamPlayer received play speed changed event: %{public}f", castPlusSpeedToDouble_[speed]);
avCastPlaybackState.SetSpeed(castPlusSpeedToDouble_[speed]);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnPlaySpeedChanged for registered listeners");
listener->OnCastPlaybackStateChange(avCastPlaybackState);
}
}
SLOGI("play speed changed event done: %{public}f", castPlusSpeedToDouble_[speed]);
}
void HwCastStreamPlayer::OnPlayerError(int errorCode, const std::string &errorMsg)
{
SLOGD("StreamPlayer received error event, code: %{public}d, message: %{public}s", errorCode, errorMsg.c_str());
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnPlayerError for registered listeners");
listener->OnPlayerError(errorCode, errorMsg);
}
}
SLOGI("error event done, code: %{public}d, message: %{public}s", errorCode, errorMsg.c_str());
}
void HwCastStreamPlayer::OnSeekDone(int32_t seekNumber)
{
SLOGD("StreamPlayer received seek done event: %{public}d", seekNumber);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnSeekDone for registered listeners");
listener->OnSeekDone(seekNumber);
}
}
SLOGI("StreamPlayer received seek done event done with: %{public}d", seekNumber);
}
void HwCastStreamPlayer::OnVideoSizeChanged(int width, int height)
{
SLOGD("StreamPlayer received video size change event, width: %{public}d, height: %{public}d", width, height);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnVideoSizeChange for registered listeners");
listener->OnVideoSizeChange(width, height);
}
}
SLOGI("video size change event done, width: %{public}d, height: %{public}d", width, height);
}
void HwCastStreamPlayer::OnEndOfStream(int isLooping)
{
SLOGD("Received EndOfStream callback, value is %{public}d", isLooping);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnEndOfStream for registered listeners");
listener->OnEndOfStream(isLooping);
}
}
AVPlaybackState avCastPlaybackState;
std::shared_ptr<AAFwk::WantParams> wantParams = std::make_shared<AAFwk::WantParams>();
sptr<AAFwk::IInterface> intIt = AAFwk::Integer::Box(isLooping);
if (wantParams == nullptr || intIt == nullptr) {
return;
}
wantParams->SetParam("endofstream", intIt);
avCastPlaybackState.SetExtras(wantParams);
SLOGD("Received end of stream event: %{public}d", isLooping);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnEndOfStream for registered listeners");
listener->OnCastPlaybackStateChange(avCastPlaybackState);
}
}
SLOGI("Received EndOfStream callback done, value is %{public}d", isLooping);
}
void HwCastStreamPlayer::OnPlayRequest(const CastEngine::MediaInfo& mediaInfo)
{
SLOGI("Stream player received PlayRequest event");
std::shared_ptr<AVMediaDescription> mediaDescription = std::make_shared<AVMediaDescription>();
mediaDescription->SetMediaId(mediaInfo.mediaId);
mediaDescription->SetTitle(mediaInfo.mediaName);
mediaDescription->SetMediaUri(mediaInfo.mediaUrl);
mediaDescription->SetMediaType(mediaInfo.mediaType);
mediaDescription->SetMediaSize(mediaInfo.mediaSize);
mediaDescription->SetStartPosition(static_cast<uint32_t>(mediaInfo.startPosition));
mediaDescription->SetDuration(static_cast<uint32_t>(mediaInfo.duration));
mediaDescription->SetCreditsPosition(static_cast<int32_t>(mediaInfo.closingCreditsPosition));
mediaDescription->SetAlbumCoverUri(mediaInfo.albumCoverUrl);
mediaDescription->SetAlbumTitle(mediaInfo.albumTitle);
mediaDescription->SetArtist(mediaInfo.mediaArtist);
mediaDescription->SetLyricUri(mediaInfo.lrcUrl);
mediaDescription->SetLyricContent(mediaInfo.lrcContent);
mediaDescription->SetIconUri(mediaInfo.appIconUrl);
mediaDescription->SetAppName(mediaInfo.appName);
mediaDescription->SetDrmScheme(mediaInfo.drmType);
AVQueueItem queueItem;
queueItem.SetDescription(mediaDescription);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnPlayRequest for registered listeners");
listener->OnPlayRequest(queueItem);
}
}
SLOGI("Stream player received PlayRequest event done");
}
void HwCastStreamPlayer::OnImageChanged(std::shared_ptr<Media::PixelMap> pixelMap)
{
SLOGD("Stream player received ImageChanged event");
}
void HwCastStreamPlayer::OnData(const CastEngine::DataType dataType, const std::string& dataStr)
{
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
AAFwk::WantParams data;
data.SetParam("customData", AAFwk::String::Box(dataStr));
listener->OnCustomData(data);
}
}
}
void HwCastStreamPlayer::OnAlbumCoverChanged(std::shared_ptr<Media::PixelMap> pixelMap)
{
SLOGI("Received AlbumCoverChanged callback");
if (pixelMap == nullptr) {
SLOGE("Invalid pixelMap null");
return;
}
std::shared_ptr<AVSessionPixelMap> innerPixelMap =
AVSessionPixelMapAdapter::ConvertToInnerWithLimitedSize(pixelMap);
if (innerPixelMap == nullptr) {
SLOGE("Invalid innerPixelMap null");
return;
}
std::shared_ptr<AVMediaDescription> mediaDescription = nullptr;
{
std::lock_guard lockGuard(curItemLock_);
mediaDescription = currentAVQueueItem_.GetDescription();
}
if (mediaDescription == nullptr) {
SLOGE("OnAlbumCoverChanged with nullptr mediaDescription, return with default");
return;
}
mediaDescription->SetIcon(innerPixelMap);
AVQueueItem queueItem;
queueItem.SetDescription(mediaDescription);
{
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnMediaItemChange for registered listeners on Album change");
listener->OnMediaItemChange(queueItem);
}
}
}
{
std::lock_guard lockGuard(curItemLock_);
currentAVQueueItem_ = queueItem;
}
SLOGI("Received AlbumCoverChanged callback done");
}
void HwCastStreamPlayer::OnAvailableCapabilityChanged(const CastEngine::StreamCapability &streamCapability)
{
SLOGE("Received OnAvailableCapabilityChanged callback");
std::vector<int32_t> supportedCastCmds;
checkCmdsFromAbility(streamCapability, supportedCastCmds);
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnValidCommandChange for registered listeners");
listener->OnValidCommandChange(supportedCastCmds);
}
}
}
void HwCastStreamPlayer::OnKeyRequest(const std::string& assetId, const std::vector<uint8_t>& keyRequestData)
{
SLOGD("Stream player received keyRequest event");
std::lock_guard playerListLockGuard(streamPlayerListenerListLock_);
for (auto listener : streamPlayerListenerList_) {
if (listener != nullptr) {
SLOGI("trigger the OnKeyRequest for registered listeners");
listener->OnKeyRequest(assetId, keyRequestData);
}
}
SLOGI("Stream player received keyRequest event done");
}
void HwCastStreamPlayer::checkCmdsFromAbility(
const CastEngine::StreamCapability& streamCapability, std::vector<int32_t>& supportedCastCmds)
{
if (streamCapability.isPlaySupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_PLAY);
}
if (streamCapability.isPauseSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_PAUSE);
}
if (streamCapability.isStopSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_STOP);
}
if (streamCapability.isNextSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_NEXT);
}
if (streamCapability.isPreviousSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_PLAY_PREVIOUS);
}
if (streamCapability.isSeekSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_SEEK);
}
if (streamCapability.isFastForwardSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD);
}
if (streamCapability.isFastRewindSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_REWIND);
}
if (streamCapability.isLoopModeSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_SET_LOOP_MODE);
}
if (streamCapability.isSetVolumeSupported) {
supportedCastCmds.push_back(AVCastControlCommand::CAST_CONTROL_CMD_SET_VOLUME);
}
}
void HwCastStreamPlayer::checkAbilityFromCmds(
const std::vector<int32_t>& supportedCastCmds, CastEngine::StreamCapability& streamCapability)
{
for (const int32_t cmd : supportedCastCmds) {
switch (cmd) {
case AVCastControlCommand::CAST_CONTROL_CMD_PLAY:
streamCapability.isPlaySupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_PAUSE:
streamCapability.isPauseSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_STOP:
streamCapability.isStopSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_PLAY_NEXT:
streamCapability.isNextSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_PLAY_PREVIOUS:
streamCapability.isPreviousSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SEEK:
streamCapability.isSeekSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD:
streamCapability.isFastForwardSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_REWIND:
streamCapability.isFastRewindSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SET_LOOP_MODE:
streamCapability.isLoopModeSupported = true;
break;
case AVCastControlCommand::CAST_CONTROL_CMD_SET_VOLUME:
streamCapability.isSetVolumeSupported = true;
break;
default:
break;
}
}
streamCapability.isToggleFavoriteSupported = false;
}
} // namespace OHOS::AVSession