视频花屏分析

news/2025/1/11 14:10:13/

1. 前言

视频花屏是多媒体工程师最常见的问题之一,也是最棘手的问题之一,笔者此前也数次遇到这样的问题,今天在此总结分享下经验。

本文分析的重点是视频录制过程中引起的花屏问题,粗浅涉及视频播放。但是其中都不会涉及到编码器或者解码器本身所引起的花屏问题。

本文所用到的测试资源如下图:
这里写图片描述


2. 视频花屏问题定位

当遇到视频花屏时,首先要定位是最先出现的花屏的是哪个阶段产生的花屏。以视频录制为例,其具体流程如下:

这里写图片描述

采集阶段不属于本文分析范畴
通过使用其它播放器播放视频和检验采集到的原始数据这两种手段可以定位到具体的问题。具体步骤如下:

Created with Raphaël 2.1.0 开始 更换播放器是否花屏? 渲染数据是否花屏? 原始数据是否花屏? 采集问题 结束 渲染问题 编码问题 播放解码问题 yes no yes no yes no

3. 视频花屏三种类型

常见视频花屏有一下三种原因造成:

  • 渲染脏数据
  • 丢帧
  • 图像格式转换

3.1 渲染脏数据

渲染脏数据是还为完成渲染的数据。具体来讲就是在视频帧渲染到一半的时候,即被送到编码器编码。
此问题发生在视频渲染阶段。

3.1.1 特征

(1)图像具有明显的撕裂或者错位特征
渲染脏数据造成结果就是该图像一半是当前帧的数据,另一半是上一帧的数据
(2)渲染脏数据通常不会造成持续型的花屏现象
如下图所示,图片中上下存在明显错位的现象。
PS:一般脏数据的渲染结果不一定像下图中那么规则。
这里写图片描述

3.1.2 产生原因与解决方法

以笔者经验产生原因有两类:

  • 通过glReadPixels等类似方法从OpenGL获取数据,在draw和glReadPixels中间没有等待绘制完
    解决方法是:在draw和glReadPixels中间调用glFinish方法

    PS:
    (1)不要滥用glFinish方法,该函数会严重影响渲染效率,如果不是立即从GPU中读取数据的话可采用glFlush代替
    (2)glReadPixels非常非常耗时,建议新建一个新的渲染线程,把数据在新线程中重新渲染一遍,然后调用glReadPixels

  • 如果多个渲染线程通过共享纹理的方式串型工作,确认该纹理在多个线程中工作是否互斥行为。
    如前文提到的开辟一个渲染线程专门进行glReadPixels操作,如果有这样类似的行为尽量采用多缓冲机制

    PS:笔者的经验是当存在多个渲染线程

3.1.3 总结

解决此问题的方法就是等该帧渲染完成后在捕获渲染后的数据,同时需要注意的性能问题。具体方法有多缓冲:
(1)加锁
最简单的方法,但是慎用会影响渲染效率
(2)多缓冲
这是必须的
(3)glFlush/glFinish
笔者的经验是普通绘制完毕后调用glFlush,在glReadPixels方法前调用glFinish。

3.2 丢帧

此处所说丢帧丢弃的是视频编码后的视频帧,通常发生在复用(Mux)阶段。
由于视频编码后帧之间存在依赖关系,丢帧会带来及其严重花屏效果,并且具有持续性影响。
此问题发生在视频编码阶段。

3.2.1 特征

(1)存粹的花屏,且花屏效果没有明显的规则型(比如撕裂、错位)
(2)连续多帧存在花屏现象
如下图所示:
这里写图片描述

3.2.2 产生原因与解决方法

产生原因

  • 视频帧时间戳(PTS)不对
    由于大部分复用器(Muxer)都严格要求视频帧PTS是严格递增的,比如ffmpeg中mp4 Muxer如果当前帧的PTS小于或等于前一帧的PTS,那么该帧就不会被写入文件,ffmpeg会报”Invalid pts”错误。

  • 视频向音频同步引发丢帧

  • 缓冲队列溢出

解决方法
引发此问题的原因众多,具体案例具体分析。关键是确认花屏是由于丢帧引起的,以及什么原因引发的丢帧。
后面介绍几种下视频分析方法,帮助确认丢帧问题。

3.3 图像格式转换

在视频编解码中必然会涉及到YUV和RGB图像格式的转换,并且YUV还有多种格式。如果转换格式或者算法不正确也会引发视频花屏问题。
此问题发生在视频渲染或者播放阶段。

3.3.1 特征

由YUV与RGB图像格式转换引发的花屏现象有很多无法判断,但是有一种情况基本可以判定是由于此原因引发的:
(1)图像的黑白数据是正常的,但是色彩不正常,比如色彩偏色、甚至错乱。
(2)图像整体依然处于可识别的状态,但是存在明显的彩色斑块
如下图所示:
这里写图片描述

3.3.2 产生原因与解决方法

产生原因

  • YUV格式错误
    YUV有很多种格式,任意两种之间都都会造成转换出来的图像存在巨大差异。
  • 图片大小
    给格式转换算法设置的宽高和图像本身存在微小差异。

    比如笔者在Android MTK机型上遇到过,MTK为了做GPU数据对其优化,是得GPU产出的图像分辨率和常规分辨率存在微小差距,最后造成图像色彩混乱,修复后还存在绿边问题,需要特色处理。

  • 图像转换算法
    (1)不同的图像制式对应RGB与YUV转换矩阵不同,其转换的色彩也存在偏差。
    (2)目前大部分采用硬件加速的技术(GPU)实现图像格式转换,不同平台可能存在差异。

解决方法
首先把YUV数据保存下来,然后用专门的工具对其进行转换,查看转换效果,然后做进一步的分析。
YUV240P数据如下图所示:
这里写图片描述

总结:
(1)图像的黑白数据是基本正常的,色彩混乱:
可能是由于错误的图像大小引发,亦可能是由于算法不支持该图像的分辨率引起的
(2)图像整体依然处于可识别的状态,但是存在明显的彩色斑块
基本确认是由于错误地识别YUV格式引起的(我很确定地告诉你,你把YUV420P和NV12搞混了)


4. 视频分析工具与使用

4.1 视频丢帧分析

4.1.1 ffprobe

ffprobe是FFmpeg里面比较重要的一个工具,在此不在多说了。
(1) 获取帧信息
ffprobe -show_frames We_Are_Young.mp4 > frames.info
这里写图片描述
(2)统计I帧数量
keyframe=1 : key frame
pict_type=I : I-frame

cat frames.info | grep “pict_type=I” |wc -l

(3)统计视频帧数量
cat frames.info | grep “media_type=video” |wc -l
ffprobe -show_format -show_streams filename

4.1.2 VideoEye

VideoEye[2]是雷霄骅开发的一款视频分析工具,功能很多,比较强大。
项目主页
SourceForge:https://sourceforge.net/projects/videoeye/
Github:https://github.com/leixiaohua1020/VideoEye
开源中国:http://git.oschina.net/leixiaohua1020/VideoEye

具体操作和介绍参见开源实时视频码流分析软件:VideoEye
下面这张图是视频PTS分析的截图
这里写图片描述

4.2 YUV分析

4.2.1 YUV与RGB格式转换

(1)视频

ffmpeg -i VID20160412102008.mp4 -c:v rawvideo -pix_fmt yuv420p out.yuv

(2)图像

RGB ==> YUV
ffmpeg  -i a.bmp -pix_fmt yuv420p -y a.yuvYUV ==> RGB
ffmpeg -pix_fmt yuv420p -video_size 352x288 -i a.yuv  -y b.bmp

4.2.2 YUV预览

不管用什么工具都必须知道YUV数据的宽高信息,否则无法对YUV数据进行分析。

ffplay

ffplay -f rawvideo -video_size 640x480 test.yuv

mplayer

mplayer name.yuv -demuxer rawvideo -rawvideo w=352:h=288

mpv

mpv VID.yuv --demuxer=rawvideo --demuxer-rawvideo-w=720 --demuxer-rawvideo-h=1280

GLYUVPlay
GLYUVPlay是MAC上一款查看YUV数据的工具,官方网站为 http://bax.comlab.uni-rostock.de/en/projects/glyuvplay/
下面是其截图
这里写图片描述


5. 参考文献

[1] wikipedia YUV
[2] 开源实时视频码流分析软件:VideoEye


http://www.ppmy.cn/news/616732.html

相关文章

【Linux 驱动篇(二)】LED 驱动开发

文章目录 一、Linux 下 LED 灯驱动原理1. 地址映射1.1 ioremap 函数1.2 iounmap 函数 2. I/O 内存访问函数2.1 读操作函数2.2 写操作函数 二、实验程序编写1. LED 灯驱动程序编写2. 编写测试 APP 三、运行测试1. 编译驱动程序和测试 APP1.1 编译驱动程序1.2 编译测试 APP 2. 运…

USRP:UHD多版本卸载

首先输入apt list | grep uhd查看已安装的uhd版本,由于一开始的无知下载了很多个版本 :~$ apt list | grep uhdWARNING: apt does not have a stable CLI interface. Use with caution in scripts.libgnuradio-uhd3.8.1/focal 3.8.1.0~rc1-2build2 amd64 libgnurad…

Hi3516DV300 USB驱动安装

1.裸片(无程序时),先烧录uboot到芯片详细操作看《HiBurn工具使用指南》。烧录好后再uboot界面(终端打印信息如xshell)下 输入usb device会提示“Install USB Device…”信息,这时可以安装USB驱动。 2.非裸片…

USB学习一:uhci ohci ehci三者区别

1.uhci ohci ehci他们都是主机控制器的规格OHCI主要为非PC系统上以及带有SiShe ALi芯片组的PC主板上的USB芯片UHCI大多为Intel和Via主板上的USB控制器芯片。UHCI的硬件电路比OHCI简单,成本第,但驱动复杂。但他们都是由USB1.1规格的。EHCI是有Intel等几…

CM211-2-CH-通刷Hi3798MV300/MV310-当贝纯净桌面-卡刷固件包

CM211-2-CH-通刷Hi3798MV300/MV310-当贝纯净桌面-卡刷固件包-内有教程 特点: 1、适用于对应型号的电视盒子刷机; 2、开放原厂固件屏蔽的市场安装和u盘安装apk; 3、修改dns,三网通用; 4、大量精简内置的…

Pericom PI3HDX414FCEEX HDMI 多路分配器

PI3HDX414FCEEX有源驱动开关解决方案针对基于HDMI/DVI标准和TMDS信号处理的高分辨率视频网络。 PI3HDX414FCEEX是一个有源单TMDS信道到四个TMDS信道分离器和具有Hi-Z输出的DeMux。该设备将差分信号驱动到四个视频显示单元。它提供可控制的输出摆动电平,可通过引脚控…

稚辉君HDMI-MIPI东芝方案(原创,连载中~)

HDMI-MIPI Adaptor 前言 前段时间在哔哩哔哩上看到稚辉君的Pocket LCD项目,感觉很有意思,正好也想要个便携式显示屏,我也来DIY一下~ 主要的流程如下: 方案选择硬件选择软件设计 记录 1. 方案选择 目前不需要充电宝这个功能&…

【海思篇】【Hi3516DV300】三、使用USB烧写映像

目的:实现USB快速烧录,比串口快很多;让更多的爱好者了解海思、加入海思。 目录 1 PC准备工作 2 海思板准备工作 3 工具HiTool开始USB烧写 1 PC准备工作 说明: Hi3516CV300/Hi3559AV100/Hi3556AV100/Hi3519AV100/Hi3516CV500…