読者です 読者をやめる 読者になる 読者になる

AVFoundationを利用したカメラ機能とパフォーマンスまとめ

AVFoundationを利用したカメラ機能の実装と、そのパフォーマンスで気になる点があったので、まとめてみました。
今回のサンプルプロジェクトはこちらになりますので、動作確認がしたい場合、そちらを参照してください。

Camera機能実装時に利用するAVFoundationクラス群

AVFoundationを利用してカメラ機能を実装する場合、以下のようなクラス群を利用します。

Class 役割
AVCaptureDevice カメラやマイクなど、キャプチャーを行う物理デバイスを表すクラス。
AVCaptureDeviceInput 物理デバイスからのインプットをSessionに入力するためのクラス。
AVCaptureSession キャプチャーしたデータの流れを調整するためのクラス。
AVCaptureVideoDataOutput 物理デバイスからSessionに渡されたを出力するためのクラス。
AVCaptureConnection AVCaptureInputとAVCaptureOutputを関連付けるためのクラス。AVCaptureSessionにAVCaptureInputをaddInput:、AVCaptureOutputをaddOutput:した時点で自動的にAVCaptureConnectionが自動的に適用されるため、AVCaptureConnectionは追加で設定を行う場合にのみ呼び出す。

実装時の具体的な手順としては、

  • AVCaptureDeviceのインスタンスを取得
  • 取得したAVCaptureDeviceのインスタンスを引数にAVCaptureDeviceInputを生成
  • AVCaptureDeviceInputをAVCaptureSessionに紐付け
  • AVCaptureVideoDataOutputを生成し、AVCaptureSessionに紐付け(&この時点でAVCaptureConnectionが自動的に生成される)
  • AVCaptureConnectionを取得し、追加的な設定を行う

これにより、AVCaptureInputとAVCaptureOutputを紐付けることができ、AVCaptureOutputのdelegateメソッドcaptureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)から CMSampleBufferRefを取得することができます。

CMSampleBufferRefとは?

それでは、CMSampleBufferRefとは何なのでしょうか。
AVFoundation Programming Guideを確認しますと、 Core Media represents video data using CMSampleBuffer... an instance contains the sample buffer for a frame of video data as a Core Video pixel buffer (see CVPixelBufferRef).と記載がありますので、キャプチャーされた各ビデオフレームのデータを保持するオブジェクトのようです。

CMSampleBufferRefからUIImageへの変換とパフォーマンス

CMSampleBufferGetImageBufferを用いることで、CMSampleBufferRefからCVPixelBufferRefを取得することができ、 そこからCIImage、UIImageと変換していくことができます。
それ以外にも、AVFoundation Programming GuideのConverting CMSampleBuffer to a UIImage Objectの項に記載がある方法でもUIImageへと変換を行うことができます。
しかし、同じ項にYou should not use this as a means to manipulate every frame of video coming from a capture device in real time.とあるので、 こちらはあまりパフォーマンスがよろしくないようです。
したがって、リアルタイムに描画を行う場合はCMSampleBufferGetImageBufferを利用した方法で行うのが良さそうです。

参考

サンプルプロジェクト