FFMpeg笔记(五) 录制小视频时几个问题解决

Stella981
• 阅读 1108

1. YUV数据在使用avfilter scale时在特定的分辨率下UV分量不对

由于是小视频,那么分辨率不需要太高,但是有的视频源是1080p,甚至有的是4K的,所以对视频源进行scale非常有必要。scale操作可以使用avfilter或者sws_scale完成,具体参考:

在对视频数据进行decode后,得到了包含YUV数据的AVFrame,AVFrame中的data[0], data[1], data[2]分别表示YUV三个分量,YUV三个分量的数据量之比是4:1:1,每行的字节数分别是linesize[0], linesize[1], linesize[2]。

假定图像长宽分别为w和h,那么Y分量字节数为w*h,linesize[0]等于w,U/V分量字节数均为0.5w*0.5h,linesize[1]等于linesize[2]等于0.5w。但是实际使用时发现,特定分辨率下scale后的UV分量显示不正常,进一步发现UV的linesize有时不等于0.5w,对此FFMpeg(avframe.h)是这么解释的:

     * @note The linesize may be larger than the size of usable data -- there
     * may be extra padding present for performance reasons.
     */
    int linesize[AV_NUM_DATA_POINTERS];

实际上确实发现UV分量的linesize不等于0.5w,这样的话,在拷贝UV分量的时候,就需要一行一行拷贝,每行拷贝0.5w,这个问题也就解决了。

Tips:Mac下使用GLYUVPlay.app软件,导入原始的YUV数据,输入分辨率,YUV格式等信息,可以查看原始YUV数据的分量信息,对于解决问题非常有帮助。

2. PCM在使用FFMpeg的aac编码器编码时提示编码失败

在特定的手机上,aac会编码失败,提示的是"Input contains (near) NaN/+-Inf\n"。但是很奇怪,只在特定的手机出现该问题,查了半天没有结果,看到有人说libfdk-aac库可能会解决这个问题,将fdk-aac添加进FFMpeg后,编码没有问题,但是编码出来后的数据有爆音,使用Audacity软件查看dump下的数据,确实有爆音,也就是说程序还是有问题。仔细审代码最后发现,aac编码输入的PCM数据只有一个声道的,而编码参数里写的输入为两个声道,而第二个声道的数据没有赋值,将第二个声道拷贝了输入数据后,问题就解决了。。

总结一下,不是所有的手机都没问题,那就证明程序还是有问题。

Tips:Mac下使用Audacity软件,输入原始PCM数据的采样率、音频数据格式后,可以查看原始PCM数据波形,有无爆音等问题。

3. 视频尺寸裁切不生效

视频尺寸裁切时,用libavfilter的crop参数,我之前的理解,av_buffersink_get_frame出来的frame数据就变成了裁切后的尺寸,后来发现不是这样。av_buffersink_get_frame后的frame只是width, height变成了裁切尺寸的长宽,data[]指针和linesize大小都没有变。debug发现,frame的crop相关参数变了,在重新编码时,就会根据crop参数和width, height参数编码成裁切后的尺寸。

 4. 录制GIF时花屏

    按照录制视频的代码去录制GIF时发现录制后的GIF花屏,查阅资料可以,GIF的out format必须是AV_PIX_FMT_RGB8,把pixel_format改成RGB8后就OK了。

5. 对带有HE-AAC的视频编码失败

    之前一直以为服务器的视频都是LC-AAC格式的,这种格式的采样样本数nb_samples是1024个,而HE-AAC视频的nb_samples是2048个,并且FFmpeg自带的aac编码器只支持LC-AAC编码。于是不得已,只能换为fdk-aac编码器,根据文档,fdk-aac编码器两种格式的aac都支持。但是fdk-aac编码器只支持S16格式的PCM,因此对解码后得到的PCM又加了一层resample,将原来FLTP格式的PCM resample成S16格式,之后编码成功。附FFmpeg支持的音频编码器信息:

Dolby Digital: ac3
Dolby Digital Plus: eac3
MP2: libtwolame, mp2
Windows Media Audio 1: wmav1
Windows Media Audio 2: wmav2
AAC LC: libfdk_aac, aac
HE-AAC: libfdk_aac
Vorbis: libvorbis, vorbis
MP3: libmp3lame, libshine
Opus: libopus

6. 编码后视频前几帧黑屏

    原因是开启了多线程编码,但是单线程编码效率很低,这个问题还需要细研究一下。

参考资料:

1. FFMpeg学习(三) 音频处理基本概念

2. FFMpeg学习(六) 用libavfilter对视频尺寸进行裁切

3. https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这