一、UI绘制层OSD显示异常,例如:
1、在首页或者其他APK 其他界面出现花屏,斜屏,黑屏,显示区域缩小或者超出屏幕的情况。
2、在视频播放界面中,控制栏出现花屏,斜屏,或者无法调出控制栏的情况;
针对不芯片不同OSD厂商的机顶盒,底层有节点可以debug osd层,但是应用层只需要关心是OSD本身问题;有root权限的盒子可以使用fb2png 工具,将该工具拷贝至/system/bin 下,并修改其权限(chmod 777 /system/bin/fb2png)
输入命令:fb2png /storage/external_storage/sdcard1/test.png,输出:
bpp : 4
width : 1920
height : 1080
pixel : 8294400
r_offset : 0
g_offset : 8
b_offset : 16
a_offset : 24
r_length : 8
g_length : 8
b_length : 8
a_length : 8
完成后再pull出来查看图片是否正常。
针对部分IPTV Amlogic的芯片;例如乐视U4盒子、ZTEB860AV1.1-T的盒子、小米3盒子等:
root@U4:/ # cat /sys/class/graphics/fb0/free_scale
free_scale_enable:[0x10001]
root@U4:/ # cat /sys/class/graphics/fb0/freescale_mode
free scale mode:
0: VPU free scaler
1: OSD free scaler
2: OSD super scaler
current free_scale_mode:1
root@U4:/ # cat /sys/class/graphics/fb0/free_scale_axis
0 0 1919 1079
root@U4:/ # cat /sys/class/graphics/fb0/window_axis
0 0 1919 1079
(1)sys/class/graphics/fb0/free_scale_axis的值必须为“0 0 1279 719”,否则为异常值。
(2) /sys/class/graphics/fb0/freescale_mode的值必须为“free_scale_mode:normal”,否则为异常值。
(3)/sys/class/graphics/fb0/free_scale的值在非720制式下必须为“free_scale_enable:[0x1]”;720制式下,如果打开了点对点播放视频时,则free_scale的值必须为0,其他情况为0或1都不会有影响。
(4)/sys/class/ppmgr/ppscaler_rect和/sys/class/video/axis这两个节点的值必须要小于或等于当前分辨率,但是也不能小到超过20%。譬如HDMI为720P模式,则HDMI的宽和高分别为1280,720,因此cat /sys/class/graphics/fb0/window_axis得到的宽和高必须满足上面提到的要求,其他HDMI模式,依次例推。
(5)display-size必须为1280x720,density必须为160,否则为异常值。(如果是720UI的话)
二、视频播放异常;
目前MBOX主流的盒子,视频层都是机顶盒芯片内置解码器demux硬解的video,音频是CPU的软解;
OTT盒子主流的,本地视频主要是系统自带的播放器解码的,因为本地视频解码视频类型太多,这块没办法脱离芯片本身解码器强大的解码能力;
流媒体解码可以用MediaPlayer的公共API系统解码,或者类似小米自己ffmpeg,集成vlc自己切换软硬解;乐视用的ExoPlayer重新封装了播放器,都是大同小异;
大家有时间可以自己研究下下面几个开源播放器:
简要点评:
1、ijkplayer 结构简单,开发难度小,官方维护力度小
2、Exoplayer 谷歌儿子更新快,维护团队强大,不适合直播
3、Vlc 跨平台兼容性最佳,功能全支持rtsp,完全解耦,维护团队强大,更新快,学习成本,很多库用不上;
当前主流的流媒体格式有:
1、HTTP
2、Hls、DASH、smooth streaming
3、RTP、RTCP、RTSP
4、MMS、MMSU、MMST
5、RTMP
6、UDP、IGMP
大部分芯片厂商自己会在ffmpeg里面实现相关解码;
rtp协议简介:
实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。
RTCP协议简介:
RTCP(RTP control protocol)负责管理传输质量在当前应用进程之间交换控制信息。在RTP会话期间,各参与者周期性地传送RTCP包,包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料。
1) RTSP协议(Real Time Streaming Protocol,实时流传输协议)以客户服务器方式工作,它是一个多媒体播放控制协议,用来使用户在播放从网络下载的实时数据时能够进行控制,如:暂停/继续、后退、前进等。
(2) RTSP与RTP和RTCP的关系:
1、Dash(Dynamic Adaptive Streaming)是基于 HTTP传输协议的自适应码率 协议,它提出了一个层次化的文件组织结构。
2、基本模型:
3、mpd脚本模型(媒体呈现)
4、文本解析:
5、切片下载与输出:
例如视频播放黑屏:
app如果怀疑系统异常,可以初步分析视频层是在osd还是video layer上显示的,例如:
例如 B860AV1.1-T电信4K盒子
输入命令:cat /sys/class/vfm/map,输出:
default_osd { osd(0) amvideo4osd}
default_ext { vdin0(0) vm}
default_amlvideo2 { vdin1(0) amlvideo2}
default { decoder(0) ppmgr(0) deinterlace(0) amvideo}
provider list:
receiver list:
… …
在播放视频过程中,如果输出为:
default { decoder(1) ppmgr(1) deinterlace(1) amvideo}则为video layer 显示。
default { decoder(0) ionvideo}则为osd 显示。
default { decoder(0) ppmgr(0) deinterlace(0) amvideo}则是APK 自己解码,显示在OSD 层
2)若video layer 已开启,则确认OSD 是否把video layer 挡住:
尝试关闭OSD 层,输入命令echo 1 > /sys/class/graphics/fb0/blank 观察输出是否有变化。
打开OSD 层命令echo 0 > /sys/class/graphics/fb0/blank
3)确定是不是ppmgr 和deinterlace 造成的:
输入以下两条指令后,再播放视频能显示,则说明是ppmgr 或者deinterlace 有问题
echo rm default > /sys/class/vfm/map
echo add default decoder amvideo > /sys/class/vfm/map
4)解码器状态是否正常:
在播放视频时输入命令cat /sys/class/vdec/amrisc_regs
输出【amrisc is power off】表示解码器未打开
输出【amrisc registers show: … …】表示解码器正常
5)比对寄存器(取正常情况与异常情况的寄存器值进行比对):
在播放视频时输入命令echo dump v 0x1d01 0x1d40 > /sys/class/amlogic/debug
IPTV机顶盒视频花屏、抖动有马赛克这种,我们是直接调用的底层解码的,花屏问题跟app播放器无关,这种一般是DI,解码,微码问题等造成的;
视频画面卡住或位置比例异常这种:
视频画面卡住跟app无关;
视频位置不对,或者是视频比例和尺寸不对这种
例如直播小窗位置异常,需要确定下x,y偏移量跟UI实际尺寸是否匹配,比如视频层x,y的实际位置错误等;
因为之前ZTE系列盒子不支持直播小窗播放;
这里说下这款的盒子的适配情况,需要针对固件做的私有处理,app适配url
需要在url拼接直播rtp流:
1、&window_x=xxx,表示视频左上角x坐标;
2、&window_y=xxx,表示视频左上角y坐标;
3、&window_w=xxx,表示视频宽;
4、&window_h=xxx,表示视频高
5、&windowmode=xxx,表示分辨率,其中windowmode=1表示PAL, windowmode=2表示NTSC, windowmode=3、4表示720P,windowmode=5、6表示1080i,windowmode=7、8表示1080P,windowmode=9表示4K。
例如:
rtsp://122.224.212.79:554/service?PuId-ChannelNo=121535000100000440-01&PlayMethod=0&StreamingType=0&window_x=172&window_y=367&window_w=546&window_h=466&windowmode=5
需要特别注意在IPTV 机顶盒里面,针对直播rtsp的流厂家适配的都不是很好,如果是布局文件XML里写的SurfaceView的这种,兼容2K/4K盒子多数打洞会比较快,如果是在代码里面setSufaceView的宽高,部分盒子可能会影响UI刷新,需要注意初始化的顺序;
需要对SurfaceView深度认识下:
View是通过刷新来重绘视图;
View和SurfaceView的区别:
1 . View适用于主动更新的情况,而SurfaceView则适用于被动更新的情况,比如频繁刷新界面。
2 . View在主线程中对页面进行刷新,而SurfaceView则开启一个子线程来对页面进行刷新。
3 . View在绘图时没有实现双缓冲机制,SurfaceView在底层机制中就实现了双缓冲机制。
当一个动画争先显示时,程序又在改变它,前面还没有显示完,程序又请求重新绘制,这样屏幕就会不停地闪烁。而双缓冲技术是把要处理的图片在内存中处理好之后,再将其显示在屏幕上。双缓冲主要是为了解决 反复局部刷屏带来的闪烁。把要画的东西先画到一个内存区域里,然后整体的一次性画出来。
标红的区域是我们需要注意的,SurfaceView不同于其他View,它的绘制会比UI 提前,所以如果是需要动态计算SurfaceView 宽高的话,需要选对合适的时机去获取宽高、包括刷新也要注意这个;
如果需要拼串去适配小屏直播播放这种,大小屏无缝的时候可能需要重新setDataSource,可能无法做到无缝直播大小屏切换;
SurfaceView拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面
SurfaceView并没有使用View的宿主窗口(下面我都管这个宿主窗口为顶级surface),它有自己独立的surface,绘制是在这个独立的surface上绘制;
例如在Amlogic芯片,SurfaceView是在video layer层绘制的,UI是OSD绘制的;所以SurfaceView的区域实际是打洞的,video layer在底层,osd 可以盖在video layer上面,所以打洞的时候一定要确定宽、高(部分盒子需要check x,y坐标)等;
SurfaceTexture可以看成Surface和Texture的组合,是将图形生产者的数据送到Texture,跟简单的View一样操作,需要注意的是手机端surfaceTexture和OpenGL ES结合才能发挥出它最大的效果;
SurfaceTexture是从Android3.0(API 11)加入的一个新类,以从camera preview或者video decode里面获取图像流(image stream)。但是,和SurfaceView不同的是,SurfaceTexture在接收图像流之后,不需要显示出来,所以不存在之前打洞的时候视频播放被挡住这种case;
关于SurfaceView跟surfaceTexture 释放的问题,需要特别注意的是:
1、SurfaceView只有在成功destroy才能正常creat,不会影响UI的刷新,但是在SurfaceView的根布局在实时动态刷新UI,很容易导致OSD层出现看上去视频播放超出了窗口位置,整个屏幕偶先条状花纹;
2、对于机顶盒SurfaceTexture其实跟普通UI都是在同一层绘制的,SurfaceTexture资源释放的时候,UI显示需要重新绘制,并且要注意先后顺序,例如Fragment 默认的三屏缓存数据,如果SurfaceTexture 销毁释放资源的时候,很可能会把当前页的UI缓存数据一起释放掉,造成UI显示异常,无数据展示;
遇到视频播放异常的时候,先check mediaplayer的状态然后根据视频播放载体,SurfaceView或者SurfaceTexture的生命周期去深入分析;
视频流播放异常的情况分析,比如直播流等:
1、可以直接将直播地址在PC端用vlcPlayer check下;
2、点播流的话可以尝试把视频dump下来 adb pull出来在vlc播放
例如ZTE-B860AV1.1的盒子
1)创建一个用于保存dump 数据的文件夹,输入命令:mkdir /data/tmp
2)修改文件夹权限,输入命令:chmod 777 /data/tmp
3)设置dump 数据类型,输入命令:setprop media.libplayer.dumpmode x
x 的值:
【1】ts,ps,rm 几种流的raw data 从文件或网络读到的数据dump
【2】ts,ps,rm 几种流的raw data 写入解码buffer 的数据dump
【4】es 码流video 数据,读数据dump
【8】es 码流video 数据,写数据dump
【16】es 码流audio 数据,读数据dump
【32】es 码流audio 数据,写数据dump
dump 到的数据存放在/data/temp/pidn_dump_xx.dat 以pidn 开头,可以区分是哪个线程dump 出来的数据。
播放ts 如果开softdemux 后dump 不到ts 流,需要按es 流dump;
dump下来后先用mediainfo分析下是否格式正常,再用vlcPlayer check下是否本身编码问题还是其他问题;
另外针对直播大小屏无缝播放功能,部分IPTV机顶盒如果播放直播流的时候,不支持SurfaceView自适应,无法实现直播无缝切换;
三、另外补充下core dump
core dump 是软件错误无法恢复的产物(core 为内存的意思)。进程coredump 的时候,操作系统会将进程终止并释放其占用的资源,正常情况下,应用进程coredump 不会对系统本身的运行造成危害,但是造成app异常。发生core dump 的主要原因有以下几个方面:
1)内存访问越界
2)多线程程序使用了线程不安全的函数
3)多线程读写的数据未加锁保护
4)非法指针
5)堆栈溢出
系统修改xx.rc文件例如:system/core下面的init.rc
setrlimit 13 40 40 下增加一条记录: setrlimit 4 -1 -1。
增加修改后,当进程coredump 的时候,会在/data 下面生成core-XXXXXX 的文件,其中
%e:出Core 进程对应的可执行文件名
%p:出Core 进程的PID
%u:出Core 进程的UID
https://docs.microsoft.com/en-us/iis/extensions/smooth-streaming-manifest-structure/iis-smooth-streaming-client-manifest-format?redirectedfrom=MSDN