开机动画相关总结
开机动画相关
开机动画社区代码默认为视频播放,想要测试图片播放可以修改源码或者增加配置文件使其播放图片,一般建议是增加配置文件
代码修改如下
路径: foundation/graphic/graphic_2d/frameworks/bootanimation/include/boot_animation_operation.h
将 if (IsBootVideoEnabled(config)) 里面的条件写为 false 即可
void BootAnimationOperation::StartEventHandler(const BootAnimationConfig& config)
{
LOGI("StartEventHandler");
runner_ = AppExecFwk::EventRunner::Create(false);
mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
// mainHandler_->PostTask([this] { this->InitRsDisplayNode(); });
mainHandler_->PostTask([this, &config] { this->InitRsSurfaceNode(config.rotateDegree); });
mainHandler_->PostTask([this] { this->StopBootAnimation(); }, duration_);
advertisement = config.advertisement_status;
rotateDegree = config.rotateDegree;
#ifdef PLAYER_FRAMEWORK_ENABLE
if (IsBootVideoEnabled(config)) {
mainHandler_->PostTask([this, &config] { this->PlayVideo(config.videoDefaultPath); });
if (ADVERTISEMENTPRESENT == advertisement)
{
mainHandler_->PostTask([this] { this->RegisterInput(); });
}
runner_->Run();
LOGI("runner run has ended.");
return;
} else {
mainHandler_->PostTask([this, &config] { this->PlaySound(config.soundPath); });
}
#else
LOGI("player framework is disabled");
#endif
mainHandler_->PostTask([this, &config] { this->PlayPicture(config.picZipPath); });
if (ADVERTISEMENTPRESENT == advertisement)
{
mainHandler_->PostTask([this] { this->RegisterInput(); });
}
runner_->Run();
LOGI("runner run has ended.");
}
一、增加配置文件使其图片视频播放
-
hisi默认将视频播放关闭了,需要修改宏
将
vendor/hisilicon/hispark_hi3751v352/config.json
中graphic_2d_feature_bootanimation_video_enable = false
改为true
。 -
本地新建
bootanimation_custom_config.json
文件,内容如下:
测试图片播放:
{
"cust.bootanimation.pics": "/system/etc/graphic/bootpic.zip",
"cust.bootanimation.sounds": "/system/etc/graphic/bootsound.wav"
}
测试视频播放:
{
"cust.bootanimation.video": "/system/etc/graphic/bootvideo.mp4"
}
- 创建文件夹
/system/etc/bootanimation
,将bootanimation_custom_config.json
推入此目录下。 - 执行
hdc shell bootanimation
播放开机动画
二、开机动画旋转
在bootanimation_custom_config.json
文件中添加以下内容控制旋转,degree为旋转角度。
"cust.bootanimation.rotate.screenid": "0",
"cust.bootanimation.rotate.degree": "90"
由于图层是在原始角度下绘制好了之后再进行旋转的,超出屏幕的部分并没有被绘制,旋转之后如果有超出屏幕的部分也不会显示,所以旋转后会出现只显示中间部分的现象。使用旋转功能需要确保旋转前后的动画均在屏幕范围内,即动画资源分辨率要不大于屏幕内所能显示的最大正方形的大小。
目标效果:开机动画按degree的角度旋转。
三、开机动画资源替换
在 /system/etc/graphic/ 下 有 bootvideo.mp4 和 bootpic.zip文件,分别对应默认开机动画的视频和图片资源,可以替换成自己想要的资源重命名为 bootvideo.mp4 和 bootpic.zip 即可
四、开机动画相关问题案例以及解决方法
无法播放开机动画(显示黑屏),内核logo后黑屏一会直接进入 launcher
- 开机动画资源问题
查看日志没有明显报错,或者播放视频资源的时候显示创建 mediaplayer 失败后退出。
这种情况可以替换下开机动画资源,可以下载社区上的开机动画资源替换
-
视频播放 视频音轨问题导致无法播放
日志会有 创建 mediaplaer失败的打印,明显可以看到 获取 SA:3002服务失败,这种情况是视频音轨有问题导致
音频服务获取异常,可以替换资源或者在获取sa服务的地方增加重试次数(次操作会拉长开机总体耗时),代码如下
foundation/systemabilitymgr/samgr/frameworks/native/source/system_ability_manager_proxy.cppsptr<IRemoteObject> SystemAbilityManagerProxy::GetSystemAbilityWrapper(int32_t systemAbilityId, const string& deviceId) { if (!CheckInputSysAbilityId(systemAbilityId)) { HILOGW("GetSaWrap SA invalid:%{public}d!", systemAbilityId); return nullptr; } bool isExist = false; int32_t timeout = RETRY_TIME_OUT_NUMBER; HILOGD("GetSaWrap:Waiting for SA:%{public}d, ", systemAbilityId); do { sptr<IRemoteObject> svc; int32_t errCode = ERR_NONE; if (deviceId.empty()) { svc = CheckSystemAbility(systemAbilityId, isExist, errCode); if (errCode == ERR_PERMISSION_DENIED) { HILOGE("GetSaWrap SA:%{public}d selinux denied", systemAbilityId); return nullptr; } if (!isExist) { HILOGD("%{public}s:SA:%{public}d is not exist", __func__, systemAbilityId); } } else { svc = CheckSystemAbility(systemAbilityId, deviceId, errCode); if (errCode == ERR_PERMISSION_DENIED) { HILOGE("GetSaWrap SA:%{public}d deviceId selinux denied", systemAbilityId); return nullptr; } } if (svc != nullptr) { return svc; } if (timeout > 0) { usleep(SLEEP_ONE_MILLI_SECOND_TIME * SLEEP_INTERVAL_TIME); } } while (timeout--); HILOGE("GetSaWrap SA:%{public}d not start", systemAbilityId); return nullptr; }
在这里加一个逻辑,如果是 3002 服务,将它的timeout从默认的6次增加到 20(尝试后得出的次数)后可以正常获取到服务
视频播放开机动画闪屏,图片播放正常,且进桌面后手动执行开机动画,视频播放不响应
这种情况下,所有的日志正常,开机动画流程正常,画面闪烁,而且内核log一直不消失
这种情况查看 layer 信息发现也是正常的,就比较难定位了。后来尝试关闭 g0图层的显示发现可以正常显示开机动画了,才得知此项目上
视频播放走的不是系统的图形层,而是特殊的 vo层,闪屏是因为 内核logo的背景是白色的,会透出 vo视频层的画面。
解决方法有两种,一种是内核logo修改下,让它最后刷一帧黑色背景。但是这种修改无法解决在桌面手动执行开机动画无法显示的问题(但是考虑到正常场景不会有进入系统后再播放开机动画,所以可以采用这个办法)
二是在开机动画里面加一下执行逻辑,在开始播放视频的时候手动去隐藏掉 图形层g0,在结束播放的时候在解除隐藏即可。代码如下
foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_video_player.cpp
void VideoPlayerCallback::OnInfo(Media::PlayerOnInfoType type, int32_t extra, const Media::Format &infoBody)
{
switch (type) {
case Media::INFO_TYPE_SEEKDONE:
LOGI("PlayerCallback: OnSeekDone currentPositon is: %{public}d", extra);
break;
case Media::INFO_TYPE_SPEEDDONE:
LOGI("PlayerCallback: SpeedDone");
break;
case Media::INFO_TYPE_BITRATEDONE:
LOGI("PlayerCallback: BitRateDone");
break;
case Media::INFO_TYPE_EOS: {
LOGI("PlayerCallback: OnEndOfStream isLooping is: %{public}d", extra);
boot_->StopVideo();
break;
}
case Media::INFO_TYPE_BUFFERING_UPDATE:
LOGI("PlayerCallback: Buffering Update");
break;
case Media::INFO_TYPE_BITRATE_COLLECT:
LOGI("PlayerCallback: Bitrate Collect");
break;
case Media::INFO_TYPE_STATE_CHANGE:
LOGI("PlayerCallback: State Change, current state is: %{public}d", extra);
if (Media::PlayerStates::PLAYER_PREPARED == extra) {
int32_t width = boot_->GetMediaPlayer()->GetVideoWidth();
int32_t height = boot_->GetMediaPlayer()->GetVideoHeight();
LOGI("UpdateBound[%{public}d %{public}d]", width, height);
boot_->UpdateBound(width, height);
LOGI("Begin to play");
std::system("echo hide > /proc/msp/gfbg0");
boot_->GetMediaPlayer()->Play();
}
break;
case Media::INFO_TYPE_POSITION_UPDATE: {
LOGD("PlayerCallback: Position Update");
break;
}
case Media::INFO_TYPE_MESSAGE:
LOGI("PlayerCallback: OnMessage is: %{public}d", extra);
if (!system::GetBoolParameter(BOOT_ANIMATION_STARTED, false)) {
system::SetParameter(BOOT_ANIMATION_STARTED, "true");
}
break;
case Media::INFO_TYPE_RESOLUTION_CHANGE:
LOGI("PlayerCallback: Resolution Change");
break;
case Media::INFO_TYPE_VOLUME_CHANGE:
LOGI("PlayerCallback: Volume Changed");
break;
default:
LOGI("PlayerCallback: Default");
break;
}
}
使用 std::system("echo hide > /proc/msp/gfbg0"); 手动隐藏
foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation_strategy.cpp
bool BootAnimationStrategy::CheckExitAnimation()
{
if (!isAnimationEnd_) {
LOGI("boot animation is end");
system::SetParameter(BOOT_ANIMATION_FINISHED, "true");
isAnimationEnd_ = true;
}
bool bootEventCompleted = system::GetBoolParameter(BOOT_COMPLETED, false);
if (bootEventCompleted) {
LOGI("read boot completed is true");
std::system("echo show > /proc/msp/gfbg0");
return true;
}
return false;
}
std::system("echo show > /proc/msp/gfbg0");退出的时候释放
开机动画卡在最后一帧没进系统,查看进程发现开机动画没退出
这种情况下参考上面我们将图层解除隐藏的那块代码,开机动画退出的条件是 bootcomplete,找一下投票事件是谁没有准备好,和开机动画流程没有关系
一般是launcher有问题导致的
在hilog里面搜索 bootevent 查看投票事件
黑屏
- 排查是不是有双屏异显代码,可以接另一个屏幕看看有没有画面。
- 屏幕是否上电/背光下发是否成功,搜索关键日志 "lcd_kit_o|lcd_kit_set_backlight|lcd_kit_check_reg_report_dsm|dpu_gfxdev_blank", 其中primary是内屏black mode: 0上电, 4下电, 1假下电
- dump下rs tree 看下displayNode surfaceNode 是否都在树上
播放过程中卡顿、花屏、马赛克等
先排查资源问题
进系统后用视频播放器播放同样的资源播放,是否有同样的现象,找media相关的报错排查。不是开机动画这块的问题
更多推荐
所有评论(0)