Android开机动画和BootVideo介绍
1. Android bootanimation¶
1.1. bootanimation启动和结束¶
bootanimation的启动和结束受surfaceflinger控制。
bootanimation虽然是core类的服务,但是在其rc文件中被配置了disabled,所以init进程在boot action阶段并不会启动bootanimation。Android把它的启动逻辑放在了surfaceflinger的初始化方法中。
surfaceflinger在初始化过程中,通过设置属性ctl.start值为bootanim启动bootanimation(init进程会监听ctl开头的控制类属性,当其值发生变化时进行相应操作,例如可通过修改ctl.start属性值用来启动相应的service),并设置属性service.bootanim.exit值为0,该值决定开机动画是否退出,当系统开机动作完成后,surfaceflinger会将service.bootanim.exit设为1,于是bootanimation退出循环播放,进入桌面。
1.2. bootanimation资源¶
bootanimation会依次在/product/media/、/oem/media/、/system/media/等路径下,寻找名为bootanimation.zip的资源包,被首先找到的资源包将被解析并作为开机动画。如果这些路径下都没有资源包,则会直接使用Android最原始的开机动画,其资源存放在system/framework/framework-res.apk中。所以,如果要替换开机动画,只需要替换上述资源包即可。
1.3. bootanimation配置¶
bootanimation.zip中,包含了一个或者多个文件夹,还有一个名为desc.txt的配置文件。
文件夹的名称一般是part+数字,代表该文件夹里面的资源组成了开机动画的第n个部分,如果自定义文件夹名称,则在desc.txt中配置统一即可;每个文件夹里面都是png格式的图片,由于图片播放顺序是根据图片名称字符排序的,所以图片名称需要按照预期播放顺序来配置,一般直接用数字命名,bootanimation会根据配置的帧率将这些图片依次展示,从而成为用户眼中的开机动画。
desc.txt是开机动画的配置文件,其格式范例如下:
512 416 60 c 1 0 part0 c 1 15 part1 c 1 0 part2 c 1 0 part3 f 0 0 part4 10
第一行的前两个参数512和416是png图片的分辨率,分辨率数值上没有限制,最终都会通过open GL库转换适配屏幕分辨率,但要求zip包中每一张图片的分辨率都保持一致;第三个参数60是帧率。
第二行(以及之后的每一行)的第一个参数有三个可选项‘p’、‘c’和‘f’,‘p’代表动画可以被中断,当开机完成后动画立刻停止,‘c’代表即使开机完成也要继续等待动画播放结束,‘f’的主要逻辑同‘p’,但具有淡出效果;第二个参数是播放次数,如果是0表示无限循环直至开机完成;第三个参数表示阶段间隔时间,单位是帧;第四个参数就是该部分动画对应的文件夹名称;如果第一个参数是‘f’,则该行还会有第五个参数,该数字代表淡出所需的帧数,例如上述范例中的10代表在开机完成后,该部分动画将以淡出的效果继续播放10帧。
特别提醒:
-
desc.txt文件末尾需留一空行
-
压缩成zip包时,压缩方式选择存储,即不做压缩
2. bootvideo客制化¶
2.1. bootvideo与bootanimation的差异¶
-
虽然都在surfaceflinger刚启动时展示,但bootvideo进程起的比bootanimation要早。bootvideo是init初始化阶段就被拉起,等到surfaceflinger启动之后才显示画面(原因在后面阐述),而bootanimation是被surfaceflinger在初始化过程中拉起。
-
bootvideo退出时间点是SystemServer将sys.boot_completed属性设为1,代表开机完成;bootanimation退出时间点(不考虑淡出等效果)是surfaceflinger将service.bootanim.exit属性设为1。两者时间非常接近,bootanimation退出的时间点稍微靠后。
-
bootvideo目前不能配置退出的动作,也就是说开机完成后马上退出,不会等视频文件播放完。
-
bootvideo实际上是视频播放,而bootanimation实际上是动图播放。所以bootvideo可以有声音而bootanimation没有。
-
bootvideo的bin文件放在vendor分区,所以它是一个vendor进程,无法与system进程通过binder通信,也无法使用system库,它音视频解码使用的ffmpeg,vdec均为vendor专有库;bootanimation的bin文件放在system分区,所以它是一个system进程,它可以通过binder与system进程(如surfaceflinger)通信,它的png解码使用的库都是framework专有库,解码完的buffer通过surfaceflinger送hwc合成。
2.2. bootvideo配置¶
bootvideo配置的文件在代码中的/device/sigmastar/<platform_name>/<product_name>/bootvideo/
路径下。其中,default_ad.mp4是默认的视频源,default_configuration.xml就是对应的默认配置,这两个文件将被放到设备的vendor/etc/bootvideo目录下,如果客户没有定制视频,则开机默认播放此视频源;如果需要定制视频,视频源的文件格式必须是mp4,编码格式必须是H.264,将视频源文件重命名为ad1.mp4,也为其新建一个configuration.xml配置文件,那么这两个文件将被放到设备的/data/vendor/bootvideo/路径下。最后,需确认该product的device.mk对上述文件做了正确的拷贝,另外由于bootvideo和bootanimation是互斥的,所以还需要在device.mk中关闭bootanimation,bootanimation在代码逻辑中对属性debug.sf.nobootanimation做了判断,如果该属性值为1,则不会播放开机动画,所以device.mk的配置如下图所示。
再看bootvideo可配置的选项,均在configuration.xml中定义。
目前支持三项配置。
- path参数可配置视频源的路径和文件名,bootvideo是vendor进程,由于SELinux的限制,视频源文件只能放在vendor分区或者/data/vendor/路径下才能被bootvideo获取到。
- videoLimit参数可配置视频源的最长播放时间,也就是说如果超出了这一时间,即使开机没有完成也将退出视频播放。
- isEnableInput参数可配置bootvideo是否响应遥控器操作,用以调整音量或者静音选项。
2.3. bootvideo工作流程与总体框架¶
init进程通过解析bootvideo.rc文件,拉起bootvideo进程。bootvideo进程被拉起后会做短暂的等待,等待surfaceflinger启动后再进行下一步逻辑,这是因为目前bootvideo会获取hwc的drm_fd来操作drm驱动(否则,bootvideo占用drm资源会影响hwc的初始化,从而拖慢开机时间),而hwc又是在surfaceflinger启动后才开始对drm做相关初始化,后续如果能够做到bootvideo和hwc对drm的占用能够平滑过渡,则可省去这一段逻辑,并把开机时间提前数秒。bootvideo对drm和alsa驱动做完初始化后,将启动两个线程分别处理audio和video。
bootvideo的功能可以分为4个模块。
- configer模块用于解析configuration.xml并做相应配置。
- input模块用于监听/dev/input/路径下的设备节点,当有key_event事件上报时,可根据其key value值来调整音量,补充说明的是,这一事件上报通路与Android原生的通路相互独立,不会影响原生逻辑。
- UI模块用于绘制音量条/静音按钮的图层,在input模块调整音量时作为显示交互,目前方案是通过open GL绘制图层,然后将该图层置于video图层的上方。
- player模块就是真正的视频播放器。首先,它利用ffmpeg将mp4格式的视频源分离出音频流和视频流,音频流将再次送ffpmeg解析出pcm码流,最后直接操作alsa驱动放音;视频流将通过MI Vdec解码,最后送drm驱动。
在bootvideo播放的过程中,视频源将被循环播放;当开机完成或者bootvideo播放超过最长时限时,将会立刻停止播放,退出进程。如果因为超过播放最长时限而停止,且此时系统未完成启动,则在进入launcher前将会有短暂黑屏时间。
2.4. bootvideo调试¶
如果需要关闭bootvideo,开启原生bootanimation,那么可将/device/sigmastar/<platform_name>/<product_name>/device.mk
中# Boot Video service
下面的配置全部删除,重新编译刷机即可;也可以remount当前设备,将vendor/bin/sstar_bootvideo_service改名或者删除,再将vendor/build.prop文件中debug.sf.nobootanimation=1
这一行删除,重启即可。
如果需要在开机完成的状态下运行调试bootvideo,先执行命令setprop sys.boot_completed 0
,再执行命令./vendor/bin/sstar_bootvideo_service &
即可播放开机视频。但此时应该只有声音而没有画面,因为系统UI图层默认在视频图层上方,也就是说Android UI挡住了bootvideo,如果需要观看视频画面,还需要关闭UI图层显示(例如P5的平台需要操作两个寄存器,执行指令riu_w 11B5 0 0x4050
;riu_w 11B4 7f 200
)。此时,由于已经开机完成,SystemServer不会再改变setprop sys.boot_completed属性值,所以开机动画将循环播放直至最长播放时限。