zoukankan      html  css  js  c++  java
  • ffmpeg编解码视频导致噪声增大的一种解决方法

    一、前言

           ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了。公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理。然而,在观察编码后的视频质量时,发现图像帧出现了较为明显噪声,类似于水面波纹一般散发开来,在运动场景下尤为明显。初步怀疑应该是码率太低导致的画面失真。于是增大码率重新编码一次,噪声仍然很明显。基本上可以排除是码率太低的问题。

           仔细观察原片,也可发现有类似的图像噪声出现,但是微乎其微到几乎不可察觉。于是再次怀疑是ffmpeg在编解码的过程中,将这个噪声放大了,导致最终产出的视频出现了明显的噪声干扰。而代码中我们正好用了ffmpeg实现的swscale()方法。在正式编码之前,我们需要用该方法将YUV数据转换为RGB数据来处理。因此,此处调用正是症结所在。

    二、解决方案

          前面说了,在正式编码之前我们需要将YUV数据转换为RGB来渲染。既然是swscale()方法的原因,那么是否可以在渲染的时候通过多重采样来降低图形噪声呢?事实上还是too young too simple。开启多重采样还是没有卵用。我们的渲染库又必须采用RGB格式的数据,难道不用swscale()方法么?是否有替代品呢?

          这么一搜索还真有!google开源的libyuv库正是这样一个替代品,可以用于在RGB和YUV之间进行转换:
    libyuv is an open source project that includes YUV scaling and conversion functionality.

          于是马上下载下来进行测试。

    git clone https://chromium.googlesource.com/libyuv/libyuv
    

      网上关于libyuv的资料貌似比较少,官方也没看到什么文档。好在项目也不大,把头文件看一看,基本上可以了解具体的使用方法的。使用CMake生成VS编译工程,可以产出静态库和动态库两种类型:

          使用实例:

          

    // yuv420p -> bgr24
    if (mOutputFormat == AV_PIX_FMT_BGR24)
    {
    	I420ToRGB24(src_frame->data[0], 
    		src_frame->linesize[0], 
    		src_frame->data[1], 
    		src_frame->linesize[1], 
    		src_frame->data[2], 
    		src_frame->linesize[2],
    		scale_frame->data[0],
    		mOutputWidth*3,
    		mOutputWidth,
    		mOutputHeight);
    }
    // bgr24 -> yuv420p
    else if (mOutputFormat == AV_PIX_FMT_YUV420P)
    {
    	RGB24ToI420(src_frame->data[0],
    		src_frame->linesize[0],
    		scale_frame->data[0],
    		scale_frame->linesize[0],
    		scale_frame->data[1],
    		scale_frame->linesize[1],
    		scale_frame->data[2],
    		scale_frame->linesize[2],
    		mOutputWidth,
    		mOutputHeight);
    }
    else { 
    	return false;
    }
    

      接口非常简洁明了。编码的视频效果对比如下(上图是libyuv实现,下图是ffmpeg的swscale实现):

          可以看出来,下图有类似于水面波纹一样的噪声,而上图则几乎不可见。

    三、参考链接

    1. https://trac.ffmpeg.org/wiki/HWAccelIntro

  • 相关阅读:
    数据库日志文件太大的解决方法及原理
    邮件发送组件
    DataConnectionDialog 旧事重提
    从LINQ实例解析LINQ的另类用法,解决多条件组合问题
    重开BLOG.
    找个搜索结果总数原来可以用到这么多的技术
    Discuz3.2与Java 项目整合单点登陆
    一点感触
    Java 处理word文档后在前端展示
    大数据: 完全分布式Hadoop集群HBase安装
  • 原文地址:https://www.cnblogs.com/csuftzzk/p/libyuv_swscale_ffmpeg.html
Copyright © 2011-2022 走看看