YunDaeHyeon
← Lab

프로토타입 기술 스택 및 구현 방식

실험2026.01.05
  • Swift
  • AVCaptureSession
  • MultipeerConnectivity

https://github.com/boostcampwm2025/iOS03-dolAwang

기술 스택 및 구현 방식

1. MultipeerConnectivity 설정

  • 암호화: encryptionPreference: .required
  • 서비스 타입: "mirroring-booth"

비디오 스트림 전송

  • 방식: session.send(_:toPeers:with:)
  • 모드: .unreliable
  • 이유: 실시간성 우선, 일부 패킷 손실 허용

사진 전송

  • 방식: session.sendResource(at:withName:toPeer:completionHandler:)
  • 이유: 파일 크기 큼, 완전성 보장, Progress 추적 가능

일반 메시지

  • 방식: session.send(_:toPeers:with:)
  • 모드: .reliable

2. 비디오 코덱 및 인코딩/디코딩

  • 코덱: H.264 (AVC)
  • 인코더: VideoToolbox의 VTCompressionSession
  • 디코더: VideoToolbox의 VTDecompressionSession
  • 프로파일: Baseline (kVTProfileLevel_H264_Baseline_AutoLevel)
  • 이유: 낮은 지연, 호환성, 실시간 스트리밍에 적합

포맷 변환

  • 인코딩: AVCC → Annex B
  • CMVideoFormatDescription에서 NAL unit은 AVCC (4바이트 길이 헤더)
  • 전송을 위해 Annex B (start code: 0x00 0x00 0x00 0x01)로 변환
  • 디코딩: Annex B → AVCC
  • 수신한 Annex B를 디코딩 전에 AVCC 형식으로 변환

3. 인코딩/디코딩 흐름

송신 측 (iPhone)

  AVCaptureVideoDataOutput 
    → CMSampleBuffer (YUV 4:2:0)
    → VTCompressionSession (H.264 인코딩)
    → AVCC 형식의 NAL units
    → Annex B 변환 (start code 추가)
    → Data
    → MultipeerConnectivity (.unreliable)

수신 측 (iPad/Mac)

  MultipeerConnectivity
    → Data (Annex B 형식)
    → NAL units 파싱 (SPS/PPS/IDR/Non-IDR)
    → SPS/PPS로 CMVideoFormatDescription 생성
    → VTDecompressionSession 생성
    → Annex B → AVCC 변환
    → VTDecompressionSession (H.264 디코딩)
    → CVImageBuffer
    → CMSampleBuffer
    → AVSampleBufferDisplayLayer (화면 표시)

4. 비트레이트 및 기타 설정

  • 해상도: Full HD (1920x1080) - VideoStreamSettings.defaultResolution
  • 비트레이트: High (6Mbps) - VideoStreamSettings.defaultBitRate
  • Low: 2Mbps
  • Medium: 4Mbps
  • High: 6Mbps (기본값)
  • 프레임 레이트: Standard (30fps) - VideoStreamSettings.defaultFrameRate
  • Low: 24fps
  • Standard: 30fps (기본값)
  • High: 60fps

인코딩 세션 설정

  • 실시간 인코딩: kVTCompressionPropertyKey_RealTime: true
  • B-frame 제거: kVTCompressionPropertyKey_AllowFrameReordering: false
  • 키프레임 간격: 1초당 1개 (30fps 기준 30프레임)
  • 픽셀 포맷: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange (YUV 4:2:0)
  • 세션 프리셋: .high

5. 사진 촬영 및 전송

  • 포맷: JPEG (AVVideoCodecType.jpeg)
  • 최대 해상도: 1920x1440 (비율 유지하며 리사이즈)
  • 압축 품질: 0.9
  • 전송 방식: sendResource (Progress 추적)

6. 아키텍처 및 설계

스레드 관리

  • AVCaptureSession: 전용 직렬 큐 (sessionQueue)
  • 인코딩: 전용 직렬 큐 (encoderQueue)
  • 디코딩: 전용 직렬 큐 (decoderQueue)

상태 관리

  • Swift 5.9+ @Observable 사용

리소스 관리

  • 세션 생성/해제
  • 임시 파일 정리
  • Delegate 생명주기 관리

요약하면..

  • MC: 비디오는 .unreliable, 사진은 sendResource
  • 코덱: H.264 Baseline, AVCC ↔ Annex B 변환
  • 설정: Full HD, 6Mbps, 30fps, B-frame 제거, 실시간 최적화