iOS H264,H265视频编码(Video encode)

本例需求:使用H264, H265实现视频数据的编码并录制开始200帧存为文件.

原理:比如做直播功能,需要将客户端的视频数据传给服务器,如果分辨率过大如2K,4K则传输压力太大,所以需要对视频数据进行编码,传给服务器后再解码以实现大数据量的视频数据的传输,而利用硬件编码则可以极大限度减小CPU压力,

H264进行编码,iOS 11 之后,iPhone 7以上的设备可以支持新的编码器H265编码器,使得同等质量视频占用的存储空间更小。所以本例中可以使用两种方式实现视频数据的编码

最终效果如下 : h264

H264 编码

h265 :

H265编码

GitHub地址(附代码) : H264,H265Encode

简书地址 : H264,H265Encode

博客地址 : H264,H265Encode

掘金地址 : H264,H265Encode

实现方式

  1. H264 : H264是当前主流编码标准,以高压缩高质量和支持多种网络的流媒体传输著称

  1. H265 :H264编码器的下一代,它的主要优点提供的压缩比高,相同质量的视频是H264的两倍。

1、.本文需要基本知识点

注意:可以先通过H264,H265编码器介绍, H.264 Data Structure了解预备知识。

1.1 软编与硬编概念

  • 软编码:使用CPU进行编码。

  • 硬编码:不使用CPU进行编码,使用显卡GPU,专用的DSP、FPGA、ASIC芯片等硬件进行编码。

    • 比较

      • 软编码:实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。

      • 性能高,低码率下通常质量低于软编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。

      • 苹果在iOS 8.0系统之前,没有开放系统的硬件编码解码功能,不过Mac OS系统一直有,被称为Video ToolBox的框架来处理硬件的编码和解码,终于在iOS 8.0后,苹果将该框架引入iOS系统

1.2 H265优点

  • 压缩比高,在相同图片质量情况下,比JPEG高两倍

  • 能增加如图片的深度信息,透明通道等辅助图片。

  • 支持存放多张图片,类似相册和集合。(实现多重曝光的效果)

  • 支持多张图片实现GIF和livePhoto的动画效果。

  • 无类似JPEG的最大像素限制

  • 支持透明像素

  • 分块加载机制

  • 支持缩略图

2、代码解析

2.1 实现流程

  • 初始化相机参数,设置相机代理,这里就固定只有竖屏模式。

  • 初始化编码器参数,并启动编码器

  • 在编码成功的回调中从开始录制200帧(文件大小可自行修改)的视频,存到沙盒中,可以通过连接数据线到电脑从itunes中将文件(test0.asf)提取出来

2.2 编码器实现流程

  • 创建编码器需要的session (h264, h265 或同时创建)

  • 设置session属性,如实时编码,码率,fps, 编码的分辨率的宽高,相邻I帧的最大间隔等等

    • 注意H265目前不支持码率的限制

  • 当相机回调AVCaptureVideoDataOutputSampleBufferDelegate采集到一帧数据的时候则使用H264/H265编码器对每一帧数据进行编码。

  • 若编码成功会触发回调,回调函数首先检测是否有I帧出现,如果有I帧出现则将sps,pps信息写入否则遍历NALU码流并将startCode替换成{0x00, 0x00, 0x00, 0x01}

2.3 主要方法解析

  • 初始化编码器 首先选择使用哪种方式实现,在本例中可以设置[XDXHardwareEncoder getInstance].enableH264 = YES 或者 [XDXHardwareEncoder getInstance].enableH265 = YES,也可以同时设置,如果同时设置需要将其中一个回调函数中的writeFile的方法屏蔽掉,并且只有较新的iPhone(> iPhone8 稳定)才支持同时打开两个session。

判断当前设备是否支持H265编码,必须满足两个条件,一是iPhone 7 以上设备,二是版本大于iOS 11

if (@available(iOS 11.0, *)) {
            BOOL hardwareDecodeSupported = VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC);
            if (hardwareDecodeSupported) {
                _deviceSupportH265 = YES;
                NSLog(@"XDXHardwareEncoder : Support H265 Encode/Decode!");
            }
        }else {
            _deviceSupportH265 = NO;
            NSLog(@"XDXHardwareEncoder : Not support H265 Encode/Decode!");
        }

系统已经提供VTIsHardwareDecodeSupported判断当前设备是否支持H265编码

初始化编码器操作

- (void)prepareForEncode {
    if(self.width == 0 || self.height == 0) {
        NSLog(@"XDXHardwareEncoder : VTSession need with and height for init,with = %d,height = %d",self.width, self.height);
        return;
    }
    
    if(g_isSupportRealTimeEncoder)  NSLog(@"XDXHardwareEncoder : Device processor is 64 bit");
    else                            NSLog(@"XDXHardwareEncoder : Device processor is not 64 bit");
    
    NSLog(@"XDXHardwareEncoder : Current h264 open state : %d, h265 open state : %d",self.enableH264, self.enableH265);
    
    OSStatus h264Status,h265Status;
    BOOL isRestart = NO;
    if (self.enableH264) {
        if (h264CompressionSession != NULL) {
            NSLog(@"XDXHardwareEncoder : H264 session not NULL");
            return;
        }
        [m_h264_lock lock];
        NSLog(@"XDXHardwareEncoder : Prepare H264 hardware encoder");
        
        //[self.delegate willEncoderStart];
        
        self.h264ErrCount = 0;
        
        h264Status = VTCompressionSessionCreate(NULL, self.width, self.height, kCMVideoCodecType_H264, NULL, NULL, NULL, vtCallBack,(__bridge void *)self, &h264CompressionSession);
        if (h264Status != noErr) {
            self.h265ErrCount++;
            NSLog(@"XDXHardwareEncoder : H264 VTCompressionSessionCreate Failed, status = %d",h264Status);
  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值