最近在做一个基于udp的屏幕广播项目时,遇到如下的问题:
在进行屏幕广播时,出现接收到的ffmpeg编码没有显示错误信息的h264数据,然后mediacodec在硬解码这些数据时,发现会偶尔有一两帧的数据会硬解码失败,因此导致视频会出现马赛克。
其实对于这个问题,我一开始是想着为什么会出现解码失败的呢?自己想了之后可能会有如下几个原因:
1、可能是UDP发包和收包过程中存在丢包的现象。
2、有可能是由于UDP发包时和接收到包的顺序出现不相同的情况了,导致数据有异常。
接着我就开始验证是不是这两个原因中的一个导致解码出错了,结果如下:
1、我在发的包中增加的顺序编号,以及每个包的大小信息
2、当我在接收端打印解码失败信息时,发现解码失败的包接收到和拼起来的顺序都没有错误,以及没有出现丢包的情况。
从上面的情况发现可以排除了丢包和收包拼包顺序紊乱的问题,这下可真的暂时还没有找到为何mediacodec还是会出现解码失败的情况。
==============================================================
我写这篇文章的目的当然不是告诉大家我还没搞清楚为何会失败而引起马赛克,而是要告诉大家,其实有时候遇到问题时,或许解决它的办法或者钥匙并在这个问题身上:
当我百思不得其解时,发现如果是mediacodec硬解码正确的数据还是会偶尔出错,那也没办法,目前又修改不了它底层的代码,那只能从另外的角度去思考解决它。
===============================================================
之所以会出现马赛克,虽然是由于解码失败导致后一帧无法根据正确的前一帧解码出正确的数据导致出现马赛克,那换个角度想想,如果能够尽可能减少这种马赛克的影响是不是就可以解决问题了呢?想到这因此有了如下的大胆构想:
1、减少gop_size至一个可以接受的合理范围,因为如果减少gop_size的话可以减少某一帧对正一组数据的影响。
2、增大码率或者减少q_min值,这样让画质更加细腻,即即使出现马赛克,每一个马赛克的块大小也会更小,更加难看出来。
根据上面这上面的两个大胆假设进行修改代码,我做出了如下改动:
1、码率由8M增加到10M
2、gop_size由原来的25减少至10(或者5)
经过上面的修复发现,原本的马赛克居然能够显得根本看不见了。
如果你看到了最后,谢谢你的阅读,但我最想说的其实不仅仅是解决这个问题的办法,而是想说明有时候解决问题的办法可能并不在问题本身,而在其他地方。