VideoToolbox
ハードウェアアクセラレーションを利用して動画のエンコード/デコードを行うための Framework。低レベルな API であるため、ポインタ型を扱う必要があったり、release を意識する必要があったりする。
https://developer.apple.com/documentation/videotoolbox
エンコード
大まかな流れ
VTCompressionSession を生成して、session を通して圧縮処理を行う。全て完了した後は開発者が明示的に開放する必要がある。
1. Session を生成する
VTCompressionSessionCreate
2. 必要に応じてプロパティを設定する
Compression Property を設定できる
VTSessionSetProperty もしくは VTSessionSetProperties が利用できる
3. 動画のフレームをエンコードする
VTCompressionEncodeFrame でエンコードする
VTCompressionOutputCallback で結果を受け取る
4. 待ち状態のフレームについて強制的に完了させる
VTCompressionSessionCmpleteFrames が利用できる
5. 圧縮が終了した場合は、session を release する必要がある
VTCompressionSessionInvalidate を利用した上で、CFRelease でメモリを解放する必要がある
https://www.objc.io/issues/23-video/capturing-video/
VTCompressionSession の設定項目
セッション作成時に設定できるエンコード設定がかなり多く、かつドキュメントが少なめなので難しい。
code:swift
func VTCompressionSessionCreate(allocator: CFAllocator?,
width: Int32,
height: Int32,
codecType: CMVideoCodecType,
encoderSpecification: CFDictionary?,
imageBufferAttributes sourceImageBufferAttributes: CFDictionary?,
compressedDataAllocator: CFAllocator?,
outputCallback: VTCompressionOutputCallback?,
refcon outputCallbackRefCon: UnsafeMutableRawPointer?,
compressionSessionOut: UnsafeMutablePointer<VTCompressionSession?>) -> OSStatus
allocator
CFAllocator は、CoreFoundation のオブジェクトの生成時に受け渡すことができ、生成対象のオブジェクトがメモリの割り当て/開放等のメモリ操作を行うときの振る舞いを決定する。ざっくりいうと、生成対象のオブジェクトがメモリ操作を行う際に利用するオブジェクト、になるようだ。
CFAllocator | Apple Developer Documentation
Predefined な Allocator としては下記があるけれど、特別な事情がない場合は NULL = kCFAllocatorDefault を利用するのが推奨されている。
CFAllocator provides the following predefined allocators. In general, you should use kCFAllocatorDefault unless one of the special circumstances exist below.
Predefined Allocators | Apple Developer Documentation
width, height
映像フレームのピクセル単位の幅と高さを指定する。
codecType
エンコードに利用するコーデックを渡す。以下に一覧があるので、利用したいものを利用すれば良い。未指定、すなわち raw データをそのまま利用する、といった指定はできない。圧縮処理の引数なのでそれはそう。
CMVideoCodecType - Core Media | Apple Developer Documentation
encoderSpecification
利用するエンコーダを明示的に指定したい場合に、キーとエンコーダIDの Dictionary を渡すことで指定できるようだ。利用可能なエンコーダのリストは VTCopyVideoEncoderList で取得できる。
To specify a particular video encoder when creating a compression session, pass an encoderSpecification CFDictionary containing this key and the EncoderID as its value. The EncoderID CFString may be obtained from the kVTVideoEncoderList_EncoderID entry in the array returned by VTCopyVideoEncoderList.
https://stackoverflow.com/questions/31458150/how-to-set-bitrate-for-vtcompressionsession
imageBufferAttributes
ピクセルバッファプールを作成する時に利用する設定値を渡す。nil を受け渡すとバッファープールが作られないが、その場合には VideoToolBox が画像データをコピーする機会が増加してしまうという。
下記にまとめらている Pixel buffer 用の属性を CFDictionary として詰め込めば良いようだ。
https://developer.apple.com/documentation/corevideo/cvpixelbuffer/pixel_buffer_attribute_keys
compressedDataAllocator
圧縮データ用の Allocator を指定する。macOS 10.12 以降だと、指定すると余分なバッファコピーが発生してしまうと注記されている。基本的には null で良さそう。
outputCallback
エンコード終了時に呼び出される callback 関数 を登録する。
refcon
callback に受け渡したいオブジェクトを指定する。
compressionsSessionOut
これも C ライクな API だけど、この関数で生成した session を格納する変数へのポインタを受け渡す。
Compression Property