美文网首页
swift 视频编码

swift 视频编码

作者: 我会回来的 | 来源:发表于2021-12-29 18:04 被阅读0次

视频采集完成后,需要先编码,再传输,在解码,再播放(重现) 

1 视频压缩

第一: 创建VTCompressionSession 

———————————— 初始化编码器—————————————————————————— 

 //像素缓冲区选项

                letpixelBufferOptions: [String:Any] = [

                    kCVPixelBufferPixelFormatTypeKeyasString: kCVPixelFormatType_32BGRA,

                    kCVPixelBufferWidthKeyasString: frameW,

                    kCVPixelBufferHeightKeyasString: frameH,

                    kCVPixelBufferOpenGLESCompatibilityKeyasString:true,

                    kCVPixelBufferIOSurfacePropertiesKeyasString: [:]

                ]

varerr: OSStatus = noErr 

 // 初始化编码器

                err = VTCompressionSessionCreate(

                    allocator: kCFAllocatorDefault,

                    width: Int32(frameW),

                    height: Int32(frameH),

                    codecType: codecType,

                    encoderSpecification: encoderSpecificationsasNSDictionary?,

                    imageBufferAttributes: pixelBufferOptionsasNSDictionary?,

                    compressedDataAllocator:nil,

                    outputCallback: vtCallback,

                    refcon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),

                    compressionSessionOut: &sessionOut)

第二: 配置VTCompressionSession 

—————————————— 配置VTCompressionSession ———————————

varerr: OSStatus = noErr 

使用VTSessionSetProperty

//设置编码方式

                err = VTSessionSetProperty(

                    session,

                    key: kVTCompressionPropertyKey_ProfileLevel,

                    value: profileLevel)

第三: 对硬件捕获到的数据进行编码 

————————————————对硬件捕获到的数据进行编码 ———————————————

//进行硬编码 

            varsessionOut: VTCompressionSession?

 VTCompressionSessionPrepareToEncodeFrames(session)

第四:VTCompressionOutputCallback 

--------------------------------- -----帧压缩完成时调用的回调原型------------------------------------

//////// 压缩输出回调 

// 编码完成回调 

// 指针对象转换

 letenc = unsafeBitCast(outputCallbackRefCon, to: VTEncode.self

时间信息。我们可以分别使用 CMSampleBufferGetPresentationTimeStamp 和 CMSampleBufferGetDecodeTimeStamp 获得原始演示时间和解码时间的准确时间戳。

// 获取当前帧 是否是关键帧 

发送 SPS 和 PPS 

CMVideoFormatDescriptionGetH264ParameterSetAtIndex  取得 SPS 和  PPS

compressionSessionOutput  压缩会话输出

CMBlockBufferGetDataPointer (除了关键帧 其他帧只有一个数据) 

先找到PAT表, 通过PAT 找到PMT 的表,然后找到了TS流。

只有视频转换TS流。  

TS 数据包 

TS packet 是TS流的基本组成单位

TS packet 一般是188个字节长度,(或者是204个字节 188个字节加上16个字节(CRC校验数据 ))

TS packet 包含4个字节的 TS header 和其余的TS数据: 

4字节 Packet header

184字节 Packet data 

PID 唯一标识 ,Packet header 中PID是0x0000, data就为 DVB的PAT标

TS  文件是传输文件,视频编码主要格式h264/mpeg4,音频为acc/MP3。

TS流主要用于相对有错的环境下的传输和存储,如DVB

TS流 

先找到PAT表, 通过PAT 找到PMT 的表,然后找到了TS流。

PAT表: 指明了 PMT表的PID值

PMT表: 指明的是音视频流的PID值 

pcr 是递增的, 可以将其设置为dts值, 音频数据不需要pcr 。

Pes层 是在每一个视频/音频上加入了时间等信息,pes包内容很多, 只留下最常用的。

转载文档: https://blog.csdn.net/shj348794/article/details/25004783  

帧压缩时调用的回调原型  1帧后会异步调用改方法。  

// 获取sps pps 数据 只需获取一次,保存在H264文件开头即可。   

vps: 仅在H265编码器中才有。

https://blog.csdn.net/weixin_34362790/article/details/91470636

kCMSampleAttachmentKey_DependsOnOthers 通过他判断是否有I帧  

1 准备编码器

(1)创建session : VTCompressionSessionCreate

 (2)设置属性: VTSessionSetProperty 是否实时编码输出、是否产生B帧、设置关键帧、设置期望帧率、设置码率、最大码率值等等

 (3)准备开始编码:VTCompressionSessionPrepareToEncodeFrames  

2  编码完成后数据处理

(1)判断是否是关键帧

(2)组装NALU数据: 获取编码后的h264流数据:CMBlockBufferRef dataBuffer = CMSampleBufferGetDataBuffer(sampleBuffer),通过 首地址 、单个长度、 总长度通过dataPointer指针偏移做遍历

 OSStatus statusCodeRet = CMBlockBufferGetDataPointer(dataBuffer, 0, &length, &totalLength, &dataPointer); 

读取数据时有个大小端模式:网络传输一般都是大端模式

sps:序列参数集 

pps:图像参数集 

这两个帧也是独立。

添加startcode: 00 00 00 01 然后推流出去。

转载: https://www.cnblogs.com/edisongz/p/7062098.html

H.264 原始流  是由一个一个NALU组成的。

最后输出 compressionSessionOutput  压缩会话 

流程总结:

 1. 通过VTCompressionSessionCreate创建编码器 

  2. 通过VTSessionSetProperty设置编码器属性 

  3. 调用VTCompressionSessionPrepareToEncodeFrames 准备编码 

  4. 输入采集到的视频数据CVImageBufferRef /CVPixelBufferRef,调用VTCompressionSessionEncodeFrame进行编码 

  5. 获取到编码后的数据进行处理并组装NALU

     NALU分为两种格式:  Annex B 和 AVCC 

  6. 调用VTCompressionSessionCompleteFrames 停止编码器

  7.  调用VTCompressionSessionInvalidate销毁编码器 

相关文章

  • swift 视频编码

    视频采集完成后,需要先编码,再传输,在解码,再播放(重现) 1 视频压缩 第一: 创建VTCompressionS...

  • Swift 代码规范

    Swift 编码规范 A guide to our Swift style and conventions. 按大...

  • Swift代码规范

    团队的Swift代码规范,参考Swift Style Guide和Swift 4.0 编码规范,并根据团队实际需要...

  • iOS 视频硬编码H264/H265

    视频采集 视频采集部分,上一篇文章已经提及iOS视频采集 视频编码 首先初始化编码器 传入需要编码的数据 编码回调...

  • 视频格式

    视频:视频编码数据+音频编码数据 视频格式:视频封装格式(flv、mov、MP4) 视频编码格式:h264、h26...

  • webrtc源码分析之视频编码之二

    在webrtc源码分析之视频编码之一分析了视频编码初始化流程,接下来分析一下视频编码流程,如下图所示,视频编码流程...

  • 多媒体-封装格式和编码格式简单理解

    1. 封装格式和编码格式 什么是视频? 对原始视频流进行编码然后再封装的产物。 视频编码:h264音频编码:aac...

  • 视频编码

    视频音频的解码介绍过了,接下来是编码,相对于解码来说,编码流程相对麻烦一些。不过不要担心,小编带你装一把。 视频编...

  • 视频编码

    压缩编码的标准 为什么需要视频压缩编码标准目前,我们已经非常清楚,视频在存储&传输过程中,存在非常多的冗余信息,我...

  • Advanced Swift 6...

    Advanced-Swift-Sample-Code 6. 编码和解码 概览 /// 某个类型可以将⾃身编码为⼀种...

网友评论

      本文标题:swift 视频编码

      本文链接:https://www.haomeiwen.com/subject/wltyqrtx.html