FFMPEG解码优化,过滤绿屏,灰屏问题

7 篇文章 0 订阅

项目中对接gb28181码流,总会遇到一些流,在播放的时候出现绿屏或者灰屏的情况,造成这种情况的原因很多,网络丢包,乱序等等,也有可能码流本身就有问题,所以也是在网上找了很多资料目前参考两篇文章比较有参考价值.

https://blog.csdn.net/huangyifei_1111/article/details/97263485?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-13.control&dist_request_id=c6843e25-10e9-4055-b029-dfe726ae0127&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-13.control

https://blog.csdn.net/huangyifei_1111/article/details/103196797

主要两点一个是设置解码错误验证

m_pCodecCtx->err_recognition|=AV_EF_EXPLODE;
    

pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id);  

设置该标记后,如果解码校验失败则会在avcodec_decode_video2的时候返回失败,这样就可以不去解码错误的码流,这个可以过滤部分花屏的码流,但是灰屏和绿屏还是不能解决,

这时候就需要特殊的处理,处理原理就是根据灰屏和绿屏的特征,根据像素的颜色判断,整个图像有多少位灰色或者绿色,就认为该图像无效

主要代码

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;
 
    //定位最后一行Y
    pNewPoint = 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 (a == b && b == 0 && pNewPoint2[j] == 0x00)//判断绿屏
            {
                printf("%d%d%d%d%d%d", pNewPoint2[0], pNewPoint2[1], pNewPoint2[2], pNewPoint2[3], pNewPoint2[4], pNewPoint2[5]);
                iCountY++;
            }
        }
    }
    if(iCountY>100)
        return false;

    return true;

}

使用方式

bool bRes = CheckY(m_pCodecCtx->height,m_pCodecCtx->height,m_pFrame->data[0]);

 if(!bRes)
   {
            printf("灰屏或者绿屏不显示");
            avcodec_flush_buffers(m_pCodecCtx);
            return FALSE;
   }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值