Posted on 17-11-2014
Filed Under (技术) by waterlin

今天碰到一个比较有意思的问题,在我本地编译的 release 版本没有任何问题,但是如果我提交到版本库并且从构建系统里构建,则会提示说 protobuf 的头文件有一些未使用的变量,从而生成警告信息。由于我们的构建系统设置是会把警告当成错误来对待,从而抛出一个 4996 的警告,从而构建系统把这个警告当作错误信息,导致版本构建失败。

实在找不出是什么原因导致的这个警告消息,我只把强行用 #pragma 把这个警告消息去掉:

对于代码里的这种莫名其妙的问题,还是使用类似于 #pragma 的方法来处理吧。

(0) Comments    Read More   
Posted on 05-11-2014
Filed Under (技术) by waterlin

今天在使用 FFMpeg 解码 iPad 过来的视频流时,有一个非常奇怪的现象,即对于分辨率为 406*720 和 450*720 的图像来说,解码一切正常,但是把 YUV420 的数据转为 RGBA 显示出来时,图像的最右边会有一条几个像素的黑竖条,如下图所示:

./images/ffmpeg-black-bar2.jpg

碰到这个问题,通常的解决思路如下。

第一,检查一下解码是否有错误,这个好办,只要解码不返回错误码就是正常。

第二,如果解码没有问题的话,仔细查看各步的图片格式转化操作是否有问题。

1. 先看看解码出来的 yuv 数据是否就有这条黑边。可以直接把 yuv 保存成二进制文件,然后用 yuvplayer 播放。

如果是使用 FFMpeg 解码,则可以使用如下的代码来保存 yuv (平面格式)数据:

在我这里有一个特别奇怪的现象,分辨是 540*720,但是解码后得到的 YUV 的 stridesize 是: 576, 288, 288。经过查找资料,原来为了方便各种格式转换及效率,通常是把分辨率的宽度进行了 16 倍整数化,方便硬件加速。

在我查看了 yuv 图片后,还是一切正常,真是怪事,只能继续找原因了。

2. 既然 yuv 数据没有黑边,则把 sws_scale 转成 BGRA 数据后的图片保存成位图,看是否有黑边。

可以使用如下的代码来保存 BGRA 的数据:

如果使用了 Qt 库,也可以直接这样保存图片:

在我这里,恰恰是第2步使用 sws_scale 转换图片格式后出现的黑边。我原来 sws_scale 的使用方法如下:

事实上问题就出在这里,是 sws_getContext 这个函数的参数需要带上 SWS_ACCURATE_RND,即修改成如下方式:

但是加了这个参数后,运算速度就变得巨慢了。

有一个更好的解决办法,就是在解码后把图片的 yuv 格式转成 BGRA 格式之前,先考虑一下设置 RGBA 格式的图像的宽度是 16 的倍数:

这样在你以后用 sws_scale 时就可以直接使用 dst_w 这样的16的倍数来进行操作。这样,黑边的问题就解决了,黑边得到了裁剪,并且并不会耗费大量的计算时间,不过缺点是图像的分辨率也变小了。*最佳的解决办法,是在压缩流的输出端就保证分辨率的宽度值是 16 的整数倍*。

PS:我这里碰到这个问题,有可能是因为使用的 FFMpeg 库被修改过,用 SSE4 加速了 rgb 到 yuv420 的转换操作。原版的 FFMpeg 在这些奇怪的分辨率下是否会是如此,我没有验证。

(0) Comments    Read More