众所周知视频在各个领域占有极为重要的地位,安防领域,互联网,医药,教育等等等等。扯淡我就尽量不多扯了,现主要扯安防领域吧,安防领域尤其是视频分析领域,视频质量要求比较苛刻。下面介绍一下场景比较苛刻的图片情况:

1.这种

2.这种

花屏现象,在视频接入解码过程中尤为常见,(比如28181接入,rtsp等等),解码大家都考虑使用ffmpeg进行解码,首先考虑的可能是解码错误直接从解码过程中就把这种错误的帧给干掉,看了好多博客大概也就是这个思想。

1.如果解码错误抛帧。2.如果是I帧从下一个IDR帧开始解码。想法不错当然我也在做了这一部分,具体部分代码示例如下:

//伪代码......
int len = av_parser_parse2(m_h264Parser, m_ctx, &avpkt.data, &avpkt.size, in_buf, in_buf_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);//重要: 如果有解码错误,并且当前帧不是IDR就直接跳过//m_iErrorDeocde 表示是否有解码错误 //m_h264Parser->pict_type != AV_PICTURE_TYPE_I 表示当前帧是否是I帧if (m_iErrorDeocde /*&& m_iLastFrame*/ && m_h264Parser->pict_type != AV_PICTURE_TYPE_I)return 0;in_buf += len;in_buf_size -= len;if(avpkt.size > 0){
#if 0decode_video(m_ctx, m_picture, &avpkt,out_buf,pout,lineSize);m_iLastFrame = (m_h264Parser->pict_type == AV_PICTURE_TYPE_I)?1:0;
#endif
#if 1{ret = avcodec_decode_video2(m_ctx, m_picture, &got_picture, &avpkt);m_iLastFrame = (m_h264Parser->pict_type == AV_PICTURE_TYPE_I) ? 1 : 0;if (ret < 0){printf("damage!!!!!!!!!!");avcodec_flush_buffers(m_ctx);goto finish;}}

到这种情况其实已经过滤掉了很多坏图了,但是想上图展示的两种情况,就像是打不死的小强一下死了又来来了又死,怎么办?

当然前面的两张图你必须得把ffmpeg的错误隐藏给关掉,再就是另一个err_recognition这个东西,看解码那块的源码找到了个这么东西,具体干什么的,自己可以细细研究一下。

观察上面的图都有规律,是什么?对,没错!就是都有灰图,那灰图是怎么来的呢?于是乎我有看了看ffmpeg的h264解码,注意到了一个0x80这么数值,还是在alloc_pic的时候,难道这就是传说中的赋初始值?看着像,具体也没看太明白。。。。

那么那些解码错误的灰色的图块吧,确实的东西是不是就是这个默认值呢?答案差不多,那我是不是就可以把这些看似解码正确的图片其实是花了的图片,直接判断这些坏块再做一遍过滤,剔除掉呢?

这里我补充一些色彩空间的知识,不再赘述了,大概就是Ycbcr经过偏置处理默认值128即0x80,大概就是为了和rgb的0~255在一个范围吧:

https://blog.csdn.net/asahinokawa/article/details/80596655

好了,到这一步骤,基本上就是单纯的过滤有灰块的图了,我的思想是判断这个值,或者这个值范围内的值,那么选择yuv哪个分量做过滤呢?当然是Y了,UV是色彩和饱和度,到了晚上这种值当然就是0x80了,看这张图。

他的末尾全是这玩意,即0x80,这就是我选y的原因,因为他是亮度。。。

我的过滤部分伪代码实现如下:

//只是思想没有做代码的整洁及优化,可以根据自己情况去增加删除代码
bool  CheckY(int iwidth, int iHeight, unsigned char*Buf)
{unsigned char * pNewPoint = Buf;int iCountu = 0, iCountv = 0, iCountY = 0;int iValues = 0;unsigned char uBytes = 0;//定位最后一行YpNewPoint = Buf;//uBytes = pNewPoint[0];//获得新的像素位置pNewPoint = Buf + (iHeight - 8)*iwidth;//遍历Y信息的所有高for (int i = 0; i < 8; i++){unsigned char *pNewPoint2 = pNewPoint + i*iwidth;//遍历Y信息的宽for (int j = 0; j < iwidth; j+=24){int a = memcmp(pNewPoint2 + j, pNewPoint2 + j + 8, 8);int b = memcmp(pNewPoint2 + j + 8, pNewPoint2 + j + 16, 8);//判断连续两个8像素宏块,是否相同,并且在这个值范围内(0x7A~0x80)if (a == b && b == 0 && pNewPoint2[j] > 0x7A&& pNewPoint2[j] <= 0x80){printf("%d%d%d%d%d%d", pNewPoint2[0], pNewPoint2[1], pNewPoint2[2], pNewPoint2[3], pNewPoint2[4], pNewPoint2[5]);iCountY++;}/*if (((unsigned char *)pNewPoint2)[j] == 0x80){printf("uByte=%x,pNewPoint2=%x",uBytes,pNewPoint2[j]);} */}}
}

思想已经说完了,具体实现就看自己了,代码为商业代码,就不能提供了。

H264解码过滤花屏视频帧相关推荐

  1. h264 丢包花屏处理的一个想法

    本文 来自 csdn lidp http://blog.csdn.net/perfectpdl, 转载注明出处,谢谢. H264视频在分组网络中传输丢包不可避免,尤其在网络环境不好时传输h264码流, ...

  2. h264视频解码显示花屏问题集

    1. 收到服务器过来的视频码流,使用stream eye播放正常,使用自己的设备来解码播放时,出现严重的花屏. 原因:码流中有部分帧,如I帧的slice数目过大,大于解码器设定的最大slice数目,解 ...

  3. android软解码花屏,视频花屏 · Issue #386 · bilibili/ijkplayer · GitHub

    @各位大神,还是没法解码 ijkmp_set_format_callback(0x10d5e5, 0x17ec4a20) ijkmp_set_format_callback()=void ijkmp_ ...

  4. ffmpeg h264解码, 屏蔽因为网络丢包等各种原因导致的花屏帧

     ffmpeg h264解码, 屏蔽因为网络丢包等各种原因导致的花屏帧  ---->看来问题只能这样解决了,现在还要多测测,防止产生新的问题.目前来看,对现有代码没有影响,花屏的帧直接屏蔽掉了. ...

  5. FFmpeg花屏解决(修改源码,丢弃不完整帧)

    linux下模拟丢帧的命令,因为帧之间的参考关系,实测如果是1%几乎没有完好的帧. sudo tc qdisc add dev enp0s31f6 root netem loss 0.1% 删除上面的 ...

  6. SkeyePlayer RTSP/RTMP流媒体超低延迟播放器源码解析系列之H264一帧多NAL写MP4录像花屏问题解决方案

    接上一篇[SkeyePlayer源码解析系列之录像写MP4]之续篇,我们来讲解一下关于H264编码格式中的一帧多nal(Network Abstract Layer, 即网络抽象层),关于H264和N ...

  7. 视频编解码 — 卡顿与花屏

    目录 卡顿问题 卡顿问题出现的可能性 1.帧率不够 2.编码出码率超过实际网络带宽 3.网络本身有一定的丢包率 视频花屏 1.帧不完整 2.参考帧不完整,导致花屏 3.YUV格式问题 4.stride ...

  8. ffmpeg 切片花屏_利用ffmpeg解码H264,花屏,该如何解决

    利用ffmpeg解码H264,花屏 UINT CMP4File::VideoCap_Thread_Fun(void* pParam) { CMP4File  *pMP4File=(CMP4File*) ...

  9. 达芬奇在AMD处理器的联想电脑上编辑视频时花屏、卡帧、闪烁的解决方法

    故障描述:达芬奇在使用AMD 4000系列移动端处理器的联想笔记本电脑上处理视频时出现了时间线花屏.修改时间线上的素材后播放时画面卡在两帧以内反复闪烁.画面闪烁黑帧的问题,重装软件.更换版本均无法有效 ...

  10. 视频帧数据用硬件编码输出,仅仅使用FFMPEG将硬件编码出的数据推流RTSP数据后严重花屏且画面卡住不动

    由于使用的是其他硬件编码器出来的数据,所以不再是使用av_read_frame来获取AVPacket包了,所以在输出编码数据的回调接口里写伪代码如下: //相当于初始化AVPacket包 AVPack ...

最新文章

  1. GPS数据转换为OneNet需要的数据
  2. 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编框架 | PyCharm 中导入 Capstone 反汇编框架 )
  3. redis之zskiplist
  4. ERROR: This virtual machine appears to be in use
  5. mysql innodb创建数据文件失败
  6. 解决GitLab中使用SSH的git clone总是提示输入密码且任何密码都不对
  7. spring aop搭建(2) :基于代码的实现
  8. Qt配置VS2017
  9. Apollo进阶课程㉟丨Apollo ROS原理—4
  10. LR学习笔记七 之 LR录制sql脚本
  11. ORACLE的Copy命令和create table,insert into的比较
  12. 批量合并工作簿,包含三种合并方式,Excel技能演示
  13. 微信支付 unmatched order appid and payment appid
  14. CRX 4 Chrome
  15. JavaEclipse中从Lambada表达式运行错误的解决方法到学到新知识
  16. LIO-SAM imuPreintegration
  17. 计算机里找不到读卡器、,读卡器不显示怎么办解决教程
  18. 云计算作者姚宏宇1月26日中关村图书大厦讲座
  19. Matlab基础之矩阵循环
  20. C++11:使用 auto/decltype/result_of使代码可读易维护

热门文章

  1. linux steam安装目录,如何在Linux系统的服务器中安装steamCMD,常用steam游戏安装指令有哪些...
  2. stearm计算机验证码,steam账户名称怎么取,值得收藏
  3. H3CIE(WLAN)学习笔记(4)——PHY层协议
  4. lync 2013标准版安装
  5. win10系统开启扫描仪服务器,win10怎么安装扫描仪 win10扫描仪怎么扫描
  6. 可用性和可靠性的区别
  7. C语言之父丹尼斯·里奇:乔布斯脚下的巨人肩膀
  8. linux ftp prompt off,FTP命令详解及使用技巧
  9. 计算机电路基础张志良,计算机电路基础 第2版
  10. ROS+opencv实践-cv_bridge的使用