OpenHarmony视频旋转透屏分析
一、关键字 视频旋转;透屏 二、问题描述 设备型号:rk3568系统版本号:OpenHarmony 4.1代码版本号:OpenHarmony 4.1问题现象:Photo应用播放视频时进行旋转操作,旋转过程中视频的位置大小不正确,而且底层的桌面会透出来。 三、原因分析 3.1 正常机制 旋转时,视频在屏幕中心旋转,位置大小渐变为目标位置大小,底层的桌面不会透出来。 3.2 异常机制 旋转时,视频大小
一、关键字
视频旋转;透屏
二、问题描述
设备型号:rk3568
系统版本号:OpenHarmony 4.1
代码版本号:OpenHarmony 4.1
问题现象:Photo应用播放视频时进行旋转操作,旋转过程中视频的位置大小不正确,而且底层的桌面会透出来。
三、原因分析
3.1 正常机制
旋转时,视频在屏幕中心旋转,位置大小渐变为目标位置大小,底层的桌面不会透出来。
3.2 异常机制
旋转时,视频大小没有发生变化直到最后一帧才变为目标大小;视频位置不在屏幕中心;底层桌面透出。
3.2.1 视频大小异常分析
根据代码流程,视频大小的计算是在RenderThread(RT)的Animate中进行的,之后会将大小发送给RenderService(RS)。
void RSSurfaceRenderNode::SetContextBounds(const Vector4f bounds)
{
std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetBounds>(GetId(), bounds);
SendCommandFromRT(command, GetId());
}
RS会在ProcessCommand中处理接受到的命令,更改视频节点的属性。
void SurfaceNodeCommandHelper::SetContextBounds(RSContext& context, NodeId id, Vector4f bounds)
{
if (auto node = context.GetNodeMap().GetRenderNode<RSSurfaceRenderNode>(id)) {
node->GetMutableRenderProperties().SetBounds(bounds);
}
}
此时视频大小属性是正常的,但是RS中的视频节点存在一条关于视频大小的modifier,它没有被改变,保存的仍然是视频原始的大小。在后续的ApplyModifiers操作中将视频大小修改回了原始大小,导致了旋转过程中视频大小没有发生变化。直到旋转完成,应用才会发送命令更新modifier。
3.2.2 底层桌面透出分析
实际上旋转透屏不仅视频会出现,其他任何Xcomposer组件节点都会出现这一问题(比如备忘录的文本编辑区域)。它们相当于是一个插件被插入应用的图层中,RT会对应用的画布挖洞来存放XComposer。当挖洞的区域与视频区域不吻合时,就会出现透屏。此现象是由多方面的原因导致的,总结出了一下几点原因,但还不确定这些是否就是全部的原因。
3.2.2.1 挖洞大小会随画布变化而变化
挖洞操作是在RT中进行的,此时的画布大小还是原始大小,没有因为旋转而放缩。当后面画布进行放缩时,挖洞区域的大小也会随之放缩,而视频区域是最初挖洞的大小,当进行合成时它们也就不吻合了,导致透屏。
3.2.2.2 视频图层大小与其他图层大小变化不同步
视频的旋转动画计算是在RT中进行的,而其他图层是在RS中进行的。
当执行旋转命令时,RS和应用同时做出反应,RS对Entry、Photo等非XComposer图层进行大小计算,应用对应用内的一些组件进行布局计算。当应用布局计算结束之后才会给RT发送命令进行大小位置计算,此时距离刚开始执行旋转命令已经过去很久了(10帧左右),也就是说相对于整个动画过程的大小位置变化进度,其他图层的大小位置比视频的大小位置变化领先了10帧左右。桌面旋转时,应用图标变化比旋转进度慢也是这个原因。
3.2.3 视频位置不在中心分析
主要有两点原因:
- 由于3.2.2.2提到的原因,视频位置大小变化进度与其他图层进度不符,它们之间的位置大小自然就对应不上。
- RT中计算的视频位置大小是基于原始画布的,将视频“画上”画布时拿的是放缩过后的画布,这就导致了视频位置不在画布中心。
四、解决方案
经过以上分析,旋转透屏属于底层框架的问题,牵涉面甚多,暂时没有正式的解决方案。下面给出规避方案(只是从现象上规避)。
4.1 规避视频大小不变化问题
foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp
4.2 规避视频位置不在屏幕中心的问题
foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/pipeline/rs_surface_render_node.cpp
4.3 规避透屏问题
foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/pipeline/rs_surface_render_node.cpp
更多推荐
所有评论(0)