织梦CMS - 轻松建站从此开始!

罗索

ffmpeg图象倒置

jackyhwei 发布于 2011-12-05 09:31 点击:次 
我在用FFMPEG 开发在DirectShow 环境下生成FLV的筛选器(Filter)的时候,碰到了一个比较古怪的问题。因为该筛选器的输入格式需要支持常见的RGB,和YUV格式。但是在输入是RGB格式的时候,最终生成的视频图像是翻转的。而用YUV格式确实没有问题的。
TAG:

我在用FFMPEG 开发在DirectShow 环境下生成FLV的筛选器(Filter)的时候,碰到了一个比较古怪的问题。因为该筛选器的输入格式需要支持常见的RGB,和YUV格式。但是在输入是RGB格式的时候,最终生成的视频图像是翻转的。而用YUV格式确实没有问题的。

分析了一下程序,因为ffmpeg支持的最终存入FLV的格式是YUV420P,需要调用sws_scale进行图像的格式转换,应该是调用sws_scale进行图像格式转换的时候发生的图像反转。虽然问题很显然,但是却一直找不到好的办法,这个问题困扰了好久,也查看了ffmpeg的源代码。本想也一段代码,先把RGB格式的图像先手工做一次反转,再通过sws_scale进行处理,那样负负得正正好解决问题,当然实现这样的反转代码也比较简单,稍微花点时间就可以搞定。但是进行编解码处理的程序关键是性能,这样处理,因为图像反转操作,白白损失了大量的CPU。后来发现其实,有一个非常巧妙的方法可以解决这个问题。或许ffmpeg在开发的时候,他们早已考虑到了这个问题,已经预留了这个后门了。

办法是这样的:

先看看sws_scale的函数定义

int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[],
              int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])

其中src和srcStride定义了输入图像的四个平面的数据起始指针和四个平面中每一行包含的像素的个数。

dst和dstStride是输出变量,定义的是输出图像的四个平面的数据起始指针和四个平面包含的数据的大小。

为什么一个图像有四个平面,可以找一下YUV格式的一些详细介绍就可以明白。

当然,RGB格式是按照紧凑格式进行编码的,因此只有一个平面,也就是说只要设置src[0]就可以,src[1],src[2],src[3]都为NULL。

我们就在设置src[0]和srcStride[0]的地方做文章。

按照一般处理src[0]和srcStride[0]分别设置为起始图像数据的开始和图像每一行的像素个数。

那如果把src[0] 设置为 width * ( height - 1)    srcStride[0] = -height 结果会如何呢?是不是就会把图像倒过来呢?

实际确实如此。进行图像倒置的操作尽然如此简单。这样避免了人为再添加一次图像的反转操作,提高了编码的性能。

如果图像格式是YUV420,可以这样实现图像翻转:
picture->data[0] += picture->linesize[0] * (height - 1);
                     picture->linesize[0] *= -1;                    
                     picture->data[1] += picture->linesize[1] * (height / 2 - 1);
                     picture->linesize[1] *= -1;
                     picture->data[2] += picture->linesize[2] * (height / 2 - 1);
                     picture->linesize[2] *= -1;
 

(zorru)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201112/15405.html]
本文出处:hi.baidu.com/zorru 作者:zorru 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容