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

  • 相关阅读:
    octotree神器 For Github and GitLab 火狐插件
    实用篇如何使用github(本地、远程)满足基本需求
    PPA(Personal Package Archives)简介、兴起、使用
    Sourse Insight使用过程中的常使用功能简介
    Sourse Insight使用教程及常见的问题解决办法
    github 遇到Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts问题解决
    二叉查找树的C语言实现(一)
    初识内核链表
    container_of 和 offsetof 宏详解
    用双向链表实现一个栈
  • 原文地址:https://www.cnblogs.com/csuftzzk/p/libyuv_swscale_ffmpeg.html
Copyright © 2011-2022 走看看