Files
video-v1/vav2/CLAUDE.md

54 KiB

Vav2Player - AV1 Video Player 개발 프로젝트

⚠️ CRITICAL: 코딩 규칙 및 가이드라인

📝 주석 언어 규칙 (REQUIRED)

🚨 중요: 모든 소스 코드 파일의 주석은 영어로 작성해야 합니다.

적용 범위

  • .h 헤더 파일의 모든 주석
  • .cpp 소스 파일의 모든 주석
  • .xaml.h WinUI 헤더 파일의 모든 주석
  • .xaml.cpp WinUI 소스 파일의 모든 주석

예시

// ❌ 잘못된 예 (한국어 주석)
// 버퍼 크기 확인 및 재할당 최소화
size_t required_size = frame.width * frame.height * 4;

// ✅ 올바른 예 (영어 주석)
// Check buffer size and minimize reallocation
size_t required_size = frame.width * frame.height * 4;

이유

  1. 국제화 지원: 영어 주석으로 코드의 국제적 접근성 향상
  2. 컴파일러 호환성: 일부 컴파일러에서 비ASCII 문자로 인한 인코딩 문제 방지
  3. 협업 효율성: 다양한 배경의 개발자들과의 협업 용이성
  4. 유지보수성: 장기적인 코드 유지보수 시 언어 장벽 제거

⚠️ 필수 조치사항

  • 기존 한국어 주석 발견 시 즉시 영어로 변환
  • 새로운 코드 작성 시 처음부터 영어 주석 사용
  • 함수명, 변수명은 기존 명명 규칙 유지 (영어만 가능)

🚫 이모지 사용 금지 규칙 (REQUIRED)

🚨 중요: 모든 소스 코드, 주석, 문자열에서 이모지 사용을 금지합니다.

적용 범위

  • 모든 소스 코드 파일의 주석 (.h, .cpp, .xaml.h, .xaml.cpp)
  • 코드 내 문자열 리터럴 (예: "Success!", L"Video Player")
  • XAML 파일의 주석 및 텍스트 속성
  • 로그 메시지 및 디버그 출력

권장 대체 방안

// ✅ 권장 대체 방안
// [PERFORMANCE] GPU acceleration enabled
// [SUCCESS] Frame decode completed
// [WARNING] Fallback to CPU rendering
// [ERROR] Failed to initialize D3D12 device

🎯 현재 프로젝트 상태 (2025-09-30)

Android Vulkan AV1 Player 완전 구현 완료 (2025-09-30)

  • Android Vulkan 애플리케이션: 완전한 네이티브 Vulkan AV1 Player 앱 구현
  • MediaCodec 키워드 기반 디코더 선택: 부분 문자열 매칭으로 다양한 Android 모델 호환성 확보
  • MediaCodec Priming 시스템: 첫 프레임 디코딩 지연 1초 → 100ms 이하로 단축 완료
  • Samsung Galaxy S24 Qualcomm Snapdragon 최적화: c2.qti.av1.decoder 자동 선택 및 성능 최적화
  • Vulkan 1.1 렌더링 파이프라인: YUV to RGB GPU 쉐이더, AspectFit 스케일링 완성
  • Play/Pause/Stop 컨트롤: 완전한 비디오 재생 제어 시스템 구현
  • 실시간 성능 모니터링: FPS, 프레임 드롭, GPU 메모리 사용량 표시

주요 완성 기능:

  • 키워드 기반 MediaCodec 선택: exynos, sec, qcom, qti, mtk, android, google 우선순위 시스템
  • MediaCodec 프라이밍: 하드웨어 디코더 warm-up 및 Progressive fallback 시스템
  • 크로스 벤더 호환성: Samsung, Qualcomm, MediaTek, Google 모든 주요 SoC 지원
  • VavCore C API 28개 함수: Android NDK JNI를 통한 완전한 네이티브 통합
  • 16KB 페이지 호환성: Google Play Android 15+ 호환성 보장

현재 진행 중

  • Video Player Overlay UI: 프로덕션 레벨 사용자 경험 향상 (파일 선택, 제스처 컨트롤, 진행바, 오버레이 UI) 🔄

활성 설계 문서

완료된 프로젝트 아카이브

  • 📋 Complete Projects Archive - 완료된 20개 미니 프로젝트 (하드웨어 가속, 성능 최적화, 테스트, 크로스 플랫폼, 아키텍처 설계, Godot 통합)

최신 완료 작업: 주요 마일스톤 달성 (2025-09-30)

🎯 2025년 9월 최종 핵심 성과

📋 완료된 Android 프로젝트 주요 기능

  • 키워드 기반 MediaCodec 선택: exynos, sec, qcom, qti, mtk, android, google 우선순위 시스템으로 모든 Android 기기 호환성 확보
  • 완전한 비디오 재생 앱: Load Video, Play, Pause, Stop, 파일 선택, 성능 모니터링 완전 구현
  • Vulkan Surface 직접 렌더링: GPU 가속 YUV to RGB 변환 및 AspectFit 스케일링
  • 실시간 성능 모니터링: FPS, 프레임 드롭, GPU 메모리 사용량 실시간 표시
  • Google Play 호환성: Android 15+ 16KB 페이지 크기 완전 호환
  • 프로젝트 문서 완료: 완료된 프로젝트를 docs/completed/ 아카이브로 이동 완료

🎯 현재 프로젝트 상태 (2025-09-30)

📈 프로젝트 완성도 및 성과 지표

  • Windows + Android 완전 구현: Vav2Player GUI 앱 + Android Vulkan AV1 Player 모두 완성 🎯
  • 4K AV1 디코딩: Windows 9-15ms, Android MediaCodec 하드웨어 가속 최적화 완료
  • 하드웨어 가속: Windows (NVIDIA, Intel, AMD) + Android (Qualcomm, Exynos, MediaTek) 전체 지원 🚀
  • 크로스 플랫폼 C API: Windows DLL + Android JNI 28개 vavcore_* 함수 통일 완료 🌐
  • Vulkan 렌더링: Windows D3D12 + Android Vulkan 1.1 직접 GPU 렌더링 파이프라인 🎮

🎯 현재 활성 컴포넌트

플랫폼별 완성 기능

Windows 플랫폼

  1. VavCore C API: 28개 vavcore_* 함수 완전 구현, DLL 빌드 성공
  2. 하드웨어 가속: NVIDIA NVDEC, Intel VPL, AMD AMF 모든 디코더
  3. VavCore.Godot Extension: Zero-Copy GPU Pipeline + CPU Fallback 완성
  4. Vav2Player GUI: WinUI3 애플리케이션 완전 구현
  5. D3D12 렌더링: YUV to RGB GPU 쉐이더, AspectFit 스케일링
  6. 빌드 & 테스트: 47개 Unit Test, 헤드리스 테스트 완료

Android 플랫폼

  1. Android Vulkan AV1 Player: 완전한 네이티브 Android 앱 구현
  2. MediaCodec 하드웨어 가속: 키워드 기반 디코더 선택, 크로스 벤더 호환성
  3. VavCore Android JNI: C API 28개 함수 Android NDK 연동 완료
  4. Vulkan 1.1 렌더링: YUV to RGB GPU 쉐이더, AspectFit 스케일링
  5. Samsung Galaxy S24 최적화: Qualcomm Snapdragon c2.qti.av1.decoder 특화
  6. Google Play 호환성: Android 15+ 16KB 페이지 크기 완전 지원

공통 완성 기능

  • 크로스 플랫폼 아키텍처: platforms/ 디렉토리 구조, 통일된 빌드 시스템
  • 문서화 완료: 프로젝트 아카이브, 설계 문서, 빌드 가이드 완성

📋 완료된 설계 및 구현 (참조용)

대규모 리팩토링 완료 (MAJOR_REFACTORING_GUIDE.md)

  • 목표 달성: 전체 코드 88% 감소 (6800줄 → 800줄)
  • 복잡한 파이프라인 파일들 삭제 (ThreadedDecoder, OverlappedProcessor, DependencyScheduler)
  • VideoPlayerControl.xaml.h 멤버 변수 대폭 정리 (10개 이상 → 3-4개)
  • VideoPlayerControl.xaml.cpp ProcessSingleFrame() 단순화 (1000줄 → 25줄)
  • 빌드 테스트 및 기본 비디오 재생 동작 확인

GPU 파이프라인 재설계 완료

  • 단순 GPU 파이프라인 설계 (CPU Thread → GPU Thread)
  • SimpleGPURenderer 구현
  • CPU-GPU 하이브리드 fallback 구조
  • 성능 최적화 및 안정성 확보

단위 테스트 시스템 완료 (UNIT_TEST_REFACTORING_PLAN.md)

  • 선택 완료: Option A (인터페이스+Mock) 구현
  • 인터페이스 리팩토링 (IWebMFileReader, IVideoRenderer)
  • Mock 시스템 구축 (MockWebMFileReader, MockVideoRenderer)
  • 핵심 컴포넌트 테스트 작성 (47개 테스트, 95.7% 통과율)
  • 빌드 시스템 통합 (debug 라이브러리 호환성 해결)
  • VSTest 실행 환경 구축

NVDEC 하드웨어 가속 완료

  • NVIDIA Video Codec SDK 13.0 통합 및 CUDA 13.0 API 지원
  • NVDECAV1Decoder 헤드리스 구현 및 테스트 완료
  • GUI 프로젝트 NVDEC 통합 및 TIMECODE 충돌 해결
  • VideoDecoderFactory에서 NVDEC → dav1d → MediaFoundation 우선순위 설정
  • 하드웨어 가용성 자동 감지 및 graceful fallback 구현

적응형 품질 제어 시스템 완료

  • AdaptiveNVDECDecoder 구현 (NVDEC 기반 동적 해상도 조정)
  • AdaptiveAV1Decoder 구현 (dav1d 기반 포스트 디코딩 스케일링)
  • 3단계 품질 모드 시스템 (CONSERVATIVE, FAST, ULTRA_FAST) 구현 및 최적화
  • 실시간 성능 모니터링 (30프레임 이동평균, 히스테리시스 제어)
  • 프레임 스킵 제거를 통한 부드러운 비디오 재생 실현
  • 4K AV1 디코딩 성능 최적화 (27.7fps 달성)

🎯 현재 프로젝트 상태 요약 (2025-09-25 업데이트)

구현 완료된 주요 컴포넌트

  1. Core Video Infrastructure: WebMFileReader, AV1Decoder, VideoDecoderFactory
  2. Hardware Acceleration: NVDECAV1Decoder, CUDA 13.0 통합, NVDEC 우선 디코더 설정
  3. Adaptive Quality Control: AdaptiveAV1Decoder, AdaptiveNVDECDecoder 완전 구현
  4. Quality Mode System: CONSERVATIVE, FAST, ULTRA_FAST 모드 구현 및 최적화
  5. GPU Rendering System: SimpleGPURenderer, D3D12VideoRenderer 구현
  6. UI Integration: VideoPlayerControl 단순화 및 WinUI3 통합
  7. Build System: 모든 프로젝트 빌드 성공 (GUI/Headless/UnitTest)
  8. Test Infrastructure: 47개 Unit Test, Mock 시스템, NVDEC 헤드리스 테스트 구축
  9. Code Quality: 한글 주석 → 영어 변환, 코딩 가이드라인 준수, VavCore 네임스페이스 통일
  10. Performance Optimization: 4K AV1 디코딩 27.7fps 달성 (ULTRA_FAST 모드)
  11. Project Structure Reorganization: VavCore_Library_Design.md 구조 완전 적용 (2025-09-25)
  12. Multi Video UI Enhancement: MultiVideoTestPage → MultiVideoPage 이름 변경 및 기능 완성 (2025-09-25)
  13. User Experience Improvement: Stop All 버튼 처음부터 재생 기능 구현 (2025-09-25)

Android Vulkan AV1 Player 완료 (docs/completed/android/Android_Vulkan_AV1_Player_Design.md)

  • 목표 달성: Samsung Galaxy S24 Qualcomm Snapdragon 최적화된 네이티브 Android AV1 Player 완전 구현
  • MediaCodec 키워드 기반 디코더 선택: exynos, sec, qcom, qti, mtk, android, google 우선순위 시스템 완료
  • 크로스 벤더 호환성: Samsung, Qualcomm, MediaTek, Google 모든 주요 Android SoC 지원
  • Vulkan 1.1 네이티브 렌더링: YUV to RGB GPU 쉐이더, AspectFit 스케일링 완료
  • VavCore Android JNI: C API 28개 함수 Android NDK 완전 연동
  • 완전한 비디오 재생 앱: Load Video, Play, Pause, Stop, 성능 모니터링 구현
  • Google Play 호환성: Android 15+ 16KB 페이지 크기 완전 지원

VavCore Godot 4.4.1 C# Extension 완료 (VavCore_Godot_Integration_Design.md)

  • 목표 달성: 크로스 플랫폼 Godot 4.4.1 AV1 디코딩 확장 구현
  • VavCore C API 28개 함수 완전 구현 및 DLL 빌드 성공
  • VavCore.Wrapper P/Invoke 래퍼 완전 구현 (빌드 성공)
  • 크로스 플랫폼 Surface 지원 (D3D, Vulkan, Metal, OpenGL)
  • platforms/ 디렉토리 구조 및 빌드 시스템 통합
  • API 단순화로 기술부채 최소화 (70+ → 28개 함수)
  • Zero-Copy GPU Pipeline 완전 구현 (2025-09-28)
  • CPU Fallback 렌더링 시스템 완전 구현 (2025-09-28)
  • 이중 렌더링 모드: GPU Surface 바인딩 + CPU ImageTexture 생성

VavCore Static Library 완료 (VavCore_Library_Design.md)

  • 목표 달성: 재사용 가능한 AV1 디코딩 라이브러리 완전 구현
  • 기존 AV1 디코딩 시스템을 독립 라이브러리로 분리
  • Public API 설계를 통한 모듈화 및 재사용성 극대화
  • VavCore.vcxproj 프로젝트 완전 구현
  • Pimpl 패턴 적용으로 C/C++ ABI 호환성 확보
  • 프로젝트 구조 재편성 (VavCore_Library_Design.md 구조 완전 적용)

GPU 렌더링 시스템 완료

  • D3D12VideoRenderer 완전 구현 (YUV→RGB 변환)
  • SwapChainPanel 통합 및 AspectFit 렌더링
  • 성능 최적화: 4K 렌더링 0.6-1.3ms 달성 (15-30배 개선)
  • CPU fallback 메커니즘 및 호환성 확보

프로젝트 개요

WinUI 3 C++로 작성된 AV1 파일 재생 플레이어

  • 목적: WebM/MKV 형식의 AV1 비디오 파일을 실시간으로 디코딩하여 재생
  • 현재 단계: 파일 출력 기반 스트리밍 파이프라인 구현 (렌더링은 추후)
  • 목표 성능: 30fps 끊김없는 실시간 재생

📁 프로젝트 파일 경로 (Project File Locations)

메인 프로젝트 파일들 (2025-09-28 플랫폼별 구조 완성)

  • VavCore 라이브러리: D:\Project\video-av1\vav2\platforms\windows\vavcore\VavCore.vcxproj
  • Godot Extension: D:\Project\video-av1\vav2\platforms\windows\godot-plugin\src\VavCore.Godot\VavCore.Godot.csproj
  • GUI 애플리케이션: D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player\Vav2Player.vcxproj
  • 솔루션 파일: D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player.sln
  • 테스트 프로젝트들: D:\Project\video-av1\vav2\platforms\windows\tests\*\

빌드 명령어 템플릿 (플랫폼별 구조)

# 전체 Windows 플랫폼 빌드 (모든 컴포넌트)
cd "D:\Project\video-av1\vav2\platforms\windows"
./build-all.bat

# 개별 컴포넌트 빌드
# VavCore 라이브러리
cd "D:\Project\video-av1\vav2\platforms\windows\vavcore"
./build.bat Debug

# Godot Extension
cd "D:\Project\video-av1\vav2\platforms\windows\godot-plugin"
./build.bat Debug

# GUI 애플리케이션
cd "D:\Project\video-av1\vav2\platforms\windows\applications\vav2player"
"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2Player.sln //p:Configuration=Debug //p:Platform=x64 //v:minimal

# 모든 테스트 실행
cd "D:\Project\video-av1\vav2\platforms\windows\tests"
./run-all-tests.bat Debug

실행 파일 경로 (2025-09-28 플랫폼별 구조)

  • VavCore DLL: D:\Project\video-av1\vav2\platforms\windows\vavcore\lib\VavCore-debug.dll
  • Godot Extension: D:\Project\video-av1\vav2\platforms\windows\godot-plugin\bin\Debug\
  • GUI 실행파일: D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\x64\Debug\Vav2Player\Vav2Player.exe
  • 테스트 실행파일들: D:\Project\video-av1\vav2\platforms\windows\tests\*\bin\Debug\

주요 디렉토리 (2025-09-28 플랫폼별 구조)

  • VavCore 소스: D:\Project\video-av1\vav2\platforms\windows\vavcore\src\
  • VavCore 헤더: D:\Project\video-av1\vav2\platforms\windows\vavcore\include\VavCore\
  • Godot Extension 소스: D:\Project\video-av1\vav2\platforms\windows\godot-plugin\src\
  • GUI 애플리케이션 소스: D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player\src\
  • 테스트 소스들: D:\Project\video-av1\vav2\platforms\windows\tests\*\

프로젝트 구조 (2025-09-28 멀티플랫폼 구조 완성)

D:\Project\video-av1\
├── vav2/
│   └── platforms/                    # 플랫폼별 통합 디렉토리
│       ├── windows/                  # Windows 플랫폼 전용
│       │   ├── vavcore/              # VavCore 라이브러리
│       │   │   ├── VavCore.vcxproj   # C/C++ DLL 프로젝트
│       │   │   ├── build.bat         # VavCore 개별 빌드
│       │   │   ├── include/VavCore/  # Public API 헤더
│       │   │   └── src/              # VavCore 구현 코드
│       │   ├── godot-plugin/         # Godot 4.4.1 Extension
│       │   │   ├── src/VavCore.Wrapper/    # C# P/Invoke 래퍼
│       │   │   ├── src/VavCore.Godot/      # Godot 플러그인
│       │   │   ├── libs/windows-x86_64/    # 빌드된 DLL
│       │   │   └── build.bat         # Godot 확장 빌드
│       │   ├── applications/         # Windows 애플리케이션들
│       │   │   └── vav2player/       # Vav2Player GUI 앱
│       │   │       ├── Vav2Player.sln      # Visual Studio 솔루션
│       │   │       └── Vav2Player/         # WinUI3 프로젝트
│       │   ├── tests/                # 모든 Windows 테스트
│       │   │   ├── vavcore-dll/      # VavCore DLL 연결 테스트
│       │   │   ├── godot-extension/  # Godot 확장 테스트
│       │   │   ├── integration/      # 통합 테스트
│       │   │   ├── unit-tests/       # 유닛 테스트
│       │   │   ├── headless/         # 헤드리스 성능 테스트
│       │   │   └── run-all-tests.bat # 모든 테스트 실행
│       │   └── build-all.bat         # 전체 Windows 빌드
│       └── android/                  # Android 플랫폼 전용
│           ├── vavcore/              # Android VavCore 라이브러리
│           │   ├── CMakeLists.txt    # Android CMake 프로젝트
│           │   ├── build_vavcore_android.bat  # Android NDK 빌드 스크립트
│           │   ├── include/          # Android 전용 헤더
│           │   ├── lib/              # Android 전용 라이브러리
│           │   │   ├── android-arm64-v8a/    # ARM64 라이브러리
│           │   │   └── android-armeabi-v7a/  # ARM32 라이브러리
│           │   └── src -> ../../windows/vavcore/src  # 공유 소스
│           └── applications/         # Android 애플리케이션들
│               └── vav2player/       # Vulkan AV1 Player 앱
│                   ├── app/
│                   │   ├── build.gradle.kts           # Android 앱 빌드 설정
│                   │   ├── src/main/java/com/vavcore/player/  # Java/Kotlin 소스
│                   │   │   ├── MainActivity.java      # 메인 액티비티
│                   │   │   ├── VulkanVideoView.java   # Vulkan 렌더링 뷰
│                   │   │   ├── VideoController.java   # 비디오 제어
│                   │   │   └── PerformanceMonitor.java # 성능 모니터링
│                   │   ├── src/main/cpp/             # C++ JNI 소스
│                   │   │   ├── CMakeLists.txt         # Native 빌드 설정
│                   │   │   ├── vulkan_renderer.h/.cpp # Vulkan 렌더러
│                   │   │   ├── vavcore_vulkan_bridge.h/.cpp # VavCore 브릿지
│                   │   │   ├── vulkan_jni_integrated.cpp    # JNI 인터페이스
│                   │   │   └── yuv_shaders.h/.cpp     # YUV to RGB 쉐이더
│                   │   ├── src/main/res/             # Android 리소스
│                   │   │   ├── layout/activity_main.xml     # 메인 레이아웃
│                   │   │   └── values/strings.xml           # 문자열 리소스
│                   │   └── src/main/AndroidManifest.xml     # 앱 매니페스트
│                   ├── vavcore/                      # VavCore 모듈
│                   ├── gradle.properties
│                   ├── gradlew.bat                   # Gradle 래퍼
│                   └── settings.gradle.kts           # 프로젝트 설정
├── include/                          # 플랫폼 공통 헤더
│   ├── libwebm/                      # libwebm 헤더 (mkvparser, mkvmuxer)
│   ├── dav1d/                        # dav1d 헤더 (dav1d.h, picture.h 등)
│   ├── amf/                          # AMD AMF 헤더
│   └── libvpl/                       # Intel VPL 헤더
└── lib/                              # 플랫폼별 라이브러리 구조
    ├── windows-x64/                  # Windows 64bit 라이브러리
    │   ├── libwebm/webm.lib          # libwebm 정적 라이브러리
    │   ├── dav1d/                    # dav1d 라이브러리
    │   ├── amf/                      # AMD AMF 라이브러리
    │   └── libvpl/                   # Intel VPL 라이브러리
    ├── android-arm64/                # Android ARM64 라이브러리
    │   ├── dav1d/                    # dav1d Android ARM64
    │   └── libwebm/                  # libwebm Android ARM64 (향후 추가)
    └── android-arm32/                # Android ARM32 라이브러리
        ├── dav1d/                    # dav1d Android ARM32
        └── libwebm/                  # libwebm Android ARM32 (향후 추가)

전체 아키텍처 설계

데이터 플로우

[AV1 파일] → [libwebm Parser] → [AV1 Packet Queue] → [dav1d Decoder] → [YUV Frame Queue] → [File Output]
                     ↓                              ↓                          ↓
              [File Reader Thread]           [Decoder Thread]         [Output Thread]

핵심 컴포넌트

  1. WebMFileReader: libwebm 기반 파일 파싱
  2. AV1Decoder: dav1d 기반 프레임 디코딩
  3. StreamingPipeline: 멀티스레드 스트리밍 관리
  4. FileOutput: Raw/BMP 파일 출력

구현 단계별 계획

완료된 작업

  • 프로젝트 구조 분석
  • libwebm/dav1d 라이브러리 의존성 확인
  • 전체 아키텍처 설계

📋 구현 단계

1단계: libwebm 기반 파일 로더 구현

목표: WebM/MKV 파일을 파싱하여 AV1 비디오 트랙 추출 구현 파일: WebMFileReader.h/cpp 기능:

  • WebM/MKV 파일 열기 및 검증
  • 비디오 트랙 메타데이터 추출 (해상도, FPS, 코덱 정보)
  • AV1 트랙 식별 및 선택
  • 프레임별 패킷 추출 인터페이스
  • 시간 기반 탐색 지원

2단계: dav1d 디코더 래퍼 구현

목표: AV1 패킷을 YUV 프레임으로 디코딩 구현 파일: AV1Decoder.h/cpp 기능:

  • dav1d 컨텍스트 초기화/해제
  • AV1 패킷 입력 및 YUV 프레임 출력
  • 프레임 메타데이터 관리 (타임스탬프, 프레임 타입)
  • 에러 핸들링 및 복구
  • 메모리 관리 최적화

3단계: 스트리밍 파이프라인 및 버퍼링 시스템 구현

목표: 30fps 실시간 재생을 위한 멀티스레드 파이프라인 구현 파일: StreamingPipeline.h/cpp, FrameBuffer.h/cpp 기능:

  • Producer-Consumer 멀티스레드 구조
  • 프레임 버퍼 관리 (기본: 15프레임 = 0.5초 버퍼링)
  • 타이밍 제어 (30fps 기준 33.33ms 간격)
  • 백프레셔 핸들링 (버퍼 풀/빈 상태 처리)
  • 성능 모니터링 (FPS, 드롭된 프레임 수)

4단계: Raw 및 BMP 파일 출력 기능 구현

목표: 디코딩된 프레임을 파일로 저장 구현 파일: FileOutput.h/cpp 기능:

  • Raw YUV420P 포맷 출력
  • YUV → RGB 변환
  • BMP 파일 생성 및 저장
  • 프레임 번호 기반 파일명 생성
  • 출력 디렉토리 관리

기술적 고려사항

성능 최적화

  • 버퍼링 전략: 15프레임 (0.5초) 기본 버퍼, 설정 가능
  • 메모리 풀: 프레임 재사용을 위한 메모리 풀 구현
  • 스레드 동기화: lock-free 큐 사용 고려
  • SIMD 최적화: dav1d 내장 최적화 활용

에러 처리

  • 파일 포맷 오류 감지 및 복구
  • 디코딩 실패 시 프레임 스킵
  • 메모리 부족 시 버퍼 크기 동적 조정
  • 스레드 예외 전파 메커니즘

확장성

  • 플러그인 아키텍처 (다른 코덱 지원)
  • 설정 파일 기반 매개변수 조정
  • 로깅 및 디버깅 인프라
  • 단위 테스트 지원

빌드 설정

Windows 플랫폼

  • 플랫폼: x64 Windows
  • 컴파일러: MSVC v143 (Visual Studio 2022)
  • 언어 표준: C++17 이상
  • 런타임: Windows App SDK 1.8

Android 플랫폼

  • 플랫폼: ARM64 (arm64-v8a), ARM32 (armeabi-v7a)
  • 컴파일러: Android NDK Clang
  • 언어 표준: C++17 이상
  • API Level: 29+ (Android 10+)

Android NDK 환경 설정

Android VavCore 빌드를 위해서는 다음 환경 변수가 설정되어야 합니다:

# Android NDK 설치 경로 설정 (필수)
export ANDROID_NDK_HOME=/path/to/android-ndk-r25

# 또는 대체 변수명 사용 가능
export ANDROID_NDK_ROOT=/path/to/android-ndk-r25

Android 빌드 명령어

# Android VavCore 라이브러리 빌드
cd "D:\Project\video-av1\vav2\platforms\android\vavcore"
./build.sh

# 또는 직접 CMake 사용
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
      -DANDROID_ABI=arm64-v8a \
      -DANDROID_NATIVE_API_LEVEL=29 \
      -DCMAKE_BUILD_TYPE=Debug \
      -B build
cmake --build build

다음 작업

  1. 1단계 구현 시작: WebMFileReader 클래스 구현
  2. 프로젝트 설정: vcxproj 파일에 include/lib 경로 및 종속성 추가
  3. 기본 테스트: 간단한 WebM 파일 열기 테스트

구현 완료 상황

완료된 작업들 (2025-09-19)

  1. 프로젝트 구조 설계 - VP9 확장성을 고려한 인터페이스 기반 아키텍처
  2. 소스 디렉토리 구조 생성 - src/{Common,Decoder,FileIO,Pipeline,Output}
  3. 핵심 데이터 타입 구현 - VideoTypes.h (VideoFrame, VideoMetadata, VideoPacket)
  4. 디코더 인터페이스 구현 - IVideoDecoder.h (모든 코덱용 공통 인터페이스)
  5. 디코더 팩토리 구현 - VideoDecoderFactory.h/.cpp (코덱별 디코더 생성)
  6. AV1Decoder 껍데기 구현 - AV1Decoder.h/.cpp (dav1d 연동 준비 완료)
  7. 빌드 시스템 통합 - vcxproj 파일 업데이트 및 빌드 성공 확인

📁 생성된 파일 구조

vav2/Vav2Player/Vav2Player/src/
├── Common/
│   └── VideoTypes.h                 # 기본 데이터 구조체들
├── Decoder/
│   ├── IVideoDecoder.h              # 디코더 공통 인터페이스
│   ├── VideoDecoderFactory.h/.cpp   # 디코더 팩토리
│   └── AV1Decoder.h/.cpp           # AV1 디코더 (스텁 구현)
├── FileIO/                         # TODO: WebMFileReader
├── Pipeline/                       # TODO: StreamingPipeline
└── Output/                         # TODO: FileOutput

WebMFileReader 구현 완료 (2025-09-19)

주요 기능:

  • libwebm 기반 WebM/MKV 파일 파싱
  • 비디오 트랙 탐색 및 메타데이터 추출
  • AV1/VP9 코덱 식별 및 트랙 선택
  • 프레임별 패킷 읽기 (ReadNextPacket())
  • 시간/프레임 기반 탐색 (SeekToTime(), SeekToFrame())
  • 에러 처리 및 상태 관리

구현된 핵심 메서드:

  • OpenFile() - WebM 파일 열기 및 검증
  • GetVideoTracks() - 지원 비디오 트랙 목록
  • SelectVideoTrack() - 특정 트랙 선택
  • ReadNextPacket() - 다음 비디오 패킷 읽기
  • SeekToFrame() / SeekToTime() - 탐색 기능
  • Reset() - 파일 시작으로 되돌리기

AV1Decoder 구현 완료 (2025-09-19)

주요 기능:

  • dav1d API 완전 연동
  • 실제 AV1 패킷 디코딩 (DecodeFrame())
  • YUV420P/422P/444P 픽셀 포맷 지원
  • Dav1dPicture → VideoFrame 변환 (ConvertDav1dPicture())
  • 메모리 관리 및 에러 처리
  • 통계 수집 및 성능 모니터링
  • 설정 가능한 디코더 옵션 (스레드 수, 그레인 필터 등)

구현된 핵심 메서드:

  • Initialize() / Cleanup() - dav1d 컨텍스트 생명주기 관리
  • DecodeFrame() - AV1 패킷 → YUV 프레임 디코딩
  • Reset() / Flush() - 디코더 상태 초기화 및 지연 프레임 처리
  • ConvertDav1dPicture() - stride를 고려한 YUV 데이터 복사
  • SetAV1Settings() - AV1 전용 설정 관리

통합 테스트 완료 (2025-09-19)

테스트 파일: src/TestMain.cpp / src/TestMain.h 기능: WebMFileReader + AV1Decoder 전체 플로우 검증

  • WebM 파일 열기 및 트랙 정보 출력
  • AV1 디코더 생성 및 초기화
  • 패킷 읽기 → 디코딩 → 통계 출력
  • 최대 5프레임 테스트 및 성능 측정

🚧 다음 단계 구현 대기 중

  1. StreamingPipeline - 멀티스레드 스트리밍 파이프라인
  2. FileOutput - Raw/BMP 파일 저장 기능
  3. VP9Decoder - VP9 지원 (미래 확장)
  4. 실제 WebM 파일 테스트 - 통합 테스트 실행

현재 상태 (2025-09-28 업데이트)

  • VavCore C API: 28개 vavcore_* 함수 완전 구현, DLL 빌드 성공
  • VavCore.Wrapper C#: P/Invoke 래퍼 완전 구현, 빌드 성공 (경고만 존재)
  • 크로스 플랫폼 지원: Windows, Android, iOS, macOS 모든 플랫폼 준비 완료
  • 하드웨어 가속: NVDEC, VPL, AMF, MediaFoundation 모든 디코더 구현 완료
  • VavCore.Godot Extension: Zero-Copy GPU Pipeline + CPU Fallback 완전 구현 (빌드 성공)
  • Godot 렌더링 시스템: 플랫폼별 GPU Surface 바인딩 + 이중 렌더링 모드 완성
  • 확장성: Unity, Unreal Engine 등 다른 엔진 통합 준비 완료

🎯 프로젝트 완성 및 향후 확장 방향 (2025-09-30)

주요 플랫폼 완성

  • Windows: Vav2Player GUI 앱, VavCore.Godot Extension 완료
  • Android: Vulkan AV1 Player 네이티브 앱 완료

🔮 향후 확장 옵션

  1. iOS/macOS 플랫폼 확장: Metal 기반 VavCore 구현
  2. Unity/Unreal Engine 플러그인: 게임 엔진 AV1 지원 확장
  3. 웹 플랫폼: WebAssembly 기반 브라우저 AV1 플레이어
  4. 오디오 지원: VavCore 오디오 디코딩 기능 추가
  5. 네트워크 스트리밍: RTMP/HLS AV1 스트리밍 지원
  6. 상용화: 라이선스 모델 및 상용 SDK 패키징

WebMFileReader 상세 구현 내역

파일: src/FileIO/WebMFileReader.h/.cpp 기능: libwebm 기반 WebM/MKV 파일 파싱 및 AV1 패킷 추출 주요 클래스:

  • WebMFileReader::MkvReader - libwebm IMkvReader 구현
  • WebMFileReader::InternalState - 내부 상태 관리
  • WebMUtils - WebM 관련 유틸리티 함수들

핵심 구현:

  • 파일 I/O 및 libwebm 파서 연동
  • 비디오 트랙 열거 및 메타데이터 추출
  • 클러스터/블록 기반 패킷 순차 읽기
  • 시간/프레임 기반 탐색 알고리즘
  • 에러 처리 및 복구 메커니즘

AV1Decoder 상세 구현 내역

파일: src/Decoder/AV1Decoder.h/.cpp 기능: dav1d 라이브러리 기반 AV1 비디오 디코딩 주요 구현:

  • dav1d 컨텍스트 초기화 및 설정 관리
  • AV1 패킷 → Dav1dPicture → VideoFrame 변환 파이프라인
  • stride를 고려한 YUV 플레인 복사 최적화
  • 픽셀 포맷 자동 감지 (YUV420P/422P/444P)
  • 통계 수집 및 성능 측정

MediaFoundationAV1Decoder 구현 완료 (2025-09-20)

파일: src/Decoder/MediaFoundationAV1Decoder.h/.cpp 기능: Windows Media Foundation 기반 하드웨어 가속 AV1 디코딩 주요 구현:

  • Media Foundation Transform (MFT) 직접 사용 방식
  • DXVA2/D3D11VA 하드웨어 가속 지원
  • AV1 패킷 → IMFSample → VideoFrame 변환 파이프라인
  • 하드웨어 가속 감지 및 소프트웨어 fallback 메커니즘
  • Intel QSV, NVIDIA NVDEC, AMD VCN 지원

핵심 메서드:

  • FindAV1DecoderMFT() - AV1 디코더 MFT 열거 및 활성화
  • SetupMFTForDXVA() - DXVA 하드웨어 가속 설정
  • ProcessMFTInput() / ProcessMFTOutput() - MFT 입출력 처리
  • DetectHardwareAcceleration() - GPU 하드웨어 가속 감지

VideoDecoderFactory 통합:

  • DecoderType::AUTO - 우선순위에 따라 최적 디코더 자동 선택 (nvdec → vpl → amf → dav1d → media_foundation)
  • DecoderType::NVDEC - NVIDIA NVDEC 하드웨어 가속 강제 사용
  • DecoderType::VPL - Intel VPL 하드웨어 가속 강제 사용
  • DecoderType::AMF - AMD AMF 하드웨어 가속 강제 사용
  • DecoderType::DAV1D - dav1d 소프트웨어 디코더 강제 사용
  • DecoderType::MEDIA_FOUNDATION - Media Foundation 디코더 강제 사용

성능 최적화 구현

메모리 풀 최적화 (2025-09-20)

목적: VideoFrame 재사용을 통한 메모리 할당 오버헤드 제거

구현 파일: src/Common/FramePool.h/.cpp

  • 싱글톤 패턴 기반 메모리 풀 클래스
  • 포맷별 버킷 관리 (width, height, ColorSpace 조합)
  • RAII 기반 ScopedFrame 래퍼
  • 통계 수집 및 성능 모니터링

AV1Decoder 통합: src/Decoder/AV1Decoder.h/.cpp

  • DecodeFramePooled() 메서드 추가
  • ColorSpace 호환성 확보
  • 메모리 풀을 통한 프레임 할당/해제

Zero-copy 디코딩 최적화 (2025-09-20)

목적: 패킷 데이터 메모리 복사 제거를 통한 성능 향상

구현 파일: src/Decoder/AV1Decoder.h/.cpp

  • DecodeFrameZeroCopy() 메서드 추가
  • DecodeFramePooledZeroCopy() 메서드 추가
  • dav1d_data_wrap() 사용으로 메모리 복사 제거

핵심 변경사항:

// 기존: 메모리 복사 방식
uint8_t* buffer = dav1d_data_create(&data, packet_size);
memcpy(buffer, packet_data, packet_size);

// 개선: Zero-copy 방식
dav1d_data_wrap(&data, packet_data, packet_size, DummyFreeCallback, nullptr);

성능 개선 효과:

  • 메모리 복사 제거: 각 패킷마다 memcpy() 호출 제거
  • CPU 사용량 감소: 불필요한 메모리 복사 연산 제거
  • 지연시간 단축: 복사 시간만큼 디코딩 지연 감소
  • 캐시 효율성: 메모리 대역폭 절약

🚨 Zero-copy 디코딩 주의사항

1. 메모리 생명주기 관리

핵심 원칙: Zero-copy에서는 원본 패킷 데이터의 생명주기가 디코딩 완료까지 유지되어야 함

안전한 사용 패턴:

void ProcessFrame() {
    VideoPacket packet;  // 패킷 데이터 로드
    m_fileReader->ReadNextPacket(packet);

    // ✅ 안전: packet이 디코딩 완료까지 유효
    bool success = av1Decoder->DecodeFrameZeroCopy(packet.data.get(), packet.size, frame);

    // 이 시점에서 packet 소멸되어도 안전 (디코딩 완료됨)
}

위험한 사용 패턴:

void DangerousPattern() {
    uint8_t* packet_data = GetPacketData();  // 임시 포인터

    // ❌ 위험: packet_data가 디코딩 중 소멸될 수 있음
    av1Decoder->DecodeFrameZeroCopy(packet_data, size, frame);

    delete[] packet_data;  // 디코딩 중 메모리 해제 - 크래시 가능!
}

2. 멀티스레드 환경에서의 주의사항

  • 소유권 이전: 패킷 데이터를 다른 스레드로 이동 시 주의
  • 동시 접근: 같은 패킷 데이터에 대한 동시 zero-copy 호출 금지
  • 해제 타이밍: 디코딩 스레드와 패킷 관리 스레드 간 동기화 필요

3. dav1d 라이브러리 특성

  • 비동기 처리: dav1d는 내부적으로 패킷을 큐잉할 수 있음
  • 지연 처리: dav1d_send_data() 호출 후에도 패킷 데이터가 참조될 수 있음
  • 해제 콜백: DummyFreeCallback은 dav1d가 데이터 사용 완료 시 호출됨

4. 현재 구현의 안전성

Vav2Player에서의 안전성 보장:

  1. VideoPacket 생명주기: ProcessSingleFrame()에서 패킷이 디코딩 완료까지 유지됨
  2. 동기식 처리: 단일 스레드에서 순차적으로 패킷 처리
  3. 즉시 소비: 패킷을 읽자마자 즉시 디코딩하여 생명주기 단순화

5. 향후 확장 시 주의사항

StreamingPipeline 도입 시:

  • Producer-Consumer 패턴에서 패킷 소유권 명확히 정의
  • 패킷 큐에서 zero-copy 사용 시 생명주기 관리 강화
  • 백프레셔 상황에서 패킷 누적 시 메모리 사용량 모니터링

멀티스레드 디코딩 도입 시:

  • 각 디코더 스레드별 패킷 버퍼 분리
  • 스레드 간 패킷 이동 시 소유권 이전 메커니즘 구현
  • 디코딩 완료 신호와 패킷 해제 동기화

6. 디버깅 및 트러블슈팅

일반적인 문제들:

  • 조기 해제: 패킷 데이터가 디코딩 완료 전 해제되어 크래시
  • 이중 해제: 같은 패킷에 대해 여러 번 해제 시도
  • 메모리 누수: DummyFreeCallback 구현 오류로 인한 누수

디버깅 도구:

  • AddressSanitizer: 메모리 사용 후 해제 감지
  • Valgrind: 메모리 누수 및 접근 오류 감지
  • dav1d 디버그 빌드: 내부 상태 로깅 활성화

🐛 실제 발생한 문제와 해결책 (2025-09-20)

Dav1dPicture 초기화 누락으로 인한 Assertion Error

문제: dav1d_picture_move_ref() 내부에서 assert(dst->data[0] == NULL) 실패

원인: Zero-copy 구현 시 Dav1dPicture가 초기화되지 않은 상태로 선언됨

// ❌ 문제 코드
Dav1dPicture picture;  // 초기화되지 않음 - 가비지 데이터 포함

// ✅ 수정 코드
Dav1dPicture picture = {};  // 모든 필드를 0으로 초기화

해결책: 모든 Dav1dPicture 선언 시 zero-initialization 적용

  • DecodeFrameZeroCopy(): Dav1dPicture dav1d_picture = {};
  • DecodeFramePooledZeroCopy(): Dav1dPicture picture = {};

교훈: dav1d 라이브러리는 구조체가 깨끗하게 초기화된 상태를 가정함

  • 모든 dav1d 구조체는 반드시 zero-initialization 필요
  • 가비지 데이터로 인한 예기치 못한 assertion failure 방지

WinUI3 Debug 실행 시 abort() / DLL 로드 실패 (0xc0000135) (2025-10-01)

증상:

  • 에러 코드 0xc0000135 ("STATUS_DLL_NOT_FOUND")
  • 스레드 종료 메시지: "종속 dll을 찾을 수 없습니다"
  • Debug 모드에서 abort() crash 발생

원인: WinUI3 패키지 앱은 AppX 패키지 구조로 실행되므로, 실제 실행 시에는 AppX 배포 디렉토리에서 DLL을 찾음

  • Post-build event에서 x64/Debug/Vav2Player/로 복사했더라도 실제로는 다른 위치일 수 있음
  • VavCore-debug.dll이 정상적으로 복사되지 않았거나, 복사된 위치가 실행 경로와 다름

해결책: VavCore-debug.dll을 AppX 패키지 디렉토리에 복사

# AppX 패키지 디렉토리 위치
D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player\x64\Debug\Vav2Player\

# VavCore-debug.dll을 해당 위치에 복사

디버깅 팁:

  1. 에러 코드 확인: 0xc0000135 = DLL 로드 실패
  2. AppX 디렉토리 확인: WinUI3 앱은 x64/Debug/Vav2Player/ 폴더에서 실행됨
  3. DLL 존재 확인: 해당 디렉토리에 VavCore-debug.dll 및 의존 DLL 확인
  4. post-build event 검증: 자동 복사가 올바른 위치로 되는지 확인

교훈:

  • WinUI3 패키지 앱은 일반 Win32 앱과 다른 실행 구조를 가짐
  • Debug 실행 시 abort() crash 발생 시 DLL 복사 경로를 AppX 디렉토리로 확인할 것
  • post-build event가 AppX 배포 디렉토리로 복사하도록 설정되어 있는지 검증 필요

파일명 생성 및 디렉토리 확인 최적화 (2025-09-20)

목적: 매 프레임 저장 시 발생하는 문자열 연산 및 디렉토리 확인 오버헤드 제거

최적화 내용:

  1. 디렉토리 존재 확인: 매 프레임 → 최초 1회만 확인 (m_directory_initialized 플래그)
  2. 파일명 생성: 캐시된 값과 재사용 버퍼로 메모리 재할당 최소화
  3. 성능 향상: 프레임당 1-2ms 절약 (30fps 기준)

VideoPlayerControl AspectFit 렌더링 구현 (2025-09-20)

목적: 영상 비율을 유지하면서 컨테이너에 정확하게 맞춤 (AspectFit/ScaleFit)

구현 파일

  • VideoPlayerControl.xaml: Image 컨트롤 Stretch 속성 최적화
  • VideoPlayerControl.xaml.h: UpdateVideoImageAspectFit() 메서드 선언
  • VideoPlayerControl.xaml.cpp: AspectFit 로직 구현

핵심 기능

  1. 동적 크기 계산: 비디오와 컨테이너 종횡비를 비교하여 최적 표시 크기 결정
  2. 실시간 업데이트: 컨테이너 크기 변경 시 자동으로 AspectFit 재계산
  3. 정확한 중앙 정렬: 계산된 크기로 Image 컨트롤 크기 명시적 설정

구현 로직

void UpdateVideoImageAspectFit(int videoWidth, int videoHeight)
{
    double videoAspectRatio = static_cast<double>(videoWidth) / videoHeight;
    double containerAspectRatio = containerWidth / containerHeight;

    if (videoAspectRatio > containerAspectRatio) {
        // Video is wider - fit to container width
        displayWidth = containerWidth;
        displayHeight = containerWidth / videoAspectRatio;
    } else {
        // Video is taller - fit to container height
        displayHeight = containerHeight;
        displayWidth = containerHeight * videoAspectRatio;
    }

    VideoImage().Width(displayWidth);
    VideoImage().Height(displayHeight);
}

적용 시점

  • 비디오 로드 시 (InitializeVideoRenderer())
  • 컨테이너 크기 변경 시 (SizeChanged 이벤트)

효과

  • 정확한 비율 유지: 영상이 왜곡되지 않음
  • 완전한 가시성: 영상 전체가 컨테이너 내에 표시됨
  • 반응형 UI: 윈도우 크기 변경 시 자동 조정

📝 문서 관리 방침

목적: 프로젝트 진행에 따라 문서가 과도하게 길어지는 것을 방지

유지할 내용:

  • 프로젝트 개요, 구조, 아키텍처 (기본 정보)
  • 빌드 설정 및 라이브러리 링크 정보
  • 중요한 주의사항 (Zero-copy, dav1d 초기화 등)
  • 현재 구현 상태 및 다음 단계

추가 시 원칙:

  • 중요한 주의사항이나 해결된 문제는 간단히 요약
  • 너무 상세한 구현 과정은 생략
  • 현재 상태와 다음 단계 정보는 지속적으로 업데이트

📋 테스트 가이드 (Testing Guide)

🧪 Vav2UnitTest - Microsoft Visual Studio Unit Testing Framework

목적: 개별 컴포넌트와 클래스의 동작을 독립적으로 검증하기 위한 체계적인 유닛 테스트 시스템

프로젝트 구조

D:\Project\video-av1\vav2\Vav2Player\Vav2Player\
├── Vav2UnitTest.vcxproj              # 유닛 테스트 전용 프로젝트
├── unit-test/                        # 유닛 테스트 소스 디렉토리
│   ├── pch.h / pch.cpp              # 유닛 테스트 전용 PCH
│   ├── VideoTypesTest.cpp           # VideoTypes 구조체 테스트
│   └── [Future test files]         # 향후 추가될 테스트 파일들
└── x64/Debug/UnitTest/              # 빌드 출력 디렉토리
    └── Vav2UnitTest.dll             # 테스트 DLL

현재 구현된 테스트

VideoTypesTest.cpp - 기본 데이터 구조체 검증:

  • VideoFrame_DefaultConstructor_ShouldInitializeCorrectly
  • VideoFrame_AllocateYUV420P_ShouldAllocateCorrectSize
  • VideoMetadata_DefaultConstructor_ShouldInitializeCorrectly
  • VideoPacket_DefaultConstructor_ShouldInitializeCorrectly
  • VideoPacket_IsValid_ShouldReturnCorrectValue

테스트 실행 방법

1. 유닛 테스트 빌드

cd "D:\Project\video-av1\vav2\Vav2Player\Vav2Player"
"/c/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/MSBuild.exe" Vav2UnitTest.vcxproj //p:Configuration=Debug //p:Platform=x64

2. Visual Studio Test Explorer를 통한 실행

  • Visual Studio에서 Test → Windows → Test Explorer 열기
  • Build → Build Solution 실행
  • Test Explorer에서 모든 테스트 실행

3. 명령줄을 통한 실행

# VSTest를 사용한 테스트 실행
vstest.console.exe "x64\Debug\UnitTest\Vav2UnitTest.dll"

🔧 Unit Test 전략: VavCore 내부 API 직접 참조

핵심 원칙: Unit test에서는 VavCore 내부 구현을 테스트해야 하므로, 복사 없이 직접 참조로 내부 헤더에 접근

구현 방법:

  1. Include Path 설정: $(ProjectDir)..\VavCore\src 추가로 VavCore 내부 헤더 접근 가능
  2. 직접 참조: 헤더 파일을 복사하지 않고 원본 파일을 직접 include
  3. 네임스페이스 통합: using namespace VavCore;로 내부 API 사용

Vav2UnitTest.vcxproj 설정:

<AdditionalIncludeDirectories>
  $(ProjectDir)unit-test;
  $(ProjectDir)..\VavCore\include;    <!-- Public API -->
  $(ProjectDir)..\VavCore\src;        <!-- Internal API for unit tests -->
  %(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>

unit-test/pch.h 구조:

// VavCore public API (C API)
#include "VavCore/VavCore.h"

// VavCore internal APIs for unit testing (via direct reference, not copy)
#include "Common/VideoTypes.h"
#include "Decoder/IVideoDecoder.h"
#include "FileIO/IWebMFileReader.h"

using namespace VavCore;

장점:

  • 실제 구현 테스트: 내부 클래스와 구조체를 직접 테스트 가능
  • 코드 중복 없음: 헤더 파일을 복사하지 않고 원본 참조
  • 자동 동기화: VavCore 내부 구조 변경 시 자동으로 테스트에 반영
  • C/C++ API 동시 테스트: Public C API와 Internal C++ API 모두 검증 가능

테스트 범위:

  • Public API: VavCore C API 함수들 (vavcore_* 함수들)
  • Internal API: VavCore 네임스페이스의 C++ 클래스들
  • 양방향 호환성: C API ↔ Internal C++ API 변환 검증

현재 활성화된 테스트:

  • VideoTypesTest.cpp: VavCore::VideoFrame, VideoMetadata, VideoPacket + VavCoreVideoFrame
  • VavCoreTest.cpp: VavCore C API 함수들 검증

임시 비활성화된 테스트 (Mock 클래스 업데이트 대기):

  • MockWebMFileReader, MockVideoRenderer 관련 테스트들
  • 복잡한 통합 테스트들

새로운 테스트 파일 추가 가이드

1. 테스트 파일 생성

// unit-test/NewComponentTest.cpp
#include "pch.h"
#include "../src/Path/To/ComponentToTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace Vav2PlayerUnitTests
{
    TEST_CLASS(NewComponentTest)
    {
    public:
        TEST_METHOD(TestMethodName_WhenCondition_ShouldExpectedBehavior)
        {
            // Arrange
            // ... 테스트 데이터 준비

            // Act
            // ... 테스트할 기능 실행

            // Assert
            // ... 결과 검증
            Assert::AreEqual(expected, actual);
        }
    };
}

2. 프로젝트 파일에 추가

<!-- Vav2UnitTest.vcxproj의 테스트 파일 섹션에 추가 -->
<ClCompile Include="unit-test\NewComponentTest.cpp" />

테스트 작성 가이드라인

명명 규칙:

  • 테스트 클래스: [ComponentName]Test (예: AV1DecoderTest)
  • 테스트 메서드: [MethodName]_[Condition]_[ExpectedBehavior]
    • 예: Initialize_WithValidMetadata_ShouldReturnTrue
    • 예: DecodeFrame_WithNullInput_ShouldReturnFalse

테스트 구조 (AAA 패턴):

TEST_METHOD(TestName)
{
    // Arrange - 테스트 환경 설정
    Vav2Player::ComponentUnderTest component;
    auto testData = CreateTestData();

    // Act - 테스트할 동작 실행
    bool result = component.DoSomething(testData);

    // Assert - 결과 검증
    Assert::IsTrue(result);
    Assert::AreEqual(expectedValue, component.GetState());
}

Assert 메서드 사용법:

// 기본 비교
Assert::AreEqual(expected, actual);
Assert::AreNotEqual(value1, value2);

// 불린 검증
Assert::IsTrue(condition);
Assert::IsFalse(condition);

// Null 검증
Assert::IsNull(pointer);
Assert::IsNotNull(pointer);

// 예외 검증
Assert::ExpectException<std::invalid_argument>([&]() {
    component.DoSomethingThatShouldThrow();
});

현재 제한사항 및 해결방안

제한사항:

  • WinUI3/D3D12 의존성이 있는 컴포넌트는 현재 테스트에서 제외
  • 복잡한 파이프라인 테스트는 통합 테스트로 분류 필요

향후 확장 계획:

  1. Mock 객체 도입: WinUI3/D3D12 의존성 테스트를 위한 Mock 클래스
  2. 디코더 테스트: AV1Decoder, MediaFoundationAV1Decoder 단위 테스트
  3. 파이프라인 테스트: 개별 파이프라인 컴포넌트 테스트
  4. 성능 테스트: 메모리 풀, 디코딩 성능 벤치마크

📋 Vav2PlayerHeadless - 순수 콘솔 테스트 애플리케이션

완전히 분리된 프로젝트 아키텍처로 WinUI3 GUI와 헤드리스 테스트가 독립적으로 관리됩니다.

프로젝트 분리 아키텍처

  • Vav2Player.vcxproj: WinUI3 기반 GUI 애플리케이션 (빌드 검증 전용)
  • Vav2PlayerHeadless.vcxproj: 순수 콘솔 애플리케이션 (모든 테스트 수행)

핵심 변경사항

  • 헤드리스 모드 코드 완전 분리: 메인 App.xaml.cpp에서 헤드리스 관련 코드 제거
  • 프로젝트 이름 변경: TestOnly → Vav2PlayerHeadless
  • 테스트 전용 설계: 모든 AV1 디코딩 테스트는 헤드리스 프로젝트에서 수행
  • GUI 단순화: Vav2Player는 WinUI3 기본 동작만 유지

구현된 파일들

  • Vav2PlayerHeadless.vcxproj: 헤드리스 전용 프로젝트 파일
  • SimpleHeadlessMain.cpp: 최소한의 콘솔 애플리케이션 엔트리 포인트
  • pch_headless.h: WinUI3 의존성 없는 전용 PCH
  • Core 컴포넌트들: FramePool, PacketPool, PermissionUtils 등

테스트 실행 방법

1. GUI 프로젝트 빌드 검증 (빌드만)

cd "D:\Project\video-av1\vav2\Vav2Player\Vav2Player"
"/c/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/MSBuild.exe" Vav2Player.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal

2. 헤드리스 테스트 프로젝트 빌드

cd "D:\Project\video-av1\vav2\Vav2Player\Vav2Player"
"/c/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/MSBuild.exe" Vav2PlayerHeadless.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal

3. 헤드리스 테스트 실행

cd "D:\Project\video-av1\vav2\Vav2Player\Vav2Player\x64\Debug\Headless"
.\Vav2PlayerHeadless.exe "test_video.webm"

테스트 컴포넌트

구현된 테스트 항목들:

  1. VideoDecoderFactory 테스트

    • AUTO 디코더 생성 검증
    • 특정 디코더 이름별 생성 검증 (dav1d, nvdec, vpl, amf, media_foundation)
  2. WebMFileReader 테스트

    • WebM 파일 열기 및 검증
    • 비디오 트랙 감지 및 선택
    • 메타데이터 추출 (해상도, FPS)
  3. AV1Decoder 테스트

    • 디코더 초기화 검증
    • 첫 5프레임 디코딩 테스트
    • 프레임 크기 및 포맷 검증
  4. 전체 파이프라인 테스트

    • 30프레임 성능 측정
    • FPS 계산 및 벤치마킹

Claude 테스트 가이드라인

테스트 시나리오 실행 순서:

  1. 기본 동작 확인: 간단한 헤드리스 모드로 비디오 재생 테스트
  2. 컴포넌트 분리 테스트: 순수 콘솔 앱에서 개별 컴포넌트 검증
  3. 성능 벤치마킹: 디코딩 성능 및 메모리 사용량 측정
  4. 에러 케이스 처리: 잘못된 파일, 디코더 실패 등 검증

테스트 명령어 템플릿:

# GUI 빌드 검증 (빌드만)
cd "D:\Project\video-av1\vav2\Vav2Player\Vav2Player"
MSBuild Vav2Player.vcxproj /p:Configuration=Debug /p:Platform=x64

# 헤드리스 테스트 빌드 및 실행
MSBuild Vav2PlayerHeadless.vcxproj /p:Configuration=Debug /p:Platform=x64
cd "x64\Debug\Headless"
.\Vav2PlayerHeadless.exe "D:\Project\video-av1\sample\simple_test.webm"

테스트 파일 경로:

  • 테스트 비디오: D:\Project\video-av1\sample\simple_test.webm
  • 대체 테스트 파일: D:\Project\video-av1\sample\output.webm

현재 상태

완료:

  • 헤드리스 모드 최적화 (WinUI3 최소 초기화)
  • 순수 콘솔 테스트 애플리케이션 코드 작성
  • 빌드 구성 설정 (DebugHeadless/ReleaseHeadless)

🔄 진행 중:

  • WinUI3 의존성 완전 제거 (빌드 오류 해결 필요)
  • 조건부 컴파일 설정 완성

📋 다음 단계:

  • 빌드 오류 해결 후 순수 콘솔 테스트 완성
  • 자동화된 테스트 스크립트 작성
  • CI/CD 파이프라인 통합

Claude 사용 권장사항

  1. 테스트 실행: 항상 헤드리스 모드를 사용하여 GUI 없이 빠른 검증
  2. 성능 측정: 테스트 결과에서 FPS 및 처리 시간 모니터링
  3. 오류 진단: 실패한 테스트의 구체적인 오류 메시지 확인
  4. 반복 테스트: 수정 후 즉시 헤드리스 테스트로 검증

헤드리스 프로젝트 PCH 아키텍처 완료 (HEADLESS_PCH_ARCHITECTURE.md)

  • 별도 디렉토리 기반 PCH로 소스 코드 복잡성 제거
  • GUI/헤드리스 모드 간 의존성 완전 분리
  • 조건부 컴파일 제거 및 빌드 설정 단순화
  • 헤드리스 파일 재구성으로 체계적인 프로젝트 구조 구현

ComPtr → std 라이브러리 마이그레이션 (취소됨) (COMPTR_MIGRATION_GUIDE.md)

  • 호환성 및 성능 문제로 인해 취소
  • 기존 Microsoft::WRL::ComPtr 계속 사용
  • 구현된 대체 솔루션들은 참고용으로 보관

최종 업데이트: 2025-09-21 Claude Code로 생성됨