FFmpeg AVFrame变量的YUV Frame旋转

最近在用FFmpeg和DShow框架交互,在Frame的层面处理一些数据。

需要从DShow FIlter获取数据,然后用buffer初始化AVFrame,再交给FFmpeg的Filter处理。

我在Dshow Filter上做了输入输出格式的兼容处理,支持输入输出IYUV、YV12、NV12、RGB24、RGB32等五种格式。(其中RGB24格式的输入还是有点问题,做sws_scale转换的时候,会报内存读写错误,但偶尔却可以正常通过)

这个时候会发现,ffmpeg下用buffer初始化AVFrame数据的时候,如果是RGB色系的,会发生一些问题。

1.RGB24:上下颠倒、色差

2.RGB32:上下颠倒

对于DShow中的RGB24,FFmpeg实际应该用BGR24初始化AVFrame。否则输出的buffer数据使用RGB24色彩空间读取,会发生明显的色彩偏差。

对于所有RGB色彩,FFmpeg直接取出,都会发现图像是“上下颠倒”


我在做DShow交互的时候发现,如果输入输出都是RGB色彩空间,排除色差的问题(使用BGR24就解决了),“上下颠倒”的问题就不会产生。

因此,如何对于输入输出仅有一方是RGB色系的颠倒现象进行纠正,同时不过多的影响时间复杂度,是最主要需要解决的问题。

这篇博文,主要是借这个问题,描述一下如何在ffmpeg里面进行图像颠倒操作。


在面临需要进行图像旋转、反转操作的时候,通常还需要兼顾效率问题(时间复杂度、空间复杂度)。

如果不需要考虑上述问题,那么进行一次O(n)的逐字节拷贝,完全可以解决任意的旋转、反转问题。

不过,既然FFmpeg会存在RGB的倒转问题,那么就一定有可以高速便捷处理的办法。


首先,分析一下问题。存在使RGB发生倒转现象的操作,应该是av_image_fill_arrays填充Frame的操作。但同时也注意到,如果使用了sws_scale发生从RGB——YUV——RGB的时候,翻转就正常了。

因此,我尝试借助ffmpeg现成的函数进行一些高效的处理:

1.进行两次av_image_fill_arrays

2.进行两次sws_scale,获得正常的YUV

然而上述的操作全部都失败了


后来,经过不懈的查找,发现仅需要修改AVFrame的linesize属性,就可以让AVFrame在ffmpeg中的处理被视为图像反转。

    //关键是这一步,上下翻转图像
    pFrame_->data[0] += pFrame_->linesize[0] * (codec_->height - 1);
    pFrame_->linesize[0] = -pFrame_->linesize[0];
    pFrame_->data[1]+= pFrame_->linesize[1] * (codec_->height / 2 - 1);
    pFrame_->linesize[1] = -pFrame_->linesize[1];
    pFrame_->data[2] += pFrame_->linesize[2]* (codec_->height / 2 - 1);
    pFrame_->linesize[2] = -pFrame_->linesize[2];

   //图像翻转完之后回到正常的读写步骤     
    length = av_image_copy_to_buffer((unsigned char*)vopBuf, 640*480*4,
                                                (const uint8_t* const *)pFrame_->data, (const int*) pFrame_->linesize,
                                                codec_->pix_fmt, codec_->width, codec_->height, 1);


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值