52 KiB
Vav2Player - AV1 Video Player 개발 프로젝트
⚠️ CRITICAL: 코딩 규칙 및 가이드라인
📝 주석 언어 규칙 (REQUIRED)
🚨 중요: 모든 소스 코드 파일의 주석은 영어로 작성해야 합니다.
적용 범위
.h헤더 파일의 모든 주석.cpp소스 파일의 모든 주석.xaml.hWinUI 헤더 파일의 모든 주석.xaml.cppWinUI 소스 파일의 모든 주석
예시
// ❌ 잘못된 예 (한국어 주석)
// 버퍼 크기 확인 및 재할당 최소화
size_t required_size = frame.width * frame.height * 4;
// ✅ 올바른 예 (영어 주석)
// Check buffer size and minimize reallocation
size_t required_size = frame.width * frame.height * 4;
이유
- 국제화 지원: 영어 주석으로 코드의 국제적 접근성 향상
- 컴파일러 호환성: 일부 컴파일러에서 비ASCII 문자로 인한 인코딩 문제 방지
- 협업 효율성: 다양한 배경의 개발자들과의 협업 용이성
- 유지보수성: 장기적인 코드 유지보수 시 언어 장벽 제거
⚠️ 필수 조치사항
- 기존 한국어 주석 발견 시 즉시 영어로 변환
- 새로운 코드 작성 시 처음부터 영어 주석 사용
- 함수명, 변수명은 기존 명명 규칙 유지 (영어만 가능)
🚫 이모지 사용 금지 규칙 (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) 🔄
활성 설계 문서
- VavCore Godot Integration - Godot 4.4.1 C# Extension 구현 현황 ✅
- Android Vulkan AV1 Player Design - Android Vulkan Surface 기반 AV1 Player 설계 ✅
완료된 프로젝트 아카이브
- 📋 Complete Projects Archive - 완료된 20개 미니 프로젝트 (하드웨어 가속, 성능 최적화, 테스트, 크로스 플랫폼, 아키텍처 설계, Godot 통합)
✅ 최신 완료 작업: 주요 마일스톤 달성 (2025-09-30)
🎯 2025년 9월 최종 핵심 성과
- Android Vulkan AV1 Player 완전 완성 - Samsung Galaxy S24 최적화 완료 ✅
- MediaCodec 키워드 기반 디코더 선택 시스템 - 크로스 벤더 호환성 확보 ✅
- Vulkan 1.1 렌더링 파이프라인 완성 - YUV to RGB GPU 쉐이더 완료 ✅
- VavCore Android 네이티브 통합 - JNI C API 28개 함수 완성 ✅
- Samsung Qualcomm Snapdragon 특화 - c2.qti.av1.decoder 자동 선택 ✅
📋 완료된 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 플랫폼
- VavCore C API: 28개 vavcore_* 함수 완전 구현, DLL 빌드 성공 ✅
- 하드웨어 가속: NVIDIA NVDEC, Intel VPL, AMD AMF 모든 디코더 ✅
- VavCore.Godot Extension: Zero-Copy GPU Pipeline + CPU Fallback 완성 ✅
- Vav2Player GUI: WinUI3 애플리케이션 완전 구현 ✅
- D3D12 렌더링: YUV to RGB GPU 쉐이더, AspectFit 스케일링 ✅
- 빌드 & 테스트: 47개 Unit Test, 헤드리스 테스트 완료 ✅
Android 플랫폼
- Android Vulkan AV1 Player: 완전한 네이티브 Android 앱 구현 ✅
- MediaCodec 하드웨어 가속: 키워드 기반 디코더 선택, 크로스 벤더 호환성 ✅
- VavCore Android JNI: C API 28개 함수 Android NDK 연동 완료 ✅
- Vulkan 1.1 렌더링: YUV to RGB GPU 쉐이더, AspectFit 스케일링 ✅
- Samsung Galaxy S24 최적화: Qualcomm Snapdragon c2.qti.av1.decoder 특화 ✅
- 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 업데이트)
✅ 구현 완료된 주요 컴포넌트
- Core Video Infrastructure: WebMFileReader, AV1Decoder, VideoDecoderFactory ✅
- Hardware Acceleration: NVDECAV1Decoder, CUDA 13.0 통합, NVDEC 우선 디코더 설정 ✅
- Adaptive Quality Control: AdaptiveAV1Decoder, AdaptiveNVDECDecoder 완전 구현 ✅
- Quality Mode System: CONSERVATIVE, FAST, ULTRA_FAST 모드 구현 및 최적화 ✅
- GPU Rendering System: SimpleGPURenderer, D3D12VideoRenderer 구현 ✅
- UI Integration: VideoPlayerControl 단순화 및 WinUI3 통합 ✅
- Build System: 모든 프로젝트 빌드 성공 (GUI/Headless/UnitTest) ✅
- Test Infrastructure: 47개 Unit Test, Mock 시스템, NVDEC 헤드리스 테스트 구축 ✅
- Code Quality: 한글 주석 → 영어 변환, 코딩 가이드라인 준수, VavCore 네임스페이스 통일 ✅
- Performance Optimization: 4K AV1 디코딩 27.7fps 달성 (ULTRA_FAST 모드) ✅
- ✅ Project Structure Reorganization: VavCore_Library_Design.md 구조 완전 적용 (2025-09-25) ✅
- ✅ Multi Video UI Enhancement: MultiVideoTestPage → MultiVideoPage 이름 변경 및 기능 완성 (2025-09-25) ✅
- ✅ 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]
핵심 컴포넌트
- WebMFileReader: libwebm 기반 파일 파싱
- AV1Decoder: dav1d 기반 프레임 디코딩
- StreamingPipeline: 멀티스레드 스트리밍 관리
- 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단계 구현 시작: WebMFileReader 클래스 구현
- 프로젝트 설정: vcxproj 파일에 include/lib 경로 및 종속성 추가
- 기본 테스트: 간단한 WebM 파일 열기 테스트
구현 완료 상황
✅ 완료된 작업들 (2025-09-19)
- 프로젝트 구조 설계 - VP9 확장성을 고려한 인터페이스 기반 아키텍처
- 소스 디렉토리 구조 생성 -
src/{Common,Decoder,FileIO,Pipeline,Output} - 핵심 데이터 타입 구현 -
VideoTypes.h(VideoFrame, VideoMetadata, VideoPacket) - 디코더 인터페이스 구현 -
IVideoDecoder.h(모든 코덱용 공통 인터페이스) - 디코더 팩토리 구현 -
VideoDecoderFactory.h/.cpp(코덱별 디코더 생성) - AV1Decoder 껍데기 구현 -
AV1Decoder.h/.cpp(dav1d 연동 준비 완료) - 빌드 시스템 통합 - 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프레임 테스트 및 성능 측정
🚧 다음 단계 구현 대기 중
- StreamingPipeline - 멀티스레드 스트리밍 파이프라인
- FileOutput - Raw/BMP 파일 저장 기능
- VP9Decoder - VP9 지원 (미래 확장)
- 실제 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 네이티브 앱 완료 ✅
🔮 향후 확장 옵션
- iOS/macOS 플랫폼 확장: Metal 기반 VavCore 구현
- Unity/Unreal Engine 플러그인: 게임 엔진 AV1 지원 확장
- 웹 플랫폼: WebAssembly 기반 브라우저 AV1 플레이어
- 오디오 지원: VavCore 오디오 디코딩 기능 추가
- 네트워크 스트리밍: RTMP/HLS AV1 스트리밍 지원
- 상용화: 라이선스 모델 및 상용 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에서의 안전성 보장:
- VideoPacket 생명주기:
ProcessSingleFrame()에서 패킷이 디코딩 완료까지 유지됨 - 동기식 처리: 단일 스레드에서 순차적으로 패킷 처리
- 즉시 소비: 패킷을 읽자마자 즉시 디코딩하여 생명주기 단순화
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 방지
✅ 파일명 생성 및 디렉토리 확인 최적화 (2025-09-20)
목적: 매 프레임 저장 시 발생하는 문자열 연산 및 디렉토리 확인 오버헤드 제거
최적화 내용:
- 디렉토리 존재 확인: 매 프레임 → 최초 1회만 확인 (
m_directory_initialized플래그) - 파일명 생성: 캐시된 값과 재사용 버퍼로 메모리 재할당 최소화
- 성능 향상: 프레임당 1-2ms 절약 (30fps 기준)
✅ VideoPlayerControl AspectFit 렌더링 구현 (2025-09-20)
목적: 영상 비율을 유지하면서 컨테이너에 정확하게 맞춤 (AspectFit/ScaleFit)
구현 파일
VideoPlayerControl.xaml: Image 컨트롤 Stretch 속성 최적화VideoPlayerControl.xaml.h:UpdateVideoImageAspectFit()메서드 선언VideoPlayerControl.xaml.cpp: AspectFit 로직 구현
핵심 기능
- 동적 크기 계산: 비디오와 컨테이너 종횡비를 비교하여 최적 표시 크기 결정
- 실시간 업데이트: 컨테이너 크기 변경 시 자동으로 AspectFit 재계산
- 정확한 중앙 정렬: 계산된 크기로 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_ShouldInitializeCorrectlyVideoFrame_AllocateYUV420P_ShouldAllocateCorrectSizeVideoMetadata_DefaultConstructor_ShouldInitializeCorrectlyVideoPacket_DefaultConstructor_ShouldInitializeCorrectlyVideoPacket_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 내부 구현을 테스트해야 하므로, 복사 없이 직접 참조로 내부 헤더에 접근
구현 방법:
- Include Path 설정:
$(ProjectDir)..\VavCore\src추가로 VavCore 내부 헤더 접근 가능 - 직접 참조: 헤더 파일을 복사하지 않고 원본 파일을 직접 include
- 네임스페이스 통합:
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 + VavCoreVideoFrameVavCoreTest.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 의존성이 있는 컴포넌트는 현재 테스트에서 제외
- 복잡한 파이프라인 테스트는 통합 테스트로 분류 필요
향후 확장 계획:
- Mock 객체 도입: WinUI3/D3D12 의존성 테스트를 위한 Mock 클래스
- 디코더 테스트: AV1Decoder, MediaFoundationAV1Decoder 단위 테스트
- 파이프라인 테스트: 개별 파이프라인 컴포넌트 테스트
- 성능 테스트: 메모리 풀, 디코딩 성능 벤치마크
📋 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"
테스트 컴포넌트
구현된 테스트 항목들:
-
VideoDecoderFactory 테스트
- AUTO 디코더 생성 검증
- 특정 디코더 이름별 생성 검증 (dav1d, nvdec, vpl, amf, media_foundation)
-
WebMFileReader 테스트
- WebM 파일 열기 및 검증
- 비디오 트랙 감지 및 선택
- 메타데이터 추출 (해상도, FPS)
-
AV1Decoder 테스트
- 디코더 초기화 검증
- 첫 5프레임 디코딩 테스트
- 프레임 크기 및 포맷 검증
-
전체 파이프라인 테스트
- 30프레임 성능 측정
- FPS 계산 및 벤치마킹
Claude 테스트 가이드라인
테스트 시나리오 실행 순서:
- 기본 동작 확인: 간단한 헤드리스 모드로 비디오 재생 테스트
- 컴포넌트 분리 테스트: 순수 콘솔 앱에서 개별 컴포넌트 검증
- 성능 벤치마킹: 디코딩 성능 및 메모리 사용량 측정
- 에러 케이스 처리: 잘못된 파일, 디코더 실패 등 검증
테스트 명령어 템플릿:
# 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 사용 권장사항
- 테스트 실행: 항상 헤드리스 모드를 사용하여 GUI 없이 빠른 검증
- 성능 측정: 테스트 결과에서 FPS 및 처리 시간 모니터링
- 오류 진단: 실패한 테스트의 구체적인 오류 메시지 확인
- 반복 테스트: 수정 후 즉시 헤드리스 테스트로 검증
✅ 헤드리스 프로젝트 PCH 아키텍처 완료 (HEADLESS_PCH_ARCHITECTURE.md)
- 별도 디렉토리 기반 PCH로 소스 코드 복잡성 제거
- GUI/헤드리스 모드 간 의존성 완전 분리
- 조건부 컴파일 제거 및 빌드 설정 단순화
- 헤드리스 파일 재구성으로 체계적인 프로젝트 구조 구현
❌ ComPtr → std 라이브러리 마이그레이션 (취소됨) (COMPTR_MIGRATION_GUIDE.md)
- 호환성 및 성능 문제로 인해 취소
- 기존
Microsoft::WRL::ComPtr계속 사용 - 구현된 대체 솔루션들은 참고용으로 보관
최종 업데이트: 2025-09-21 Claude Code로 생성됨