例如amlogic方案:
大部分情况是播放器的问题起来,这种情况主要是通过logcat -s AmSuperPlayer ;logcat -s AmlogicPlayer;
logcat -s amplayer 来查看LOG,看是否有错误信息。如果这些打印都没有出现,那可能是APK 的问题,或者系统
的其他问题,需要具体分析。
这种情况可以用PC 软件mediainfo 看一下片源里面的流的信息。确认文件里面是否有视频流。确定视频流的格式,
从而来确认我们播放器是否支持。
#echo 1 > /sys/module/di/parameters/bypass_all
#echo 1 > /sys/class/ppmgr/bypass
看看视频能不能出现,如果出现能确认是这两个模块的问题。
如果还是不出现,先退出播放,然后输入如下命令:
#echo rm default > /sys/class/vfm/map
#echo add default decoder amvideo > /sys/class/vfm/map
如果能正常播放,就属于这种情况。
# cat /sys/class/amstream/bufs
Video buffer: flag:7( Alloc Used Parser nofirststamp )
buf addr:0000000020c00000
buf size:0x2800000
buf canusesize:0x2800000
buf regbase:0xc40
buf level:0x6a
buf space:0x27fe796
buf read pointer:0x215a4800
buf first_stamp:0xffffffff
buf wcnt:0x153a5
buf max_buffer_delay_ms:0ms
buf current delay:160ms
buf bitrate latest:85140bps,avg:1545405bps
buf time after last pts:15070 ms
buf time after last write data :15070 ms
如果buf level 为0x0,就代表没有视频数据,可能是parser 或者是demux 的问题。如果是播放的ts 文件,可以切
换一下硬件demux 和软件demux,来确定问题。setprop libplayer.ts.softdemux 1 将demux 设置成软件demux。
echo 1 > /sys/class/graphics/fb0/blank
echo 1 > /sys/class/graphics/fb1/blank
如果输入这两个命令之后,视频显示出来了,就说明视频被OSD 遮住了。
可以再播放时输入如下命令:
#dumpsys SurfaceFlinger
type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame
| name
-----------+----------+------+------+----+------+-------------+--------------------------------+------------------------+------
HWC | f653cd80 | 0002 | 0000 | 00 | 0100 | RGBA_8888 | 0.0, 0.0, 1920.0, 1080.0 | 0, 0,
1920, 1080 | SurfaceView
GLES | f5c3c1f0 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 1920.0, 985.0 | 0, 0, 1920,
985 | com.droidlogic.videoplayer/com.droidlogic.videoplayer.VideoPlayer
FB TARGET | f65219c0 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 1920.0, 1080.0 | 0, 0,
1920, 1080 | HWC_FRAMEBUFFER_TARGET
查看有没有SurfaceView,并且看一下hint 是不是为0002。如果没有或者hint 不是0002,说明APK 没有创建videoview。
#cat /sys/class/video/disable_video
a、video layer 被关闭:
返回“1”,需要在代码中查找设置/sys/class/video/disable_video 为1 的地方。
b、没有视频帧需要输出:
返回“2”有可能和同步相关:
#echo 0 > /sys/class/tsync/enable
如果可以正常播放,就属于这种情况。有可能和deinterlace 或者ppmgr 相关,可以参见1.2.2 来确认这种情况。
这个一般都会有decoder error 的打印,查看kernel 打印就可以。
cat /sys/class/amstream/bufs
Video buffer: flag:7( Alloc Used Parser nofirststamp )
buf addr:0000000020c00000
buf size:0x2800000
buf canusesize:0x2800000
buf regbase:0xc40
buf level:0x17fe796
buf space:0x27fe796
buf read pointer:0x215a4800
buf first_stamp:0xffffffff
buf wcnt:0x153a5
buf max_buffer_delay_ms:0ms
buf current delay:160ms
buf bitrate latest:85140bps,avg:1545405bps
buf time after last pts:15070 ms
看video buffer 如果buf level 很高,而且不变化,排除di、ppmrg 的问题之后就应该是解码的问题。
需要抓取cat /sys/class/vdec/amrisc_regs 信息。来确定decoder 出现了什么问题。
走MediaCodec 和OMX 的时候,还有可能显示在OSD layer 上。
在播放过程中,输入如下串口命令:
#cat /sys/class/vfm/map
default_osd { osd(0) amvideo4osd}
default { decoder(1) ionvideo}
可以确认属于这种情况。
#cat /sys/class/video/axis (x0,y0,x1,y1)
#cat /sys/class/video/screen_mode(0:按片源比例显示;1:全屏;2:4 比3;3:16 比9)
#dumpsys SurfaceFlinger
type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame
| name
-----------+----------+------+------+----+------+-------------+--------------------------------+------------------------+------
HWC | f653cd80 | 0002 | 0000 | 00 | 0100 | RGBA_8888 | 0.0, 0.0, 1920.0, 1080.0 | 0, 0,
1920, 1080 | SurfaceView
GLES | f5c3c1f0 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 1920.0, 985.0 | 0, 0, 1920,
985 | com.droidlogic.videoplayer/com.droidlogic.videoplayer.VideoPlayer
FB TARGET | f65219c0 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 1920.0, 1080.0 | 0, 0,
1920, 1080 | HWC_FRAMEBUFFER_TARGET
标红的为video view 的位置
如果video view 的位置正确,而/sys/class/video/axis 的值不对,可能是换算出现问题。
logcat -s amavutils
E/amavutils( 2785): unable to open file /sys/class/graphics/fb2/clone,err: No such file or directory
I/amavutils( 2785): amvideo_utils_set_virtual_position :: x=0 y=0 w=1921 h=1081
I/amavutils( 2785): device resolution 1280x720
I/amavutils( 2785): disp resolution 1920x3240
I/amavutils( 2785): amvideo_utils_set_virtual_position:: disp_w=1920, disp_h=1080
I/amavutils( 2785): video global_offset 0
I/amavutils( 2785): set ppmgr angle :0
I/amavutils( 2785): /sys/class/graphics/fb0/free_scale_axis axis: 0 0 1919 1079
I/amavutils( 2785): after scaled, screen position3: 0 0 1280 720
I/amavutils( 2785): amvideo_utils_set_virtual_position (corrected):: x=0 y=0 w=1280 h=720
I/amavutils( 2785): /sys/class/graphics/fb0/free_scale_axis axis: 0 0 1919 1079
D/amavutils( 2785): amvideo_setscreenmode as 1.778499
蓝色字体为video view 的位置,红色字体为换算之后的video axis 的位置。
如果音视频同时卡顿,可能与如下原因:
a、buffer 下溢
这五项分别代表video、audio、subtitle、user data、h265video buffer 的情况,如果buf level 比较低,表示buffer 下
溢。有可能是player 送数据不够;如果是ts 文件,有可能是demux 有问题,可以切换一下软件demux 或者硬件
demux。切换方式为:setprop libplayer.ts.softdemux 1 为软件demux,setprop libplayer.ts.softdemux 0 为硬件demux。
cat /sys/class/amstream/bufs
Video buffer: flag:7( Alloc Used Parser nofirststamp )
buf addr:0000000020c00000
buf size:0x2800000
buf canusesize:0x2800000
buf regbase:0xc40
buf level:0x65556a
buf space:0x21a9296
buf read pointer:0x20f4f300
buf first_stamp:0xffffffff
buf wcnt:0x1a227
buf max_buffer_delay_ms:0ms
buf current delay:10520ms
buf bitrate latest:85140bps,avg:1545405bps
buf time after last pts:4060 ms
buf time after last write data :4060 ms
Audio buffer: flag:7( Alloc Used Parser nofirststamp )
buf addr:0000000027400000
buf size:0x180000
buf canusesize:0x180000
buf regbase:0x1584
buf level:0x275aa
buf space:0x157256
buf read pointer:0x27413e80
buf first_stamp:0xffffffff
buf wcnt:0x700
buf max_buffer_delay_ms:0ms
buf current delay:10496ms
buf bitrate latest:43680bps,avg:76144bps
buf time after last pts:4060 ms
buf time after last write data :4060 ms
Subtitle buffer: flag:0( Unalloc Noused noParser nofirststamp )
buf addr: (null)
buf size:0x40000
buf canusesize:0x40000
buf start:0x0
buf write pointer:0x0
buf read pointer:0x0
buf level:0x0
buf first_stamp:0xffffffff
buf wcnt:0x0
buf max_buffer_delay_ms:0ms
UserData buffer: flag:0( Unalloc Noused noParser nofirststamp )
buf addr: (null)
buf size:0x0
buf canusesize:0x0
buf regbase:0x0
buf no used.
buf write pointer:0x0
buf read pointer:0x0
buf first_stamp:0xffffffff
buf wcnt:0x0
buf max_buffer_delay_ms:0ms
HEVC buffer: flag:0( Unalloc Noused noParser nofirststamp )
buf addr: (null)
buf size:0x2800000
buf canusesize:0x2800000
buf regbase:0x3102
buf no used.
buf first_stamp:0xffffffff
buf wcnt:0x0
buf max_buffer_delay_ms:0ms
b、同步相关卡顿
查看同步模式,关闭同步,或者关闭声音
cat /sys/class/tsync/mode; 查看同步模式
echo 0 > /sys/class/tsync/enable 关闭同步
setprop media.amplayer.noaudio true disable audio
查看checkin checkou pts
echo 1 > /sys/class/tsync/debug_audio_pts 查看audio pts
echo 1 > /sys/class/tsync/debug_pts_checkin 查看checkin 的pts
echo 1 > /sys/class/tsync/debug_pts_checkout 查看checkout 的pts
echo 1 > /sys/class/tsync/debug_video_pts 查看video pts
a、视频解码出错
这种情况只需要查看kernel 打印即可,如果解码出错会有错误打印。
b、后处理相关卡顿
如果上述情况排除之后,还有可能是后处理模块或者是带宽造成的。
关闭DI:
echo 1 > /sys/module/di/parameters/bypass_all
或者
echo rm default > /sys/class/vfm/map
echo add default decoder ppmgr amvideo > /sys/class/vfm/map
DI 关闭后如果不卡顿,也有可能不是模块本身的问题,有可能是带宽问题。此时需要按照1.4.5 来确认。
关闭PPMGR:
echo rm default > /sys/class/vfm/map
echo add default decoder deinterlace amvideo > /sys/class/vfm/map
通过Underflow 查看:
cat /sys/module/amvideo/parameters/underflow
cat /sys/class/video/freerun_mode
卡顿时看这个值是否一直增长,如果是则是amvideo 前边的节点数据送过来的慢导致的,
c、带宽不足卡顿
提高CPU 频率:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
echo performance > scaling_governor
关闭OSD
echo 1 > /sys/class/graphics/fb0/blank
查看带宽信息
Check P_MMC_MON_CH0_REQ_CNT~P_MMC_MON_ALL_GRANT_CNT in header file.
P_MMC_MON_CTRL3 to set measure duration
P_MMC_MON_CTRL0~P_MMC_MON_CTRL2 to enable channel monitor
P_MMC_MON_CH0_REQ_CNT~P_MMC_MON_CH9_REQ_CNT to read back per channel request/grant
P_MMC_MON_ALL_REQ_CNT and P_MMC_MON_ALL_GRANT_CNT to read whole mmc request/grant
如果出现音视频不同步,先确认如下状态:
同步是否打开:cat /sys/class/tsync/enable
同步的状态:cat /sys/class/tsync/mode
0: vmaster //视频为准,一般这个时候表示音视频不做同步;
1:amaster //以音频作为同步基准;
2:pcrmaster //以独立的系统时间为基准;
查看APTS、PCR、VPTS:
cd /sys/class/tsync/
cat pts_audio pts_pcrscr pts_video
pts 的单位是1/90000,也就是,数值90000 表示一秒,一般比较明显的看到不同步在100ms 左右,也就9000;
如果pts 不对就查看checkin checkout pts。
setprop sys.amplayer.drop_pcm 1
看是否还有不同步出现。
a、查看checkin checkou pts
echo 1 > /sys/class/tsync/debug_audio_pts 查看audio pts
echo 1 > /sys/class/tsync/debug_pts_checkin 查看checkin 的pts
echo 1 > /sys/class/tsync/debug_pts_checkout 查看checkout 的pts
echo 1 > /sys/class/tsync/debug_video_pts 查看video pts
b、确认是audio 还是video 的问题
echo 0 > /sys/class/tsync/enable
对比在PC 上播放该视频,确认是audio 还是video 播放的问题。
如果是audio pts 有问题,一般是pts 计算错误,这个一般出现在音频那边;以为音频pts 计算复杂;
c、设置freerun_mode
echo 1 > /sys/class/video/freerun_mode
看看是否还会不同步。
d、确认音频采样率
这种情况可能是vsync 里面算pcr 有问题。
cat /sys/class/video/frame_rate
VF.fps=0.00 panel fps 50, dur/is: 93,v/s=49.46,inc=1800
panel fps 为输出的刷新率。
v/s 为实时刷新率。
设置控制同步的阀值
最小不同步时间:RW: /sys/class/tsync/av_threshold_min
最大不同步时间:RW:/sys/class/tsync/av_threshold_max
当音视频pts 差距跳入:<min 区间: ?音频或者视频会暂停或者加速同步上;
当音视频pts 差距>min,Max 是,音视频会暂时不强制同步,等待超时60 秒后强制同步;?如果视频和音频差距>max,
同步系统放弃同步处理;
视频抖动、闪烁和锯齿大部分和Deinterlace,RDMA 和VPP 设置相关。
a、确认Deinterlace 模块是否在vfm/map 链里
cat /sys/class/vfm/map
default { decoder(1) ppmgr(1) deinterlace(1) amvideo}
如果default 里面没有deinterlace,执行如下指令添加deinterlace 模块。
echo rm default > /sys/class/vfm/map
echo add default decoder ppmgr deinterlace amvideo > /sys/class/vfm/map
b、确认Deinterlace 模块是否被bypass
播放节目过程中:cat /sys/module/di/parameters/bypass_state
如果为1 则被bypass
那要根据片源的情况,然后查看
cat /sys/module/di/parameters/
bypass_1080p 1080p 片源bypass
bypass_3d 3D 片源是否bypass
bypass_all 强制所有的都bypass
bypass_dynamic 是否动态bypass
bypass_hd 高清片源bypass
bypass_hd_prog 高清逐行片源bypass
bypass_interlace_output I 模式输出的时候所有片源bypass
bypass_prog 逐行片源bypass
看是哪个结点造成di bypass 的。把它设成0 之后,然后再播放,看是否还抖动。
c、开关nr
echo 0/1 >/sys/module/di/parameters/nr2_en
d、查看Deinterlace 模块工作状态
echo state > /sys/class/deinterlace/di0/debug
e、确认送到DI 模块的帧是否是top/bottom 均匀穿插
cat /sys/module/di/parameters/same_field_bot_count
cat /sys/module/di/parameters/same_field_top_count
如果这两个值有一个一直在增加就说明前边解码器解码有问题,此时会出现锯齿。
f、小窗口视频闪烁
cat /sys/module/di/parameters/di_vscale_skip_count_real
是否真实在小窗口情况下
cat /sys/module/di/parameters/di_vscale_skip_count
是否是在小窗口情况下
cat /sys/module/di/parameters/di_vscale_skip_enable
是否enable 小窗口时bypass di
在小窗口出现花屏或者闪烁的时候,还有可能是因为带宽问题。我们现在解决的方式就是在小窗口播放的时候,先抽掉一部分视频帧的线,然后再送到VPP 去显示。通过如下命令可以看一下目前是否有抽线处理:
cat /sys/class/video/video_state
zoom_start_x_lines:0.zoom_end_x_lines:1279.
zoom_start_y_lines:0.zoom_end_y_lines:719.
frame parameters: pic_in_height 720. //标示抽线后的高度
frame parameters: VPP_line_in_length_ 1280.
vscale_skip_count 0. //标示抽线条数
hscale_skip_count 0.
hscale phase step 0x1000000.
vscale phase step 0x1000000.
根据这些状态信息可以确定输入的大小,是否抽线,是否在做scale,是否打开3d 等,一般花屏等问题需要这些信息。如果发现窗口很小,而没有抽线,可以修改如下结点:
cat /sys/module/amvideo/parameters/bypass_ratio
Vpp 的处理能力会根据这个值算出来一个结果,根据结果来判断是否抽线,越大越不容易抽线,越小越容易抽线。
cat /sys/module/rdma/parameters/enable
如果为0,则为关闭
echo 1 > /sys/module/rdma/parameters/enable
看是否还抖动。
网络流遇到各种问题,首先需要Dump 流,确认在本地能否复现问题。Dump 方法如下:
播放在线视频dump 数据
1.创建dump 文件夹mkdir /data/tmp
2.修改temp 文件夹属性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/tmp/pidn_dump_xx.dat 以pidn 开头,可以区分是哪个线程dump 出来的数据。
播放ts 如果开softdemux 后dump 不到ts 流,需要按es 流dump
如果播放APK 用的是MediaCodec 或者OMX 接口来实现的,那只能dump 到ES 数据,dump 接口如下:
media.omx.dumpRecv 是否dump Omx codec 接收到的数据
media.omx.dumpCodec 是否dump Omx codec 往解码buffer 里面写的数据
media.omx.RecvDir 设置dump Omx codec 接收到的数据写到哪个目录
media.omx.CodecDir 设置dump Omx codec 往解码buffer 数据写到哪个目录
media.omx.RecvName 设置dump Omx codec 接收到的数据写到哪个文件里
media.omx.CodecName 设置dump Omx codec 往解码buffer 数据写到哪个文件里
例如:如果需要dump Omx Codec 接收到的数据到/data/tmp/es_aml_recv.0 同时还要dump Omx Codec 往解码buffer
数据到/data/tmp/es_aml_codec.0,对应的设置如下:
setprop media.omx.dumpRecv true
setprop media.omx.dumpCodec true
setprop media.omx.RecvDir /data/tmp
setprop media.omx.CodecDir /data/tmp
setprop media.omx.RecvName es_aml_recv.0
setprop media.omx.CodecName es_aml_codec.0
如果目录不存在记得创建,然后修改目录权限为777。
其次还可以通过抓包来分析数据:
可以通过tcpdump 命令抓包
默认升级包里面没有这个命令,可以从下面编译路径拷贝
out\target\product\xxxref\symbols\system\xbin
用法:
tcpdump -s 0 -w 文件名