nyancoder

WWDC 2021 - What’s new in camera capture 본문

WWDC/WWDC 2021

WWDC 2021 - What’s new in camera capture

nyancoder 2021. 7. 7. 02:20

원본 영상: https://developer.apple.com/videos/play/wwdc2021/10047/

 

AVFoundation capture classes

AVCaptureDevice는 핵심 객체인 카메라 또는 마이크를 나타내는 입니다.

AVCaptureDeviceInputs는 이러한 장치를 감싸며, 중앙 제어 객체인 AVCaptureSession에 연결할 수 있습니다.

AVCaptureOutputs는 각각의 방식으로 입력된 데이터를 표시합니다.

MovieFileOutput은 QuickTime 동영상을 저장하며, PhotoOutput은 Live Photo 및 고해상도 이미지를 저장합니다.

VideoDataOutput과 AudioDataOutput은 비디오, 오디오 버퍼를 전달합니다.

CALayer의 하위 클래스 인 AVCaptureVideoPreviewLayer는 실시간 카메라 미리보기를 제공합니다.

데이터는 AVCaptureConnections를 통해 화살표를 따라 이동합니다.

 

Minimum focus distance

  • Minimum focus distance는 렌즈에서 선명한 초점을 얻을 수 있는 가장 가까운 지점까지의 거리입니다.
  • DSLR 카메라나 스마트 폰의 카메라 등 모든 카메라의 속성입니다.

  • 12 Pro Max Wide카메라는 Pro12와 달리 15cm 거리에서부터 초점을 맞춥니다.
  • 이는 iPhone 12 Pro Max의 센서 이동 안정화 기술 때문입니다.
  • Telephoto의 경우도 Minimum focus distance는 12 Pro보다 12 Pro Max에서 더 멉니다.
  • 이는 망원 렌즈의 줌 거리가 2.5x로 12 Pro의 2x에 비해 더 길기 때문입니다.

Minimum focus distance보다 짧은 거리만을 확보한 경우 상이 흐리게 표시됩니다.

IOS 15.0에 새로 추가된 속성인 .minimumFocusDistance를 이용하면 이 속성을 얻을 수 있습니다.

// Optimize the user experience for scanning QR codes down to sizes of 20mm x 20mm

let deviceFieldOfView = self.videoDeviceInput.device.activeFormat.videoFieldOfView
let minSubjectDistance = minSubjectDistanceForCode(
  fieldOfView: deviceFieldOfView,
  minimumCodeSize: 20,
  previewFillPercentage: Float(rectOfInterestWidth))

private func minSubjectDistance(
  fieldOfView: Float,
  minimumCodeSize: Float,
  previewFillPercentage: Float
) -> Float {
  let radians = degreesToRadians(fieldOfView / 2)
  let filledCodeSize = minimumCodeSize / previewFillPercentage
  return filledCodeSize / tan(radians)
}

let deviceMinimumFocusDistance = Float(self.videoDeviceInput.device.minimumFocusDistance)

if minimumSubjectDistanceForCode < deviceMinimumFocusDistance {
  let zoomFactor = deviceMinimumFocusDistance / minimumSubjectDistanceForCode
  do {
    try videoDeviceInput.device.lockForConfiguration()
    videoDeviceInput.device.videoZoomFactor = CGFloat(zoomFactor)
    videoDeviceInput.device.unlockForConfiguration()
  } catch {
    print("Could not lock for configuration: \(error)")
  }
}
  • 최소 바코드의 크기를 20mm 가정하고 작성된 코드입니다.
  • 카메라 미리 보기 창의 너비를 백분율로 표시하면 미리 보기 화면을 채우는 데 필요한 거리를 구할 수 있습니다.
  • 이 값을 바탕으로 초점을 맞출 수 있는 시점에 화면에 꽉 차도록 거리를 계산해서 videoZoomFactor에 대입합니다.
  • 그러면 사용자는 화면에 바코드가 너무 크게 표시되지 않도록 자연스럽게 카메라를 뒤로 조절합니다.

 

10-bit HDR video

  • HDR은 High Dynamic Range의 약자이며 iOS 4.1부터 사진 촬영에 사용되었습니다.
  • HDR은 다양한 노출로 촬영한 이미지를 혼합하여 밝은 부분과 그림자를 모두 유지합니다.
  • 비디오를 위해 2018년에 Apple은 iPhone XS 카메라 라인에 EDR(Extended Dynamic Range)를 도입했습니다.
  • EDR은 HDR과 유사한 비디오 설루션이며 캡처 프레임 속도가 두 배가 됩니다.

  • EDR 비디오는 30 fps 영상을 촬영할 때 실제로는 60 fps의 영상을 촬영합니다.
  • EV0 에서는 긴 노출의 프레임을 촬영하고 EV-에서는 짧은 노출의 프레임을 촬영하여 이를 하나의 프레임으로 만듭니다.
  • 저조도에서는 상대적으로 효과가 떨어지기 때문에 full HDR은 아닙니다.
  • 하지만 중간 밝기나 매우 밝은 환경에서는 좋은 결과를 제공합니다.

  • AVCapture API에서 .videoHDRSupported 또는 .videoHDREnabled 은 EDR의 지원/활성화 여부를 의미합니다.

  • automaticallyAdjustsVideoHDREnabled는 기본적으로 true입니다.
  • 따라서 EDR은 사용 가능하면 자동으로 활성화됩니다.
  • EDR을 비활성화하려면 automaticallyAdjustsVideoHDREnabled와 videoHDREnabled를 false로 설정해야 합니다.

  • 10bit HDR 비디오는 비트가 더 많기 때문에 진정한 HDR입니다.
  • 하이라이트 복구를 위한 EDR이 있으며 항상 켜져 있습니다.
  • BT.2020 색 공간을 사용하여 Rec 709보다 더 밝은 색상의 대비를 높일 수 있습니다.
  • AVCaptureMovieFileOutput 또는 AVCaptureVideoDataOutput, AVAssetWriter를 사용하면 Dolby Vision 메타 데이터를 프레임에 자동으로 삽입합니다.
  • 이는 Dolby Vision 디스플레이와 호환됩니다.
  • 10bit HDR 비디오는 iPhone 12 이상에서 사용할 수 있습니다.

  • 구형 iPhone 모델에서는 카메라에 쌍으로 제공되는 AVCaptureDeviceFormats가 있습니다.
  • 420v와 420f으로 제공되는 포맷은 8 비트, biplanar, YUV 형식입니다.
  • 420v의 V는 비디오 범위 (16 ~ 235)를 의미하고 420f의 F는 전체 범위 (0 ~ 255)를 나타냅니다.

  • iPhone 12 모델에서 일부는 420v, 420f, x420의 3가지 형식으로 제공됩니다.
  • 420v와 마찬가지로 x420은 biplanar 420 형식이지만 x420의 x는 8 대신 10 비트를 나타냅니다.

  • 10 비트 HDR 비디오 형식을 선택하려면 420YpCbCr10BiPlanarVideoRange를 찾으면 됩니다.

10bit HDR 비디오는 720p, 1080p 및 4K를 많이 사용되는 모든 비디오 형식을 지원합니다.

4x3 형식 (1920x1440)도 포함하여 1200만 화소 고해상도 사진 촬영을 지원합니다.

 

Video Effects in Control Center

  • 기존 방식은 새로운 카메라 기능을 도입할 때 Apple의 앱에 이를 즉시 적용합니다.
  • 그리고 새로운 AVCapture API를 공개하고, WWDC에서 개발자가 이를 학습할 수 있습니다.
  • 이후 개발자가 적절히 기능을 선택해서 적용합니다.
  • 이 방식은 안정적이지만 사용자에게 적용될 때까지는 긴 시간이 필요합니다.

Control Center를 통해 코드 변경 없이 모든 앱에서 사용자가 사용할 수 있습니다.

사용자가 기능을 원할 때, 제어할 수 있습니다.

그리고 추가되는 기능에 대한 새로운 API 또한 추가되며, 이를 개발자가 원할 때 적용할 수 있습니다.

  • 특별한 설정이 없는 경우 사람은 영상의 임의의 위치에 존재합니다.

  • Control Center에서의 설정을 통해 Center Stage를 켜고 끌 수 있습니다.

  • Center Stage 기능이 활성화되어있으면 카메라는 자동적으로 사람을 적절히 중앙에 배치합니다.

Portrait 모드를 활성화하면 사람 주변의 배경에 프라이버스 블러를 적용해줍니다.

마이크 입력도 Voice Isolation과 Wide Spectrum을 지원하며 음성채팅의 품질을 향상할 수 있습니다.

  • Center Stage는 M1 iPad Pro의 모든 전면 카메라에서 사용할 수 있습니다.
  • UltraWide, Virtual Wide, Virtual TrueDepth에서 사용할 수 있습니다.

  • 앱별로 켜기 / 끄기 토글을 제공합니다.
  • 카메라 당 하나의 상태가 아니라 앱별로 하나의 상태를 가집니다.

  • 이 설정 상태는 API의 AVCaptureDevice의 속성으로 얻을 수 있습니다.
  • AVCaptureDevice.isCenterStageEnabled로 활성화 유무를 체크할 수 있습니다.
  • AVCaptureDevice.centerStageControlMode에서 앱과 사용자 중 누가 제어할 수 있는지를 확인할 수 있습니다.

특정 카메라에 대해 Center Stage가 현재 활성화되어 있는지 확인할 수 있습니다.

  • 최대 프레임 속도는 30 fps로 제한됩니다.
  • 이미지 품질을 유지하기 위해 1920 x 1440로 제한됩니다.
  • 비디오의 확대/축소는 자동으로 이루어지므로 1로 고정됩니다.
  • GDC는 반드시 활성화되어야 합니다.
  • 깊이 정보를 전달하는 것은 비활성화되어야 합니다.

  • 사용자 모드는 기본적으로 모든 앱의 기본 값입니다.
  • 사용자만 설정을 변경할 수 있으므로, 앱에서 값을 변경하려고 하면 예외가 발생합니다.

  • 앱만이 설정을 변경할 수 있습니다.
  • Control Center에서의 버튼은 비활성화됩니다.
  • Center Stage가 앱과 호환되지 않는 것이 아닌 한, 이 모드는 사용하지 않는 것이 좋습니다.
  • centerStageControlMode = .app으로 설정한 다음 isCenterStageEnabled = false로 하여 Center Stage를 비활성화할 수 있습니다.

  • 사용자가 설정을 변경할 수 있습니다.
  • 앱 내에서도 설정을 변경할 수 있는 UI를 제공할 수 있습니다.
  • AVCaptureDevice.isCenterStageEnabled 값을 이용하여 UI를 업데이트할 수 있습니다.
  • centerStageControlMode = .cooperative로 설정한 다음 isCenterStageEnabled = true / false로 하여 적절히 Center Stage를 설정할 수 있습니다.

  • Portrait모드는 2018년 이후의 폰과 패드의 전면 카메라에 지원됩니다.
  • 또한 Neural Engine이 포함된 모든 M1 Mac에서 지원됩니다.

  • 렌더링 성능을 위해서 최대 해상도 1920 x 1440, 최대 프레임 30 fps로 제한됩니다.

  • Portrait 효과는 앱마다 켜짐/꺼짐 상태가 있습니다.
  • 사용자는 항상 Control Center를 통해 제어할 수 있습니다.

  • iOS의 경우에는 VoIP UIBackgroundMode를 사용하거나 Info.plist의 NSCameraPortraitEffectEnabled 키가 적용된 앱에서 적용됩니다.
  • macOS에서는 기본적으로 모든 앱들이 적용됩니다.

  • 카메라의 모든 Format에서 PortraitEffect가 지원되는 것은 아니므로, activeFormat.isPortraitEffectSupported를 통해 확인할 수 있습니다.
  • isPortraitEffectActive 속성을 통해서 Portrait가 현재 활성화되어 있는지 확인할 수 있습니다.

  • Mic Mode 또한 사용자의 설정은 앱별로 적용됩니다.
  • 사용자는 언제나 제어할 수 있고 앱에서 직접 설정할 수는 없습니다.
  • 일부 앱의 경우 이 기능을 지원하도록 설정해야 합니다.

  • Mic Modes는 AVFoundation의 AVCaptureDevice.MicrophoneMode를 통해서 얻을 수 있습니다.
  • .standard는 일반적인 오디오 DSP를 사용합니다.
  • .wideSpectrum은 장치 주변의 모든 사운드를 캡처하기 에코 제거 기능만을 적용하고 이외에는 최소한의 기능만을 수행합니다.
  • .voiceIsolation은 음성을 향상하고 배경 소음을 제거합니다.

  • AVCaptureDevice.preferredMicrophoneMode에서 사용자가 선택한 모드를 확인할 수 있습니다.
  • AVCaptureDevice.activeMicrophoneMode에서 현재 적용된 모드를 확인할 수 있습니다.

  • Mic Modes를 사용하려면 앱에서 CoreAudio의 AUVoiceIO를 사용해야 합니다.
  • 2018년 이후의 iOS 및 macOS에서 사용할 수 있습니다.

  • 사용자에게 AVCaptureDevice.showSystemUserInterface()를 호출하여 기능을 끄거나 켜도록 표시할 수 있습니다.
  • 전달인자에 .videoEffects 또는 .microphoneModes 를 전달하여 원하는 모드를 전달할 수 있습니다.

 

Performance best practices

  • 기본적으로 VideoDataOutput은 alwaysDiscardsLateVideoFrames 속성이 true입니다.
  • 이 설정으로 버퍼 크기가 1이 되고 오래된 프레임을 버려 항상 새로운 프레임을 제공합니다.
  • AVAssetWriter처럼 모든 프레임을 기록해야 하는 경우에는 비활성화해야 합니다.

  • 프레임이 버려질 때는 didDrop callback이 호출되며 여기서 원인을 확인할 수 있습니다.
  • FrameWasLate는 각 프레임의 처리가 너무 오래 걸린다는 것을 의미합니다.
  • OutOfBuffers는 너무 많은 버퍼를 보유하고 있을 수 있음을 의미합니다.
  • Discontinuity는 하드웨어 실패와 같은 오류로 사용자의 잘못이 아님을 나타냅니다.

  • 프레임 드롭이 발생할 때의 가장 좋은 방법은 AVCaptureDevice.activeMinVideoFrameDuration을 조절하여 프레임 속도를 낮추는 것입니다.
  • 다른 방법은 작업 부하를 줄여 각 처리 작업이 시간이 많이 걸리지 않도록 하는 것입니다.

  • AVCaptureDevice.SystemPressureState.Factors는 시스템의 부하와 관련 있는 속성을 표시하는 비트 마스크입니다.
  • .systemTemperature는 장치의 온도의 상승을 나타냅니다.
  • .peakPower는 배터리 노화의 정도와 배터리가 충분히 빠르게 전압을 높일 수 있는지에 관한 것입니다.
  • .depthModuleTemperature는 TrueDepth 카메라의 적외선 센서의 온도의 상승을 나타냅니다.

  • SystemPressureState.Level은 사용자의 경험이 손상되기 전에 조치를 취하기 위한 지표입니다.
  • .nominal은 모든 상태가 정상인 것을 나타냅니다.
  • .fair는 약간 부하가 있음을 나타내며, 주변의 온도가 높은 경우에도 발생합니다.
  • .serious는 부하가 높으며 fps 등이 영향을 받을 수 있음을 나타냅니다.
  • .critical은 부하가 상당하며 fps와 촬영 품질 등이 크게 영향을 받을 수 있습니다.
  • .shutdown 단계에서는 장치 보호를 위해 AVCaptureSession가 자동으로 종료됩니다.

  • 프레임 촬영 속도를 늦추는 것은 시스템 압력을 낮추는데 도움이 됩니다.
  • CPU와 GPU의 부하를 낮추어야 합니다.
  • 보다 작은 해상도나 적은 횟수의 처리를 통해 품질을 낮춤으로써 성능을 개선할 수 있습니다.

 

IOSurface compression

  • 메모리 대역폭은 동시에 실행할 수 있는 카메라 기능을 결정하는 제한 요소 중 하나입니다.
  • 비디오 데이터와 관련된 추상화 수준 중에서 최상위 수준에는 비디오 타이밍, 메타 데이터 등의 모든 데이터를 포함할 수 있는 CMSampleBuffer가 있습니다.
  • CMSampleBuffer안에는 메타 데이터와 픽셀 버퍼 데이터를 가질 수 있는 CVPixelBuffer가 있습니다.
  • 마지막인 IOSurface에서는 커널과 메모리를 연결할 수 있으며, 프로세스 간 공유되는 대용량 비디오 버퍼를 제공합니다.

  • iOS 15에서는 메모리 상의 무손실 비디오 압축 형식을 지원합니다.
  • 비디오 데이터의 총 메모리 대역폭을 낮추는 최적화입니다.
  • iOS 장치 및 Mac의 주요 하드웨어 간에서 사용 가능합니다.
  • iPhone 12 계열, Fall 2020 iPad Airs, Spring 2021 M1 iPad Pro에서 사용할 수 있습니다.

  • Metal, Vision, AVAssetReader/AVAssetWriter, VideoToolbox, Core Image, CALayer에서 사용할 수 있습니다.

  • IOSurface compression이 지원되는 하드웨어에서 비디오를 캡처하고 AVCaptureSession이 프로세스에 버퍼를 전달할 필요가 없는 경우에는 자동으로 IOSurface compression이 동작합니다.

  • 자동으로 동작할 수 없는 환경인 경우 물리적 메모리 구조가 불투명하고 변경될 수 있음을 염두에 두어야 합니다.
  • 데이터를 디스크에 기록해서는 안됩니다.
  • 모든 플랫폼에서 동일한 레이아웃을 가정해서는 안됩니다.
  • CPU를 사용하여 읽거나 기록해서도 안됩니다.

  • 각각의 비압축 형식에 대응되는 4자리 코드의 코드표는 위와 같습니다.

  • 실제로 코드를 통해 적용할 때의 실제 값은 위와 같습니다.

  • 카메라를 통해서 데이터를 받을 때에는 위와 같이 압축 형식을 지원하는지 우선 체크한 다음 체크하는 경우 압축 형식으로 요청을 하면 됩니다.
  • 그렇지 않은 경우에는 기존의 비압축 형식으로 요청해서 데이터를 처리하면 됩니다.

 

목차: https://nyancoder.tistory.com/2

Comments