ffmpeg编解码视频导致噪声增大的一种解决方法
一、前言
ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了。公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理。然而,在观察编码后的视频质量时,发现图像帧出现了较为明显噪声,类似于水面波纹一般散发开来,在运动场景下尤为明显。初步怀疑应该是码率太低导致的画面失真。于是增大码率重新编码一次,噪声仍然很明显。基本上可以排除是码率太低的问题。
仔细观察原片,也可发现有类似的图像噪声出现,但是微乎其微到几乎不可察觉。于是再次怀疑是ffmpeg在编解码的过程中,将这个噪声放大了,导致最终产出的视频出现了明显的噪声干扰。而代码中我们正好用了ffmpeg实现的swscale()方法。在正式编码之前,我们需要用该方法将YUV数据转换为RGB数据来处理。因此,此处调用正是症结所在。
二、解决方案
前面说了,在正式编码之前我们需要将YUV数据转换为RGB来渲染。既然是swscale()方法的原因,那么是否可以在渲染的时候通过多重采样来降低图形噪声呢?事实上还是too young too simple。开启多重采样还是没有卵用。我们的渲染库又必须采用RGB格式的数据,难道不用swscale()方法么?是否有替代品呢?
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
ffmpeg编解码视频导致噪声增大的一种解决方法的更多相关文章
- FFmpeg编解码处理2-编解码API详解
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584925.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
- ffmpeg 编解码详细过程
ffmpeg编解码详细过程 bobbypollo 转:ffmpeg编解码详细过程 原文地址:ffmpeg编解码详细过程(转)作者:心在飞翔原文出处: http://www.360doc.com ...
- FFmpeg编解码处理3-视频编码
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584937.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
- FFmpeg编解码处理1-转码全流程简介
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584901.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
- FFmpeg编解码处理4-音频编码
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584948.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
- 最近在研究FFmpeg编解码
好几年没上CNBLOGS了, 最近在研究FFmpeg编解码,一个人研究感到很寂寞,所以想通过博客来和大家分享和交流,呵呵. 最近研究的主题是: ANDROID手机同屏技术: 需要用到ANDROID截屏 ...
- BootStrap Validator 版本差异问题导致的submitHandler失效问题的解决方法
最近一直在做互金平台,做到后台提交表单的时候出现验证提交数据一直没有提交的问题.于是百度了一下.果然是版本问题造成的.幸好找到了问题所在.我一直仿照的是东钿原微信平台的做法,但是使用byond的后台框 ...
- [转]权限问题导致Nginx 403 Forbidden错误的解决方法
权限问题导致Nginx 403 Forbidden错误的解决方法 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-08-22 这篇文章主要介绍了权限问题导致Nginx 403 F ...
- eclipse上一次没有正确关闭,导致启动的时候卡死错误解决方法
关于 eclipse启动卡死的问题(eclipse上一次没有正确关闭,导致启动的时候卡死错误解决方法),自己常用的解决方法: 方案一(推荐使用,如果没有这个文件,就使用方案二): 到<works ...
随机推荐
- Could not open input file: composer.phar
Yii 2官网推荐用Composer安装框架,但是在本地出错:Could not open input file: composer.phar.后来修改了命令行就ok了,难道是我装的Composer跟 ...
- 1、AngularJS 验证
1.formName.inputFieldName.property($pristine(未修改).$dirty(修改过的).$valid(合法).$invalid(非法).$error(当前表单所有 ...
- 用window的onload事件,窗体加载完毕的时候
<script type="text/javascript"> //用window的onload事件,窗体加载完毕的时候 window.onload=function( ...
- [leetcode-561-Array Partition I]
Given an array of 2n integers, your task is to group these integers into n pairs of integer,say (a1, ...
- 4.jsp的内置对象
1.jsp有九大内置对象 out request response session application page pagecontext exception config 2.用户发请求 requ ...
- Java内部类与final关键字详解
一.内部类的几种创建方法: 1.成员内部类 class Outer{ private int i = 1; class Inner{ public void fun() {System.out.pri ...
- 使用python操作mysql数据库
这是我之前使用mysql时用到的一些库及开发的工具,这里记录下,也方便我查阅. python版本: 2.7.13 mysql版本: 5.5.36 几个python库 1.mysql-connector ...
- log 的 debug()、 error()、 info()方法的区别
软件中总免不了要使用诸如 Log4net, Log4j, Tracer 等东东来写日志,不管用什么,这些东东大多是大同小异的,一般都提供了这样5个日志级别: × Debug × Info ...
- Java 9 揭秘(10. 模块API)
Tips 做一个终身学习的人. 在本章节中,主要介绍以下内容: 什么是模块 API 如何在程序中表示模块和模块描述 如何读取程序中的模块描述 如何表示模块的版本 如何使用Module和ModuleDe ...
- 通过ALM OTA API获取test case的信息,并上传测试结果到test set中
ALM提供了OTA接口,可以用来获取和上传测试数据到ALM.比如获取Test case的step信息.上传测试结果到test instance. 在ALM的Help中可以下载相关文档,这里以ALM11 ...