FFmpeg的入门

引言H264编码使用

VideoToolbox硬编码录制H264视频

从iOS8开始,苹果将VideoToolbox.framework开放了出来,使开发者可以使用iOS设备内置的硬件设备来进行视频的编码和解码工作。硬件编解码的好处是,复杂的计算由专门的硬件电路完成,往往比使用cpu计算更高效,速度更快,功耗也更低。

VideoToolbox 工作流程大致为:

创建Session ->设置编码相关参数 ->开始编码

—> 循环输入源数据(yuv类型的数据,直接从摄像头获取)

—> 获取编码后的h264数据

结束编码

以下为详细代码,内有详细注释,完整工程在文章末尾。


编码保存的h264数据保存到Document目录下,在Info.plist文件中添加Application supports iTunes file sharing ,并设置为YES,即可通过iTunes直接导出来,然后使用VLC播放器即可直接播放。 

正文H.265编码格式

视频流媒体中程中视频数据的传输占据了绝大部分的带宽,如何提升编码效率,使用更少的带宽,提供更优质的画面质量,是音视频开发人员一直努力的重点。HEVC(High Efficiency Video Coding,也叫H.265)编码格式的推出,给这一方向带来了突破点,但由于其算法复杂度较高,前期未曾得到普遍应用,而随着移动设备计算能力的提高和越来越多的设备开始支持HEVC的硬件编/解码,直播平台也开始逐渐引入HEVC视频格式。

HEVC属视频编码层面标准,如果在视频流媒体中进行应用,还需要相应的封装格式和流媒体协议的支持。鉴于直播的大部分推拉流协议是基于RTMP的,本文主要介绍如何在RTMP协议中增加对HEVC视频编码格式的支持,其他协议或私有协议,

1. 背景介绍

典型的直播框架通常包括三大部分,如下图所示:

1. 推流端:负责音视频数据的采集、处理、编码及封装后将数据推送至源站;

2. 服务端:涵盖源站和CDN,接收来自推流端的音视频数据,然后将数据分发至各播放端;

3. 播放端:从CDN拉取直播数据,解复用、解码后渲染音视频数据;

图1. 直播框架图

引入HEVC编码,涉及到的变动部分如上图中红色字体所标注:

1. 编码模块:需要支持HEVC格式的编解码,该部分不属于本文的介绍范畴,我们有在其它文章中介绍如何在iOS11上进行HEVC的硬编硬解,感兴趣的朋友可自行查阅;

4. 封装/传输模块:RTMP、HTTP-FLV流媒体协议需要增加对HEVC视频编码格式的支持,该部分是本文介绍的重点。

相信广大的音视频开发者对于FFmpeg并不陌生,由于它在多媒体处理上提供的强大功能以及开源易于修改维护的特性,使得其被广泛应用于各音视频相关软件中。官方FFmpeg中,并没有对RTMP/FLV中进行HEVC的相关扩展,我们基于此作出了修改。本文后面介绍的就是如何在FFmpeg中,对RTMP进行HEVC扩展。如果您的开发工程中并没有用到FFmpeg,可直接阅读第四章节,也能够很轻松的在您的代码中增加这部分内容。

本文我们会着重介绍如果在iOS11上使用系统API进行265硬编硬解功能,读者需要有使用VideoToolBox进行H.264硬编/解码的相关经验。

一、什么是HEVC(H.265)

HEVC全称High Efficiency Video Coding(高效率视频编码),是比H.264更加优秀的一种视频压缩标准(也称为H.265)。HEVC在低码率视频压缩上,提升质量、减少容量和节省带宽方面都有突出表现,因此除了拍摄占用的容量减少外,在视频通话时也能更加流畅清晰。据9to5Mac的测试结果,原来的H.264标准需要需要60MB才能达到的画质,HEVC仅需要33MB。从下图的压缩效果可以看出,HEVC的压缩算法更加智能,虽然图片细节丢失的情况更高,但是却不会严重影响视频的画质。


H.264与H.265的压缩效果对比.png

需要注意的是,H.265的硬编/解功能,并不是ios的所有设备升级到新系统上都可以使用,目前苹果公布可使用HEVC编/解码的移动设备要求如下:

iOS 11 HEVC Encode


H.265硬编.png

iOS 11 HEVC Decode


H.265硬解.png

二、VideoToolBox编码

使用VideoToolBox进行H.264和H.265编码的流程完全相同,只在创建和配置编码器上存在少量差异,下面以VideoToolBox的编码流程为线索,说明使用两种编码格式时的区别。

1. 创建VTCompressionSession



如果使用H.264编码功能,参数codecType需要设置为kCMVideoCodecType_H264;

如果使用H.265编码功能,参数codecType需要设置为kCMVideoCodecType_HEVC;

其他参数在使用两种编码格式时没有区别。

2. 设置编码相关参数


3. 启动编码



4. 循环输入源数据(yuv类型)


5. 获取编码后的数据

通过在创建VTCompressionSession传入回调函数,获取编码后的数据。


至此针对使用VideoToolBox进行H.264/H.265编码的基本流程已经介绍完毕。

三、VideoToolBox解码

VideoToolBox的解码主要涉及以下几个函数:

VTDecompressionSessionCreate 创建解码session

VTDecompressionSessionDecodeFrame 解码一个frame

VTDecompressionSessionInvalidate 销毁解码session

其中VTDecompressionSessionCreate创建session时需要CMVideoFormatDescriptionRef类型的视频格式描述,而对于CMVideoFormatDescriptionRef,VideoToolBox中提供了多个方法可以创建:

CMVideoFormatDescriptionCreateCMVideoFormatDescriptionCreateForImageBufferCMVideoFormatDescriptionCreateFromH264ParameterSets

在iOS11中新增了一个方法:

CMVideoFormatDescriptionCreateFromHEVCParameterSets

用以创建H.265视频格式的描述。

对于H.264和H.265的解码,在VideoToolBox层面的操作完全一致,唯一不同的就是视频格式的描述类型不同。最常使用也最容易理解的为后两个通过ParameterSets来创建的函数,前两个函数的创建方式未作详细了解。

至此,对使用VideoToolBox解码H.265视频的重点就放在如何获取ParameterSets(即VPS、SPS和PPS)上。

3.1 H.265 NALU类型

同H.264一样,H.265数据也是以NALU的形式组织起来,区别在于H.264的NALU Header为一个字节,而H.265的为两个字节,其结构如下:


H265 nalu header

所以,H.265编码格式的NALU类型判断方式如下,code为NALU Header的第一个字节:

int type = (code &0x7E)>>1;

其中type类型为32、33、34的NALU分别为VPS、SPS和PPS,其他类型参见H.265规范《T-REC-H.265-201304-I!!PDF-E》。

3.2 HEVCDecoderConfigurationRecord

使用ffmpeg读取MP4文件后,视频的AVCodecContext结构的extradata存储的即为包含有SPS、PPS信息的数据结构。

对于H.264格式的视频来说,为AVCDecoderConfigurationRecord,该结构在标准文档《ISO-14496-15 AVC file format》中有详细说明。

对于H.265格式的视频来说,为HEVCDecoderConfigurationRecord,此结构的定义目前未找到官方的定义,参考https://lists.matroska.org/pipermail/matroska-devel/2013-September/004567.html及ffmpeg中hevc.c文件中的实现,该结构详细如下:


其中最后的nalUnit存储的即为VPS、SPS和PPS信息。

获取到VPS、SPS和PPS之后,就可以通过

CMVideoFormatDescriptionCreateFromHEVCParameterSets

来创建H.265视频格式的描述信息,再创建解码session即可使用VideoToolBox进行解码。

3.3 说明

iOS 11 beta2的版本中

VTDecompressionSessionWaitForAsynchronousFrames

此函数调用会失败,目前不确定是beta系统的问题还是什么其他原因,在该版本的iOS系统上使用ijkplayer VideoToolBox解码会发现播放卡顿,就是因为该函数的问题导致,留待后续版本观察(7月10日已经推出beta3版本,还未确认)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,963评论 25 707
  • 最近因为要音频处理的研究,音频开发,但是有一个难题就是怎么解析与提取音频的数据,于是就找到了FFmpeg。基本上只...
    知曰阅读 231,929评论 9 96
  • 在此特此声明:一下所有链接均来自互联网,在此记录下我的查阅学习历程,感谢各位原创作者的无私奉献 ! 技术一点一点积...
    远航的移动开发历程阅读 11,092评论 12 197
  • 现状:现在视频直播非常的火,所以在视频直播开发中,使用的对视频进行遍解码的框架显得尤为重要了,其实,这种框架蛮多的...
    ZHANG_GO阅读 3,161评论 0 2
  • 人生之事,皆逃不过“俗”。 之所以有这种感受,大抵是因为终于意识到学生气的自己有太多与这个世界背道而驰的品格了。 ...
    Lllllssmin阅读 581评论 0 0