Files
video-v1/vav2/docs/completed/optimization/MAJOR_REFACTORING_GUIDE.md
2025-09-28 17:10:41 +09:00

312 lines
9.9 KiB
Markdown

# 🔥 MAJOR REFACTORING GUIDE - 기술 부채 제거 및 코드 간소화
**⚠️ CRITICAL: 이 문서는 현재 진행 중인 대규모 리팩토링의 핵심 가이드입니다.**
**AI 토큰 절약 및 작업 연속성을 위해 반드시 읽고 따라야 합니다.**
---
## 🎯 **리팩토링 목표**
### **근본 문제 인식**
현재 codebase는 **"방어적 코딩"**으로 증상만 치료하고 있습니다:
- ResourceBarrier NULL 포인터 → NULL 체크 추가 (❌ 증상 치료)
- GPU 리소스 생성 실패 → 더 많은 fallback 로직 (❌ 복잡도 증가)
- 초기화 순서 문제 → 더 많은 상태 체크 (❌ 기술 부채 증가)
### **해결 철학: "삭제 후 올바른 재설계" (Delete & Redesign Properly)**
> **"잘못된 고성능 구현" < "올바른 설계 기반 구현"**
**현재 파이프라인 문제점:**
- **과도한 추상화**: 3단계 복잡한 파이프라인으로 성능 저하
- **잘못된 리소스 관리**: NULL placeholder로 인한 크래시 다발
- **역효과적 멀티스레드**: 오버헤드 > 실제 성능 향상
- **디버깅 불가능**: 복잡한 상태 머신으로 문제 추적 불가
**목표:**
1. **즉시 목표**: 안정적인 CPU 기반 재생 (6800 → 800 라인)
2. **최종 목표**: 올바른 GPU 파이프라인 재설계 (단순하지만 효율적)
---
## 📋 **단계별 실행 계획**
### **🎯 전체 로드맵**
#### **1단계: 잘못된 파이프라인 제거** (현재 진행 중)
- 복잡한 멀티스레드 파이프라인 삭제
- 안정적인 CPU 기반 재생 확보
#### **2단계: 올바른 GPU 파이프라인 재설계** (향후)
```cpp
// 새로운 단순 설계
CPU Thread: VideoPacket AV1Decode YUV Frame
(Zero-copy handoff)
GPU Thread: YUV Frame D3D12 Upload YUVRGB Shader Screen
```
#### **3단계: 점진적 최적화** (최종)
- 이중 버퍼링으로 CPU-GPU 병렬화
- 프로파일링 기반 성능 튜닝
---
### **🗑️ Phase 1: 잘못된 파이프라인 완전 제거**
#### **1.1 제거 대상 파일들 (즉시 삭제)**
```bash
# Pipeline 디렉토리 전체 제거
rm -rf src/Pipeline/ThreadedDecoder.*
rm -rf src/Pipeline/OverlappedProcessor.*
rm -rf src/Pipeline/DependencyScheduler.*
# 복잡한 GPU 관리 제거
rm -rf src/Rendering/CommandListPool.*
rm -rf src/Rendering/DirectTextureAllocator.*
# 사용하지 않는 유틸리티 제거
rm -rf src/Common/PacketPool.*
rm -rf src/Common/FramePool.*
```
#### **1.2 VideoPlayerControl.xaml.h 단순화**
```cpp
// 제거할 복잡한 멤버들
std::unique_ptr<::Vav2Player::ThreadedDecoder> m_threadedDecoder;
std::unique_ptr<::Vav2Player::OverlappedProcessor> m_overlappedProcessor;
std::shared_ptr<::Vav2Player::DependencyScheduler> m_dependencyScheduler;
std::shared_ptr<::Vav2Player::FrameDependencyScheduler> m_frameScheduler;
bool m_useMultiThreadedDecoding = true;
bool m_useOverlappedPipeline = true;
bool m_useDependencyScheduling = true;
// 유지할 핵심 멤버들
std::unique_ptr<WebMFileReader> m_fileReader;
std::unique_ptr<IVideoDecoder> m_decoder;
std::unique_ptr<D3D12VideoRenderer> m_d3d12Renderer; // 선택적
```
#### **1.3 제거할 복잡한 메서드들**
```cpp
// VideoPlayerControl.xaml.cpp에서 완전 삭제
void InitializeThreadedDecoder();
void ShutdownThreadedDecoder();
void InitializeOverlappedProcessor();
void ShutdownOverlappedProcessor();
void InitializeDependencyScheduler();
void ShutdownDependencyScheduler();
void ProcessSingleFrameThreaded();
void ProcessSingleFrameOverlapped();
void ProcessSingleFrameScheduled();
bool SubmitPacketForDecoding();
bool SubmitPacketForOverlappedProcessing();
bool SubmitFrameForScheduledProcessing();
```
### **🔧 Phase 2: 단순 처리 경로로 통합**
#### **2.1 ProcessSingleFrame() 대폭 단순화**
```cpp
// BEFORE: 1000+ 라인의 복잡한 분기 처리
void ProcessSingleFrame() {
if (m_useDependencyScheduling && m_frameScheduler) {
ProcessSingleFrameScheduled();
} else if (m_useOverlappedPipeline && m_overlappedProcessor) {
ProcessSingleFrameOverlapped();
} else if (m_useMultiThreadedDecoding && m_threadedDecoder) {
ProcessSingleFrameThreaded();
} else {
ProcessSingleFrameLegacy();
}
}
// AFTER: 10라인의 단순 선형 처리
void ProcessSingleFrame() {
VideoPacket packet;
if (!m_fileReader->ReadNextPacket(packet)) return;
VideoFrame frame;
if (!m_decoder->DecodeFrame(packet, frame)) return;
RenderFrameToScreen(frame); // 단일 렌더링 경로
}
```
#### **2.2 RenderFrameToScreen() 단순화**
```cpp
void RenderFrameToScreen(const VideoFrame& frame) {
// GPU 렌더링 시도 (선택적)
if (m_useHardwareRendering && m_d3d12Renderer && m_d3d12Renderer->IsInitialized()) {
if (m_d3d12Renderer->TryRenderFrame(frame)) {
return; // 성공하면 완료
}
}
// CPU 렌더링 (항상 동작하는 fallback)
RenderFrameSoftware(frame);
}
```
### **🧹 Phase 3: 프로젝트 파일 정리**
#### **3.1 Vav2Player.vcxproj 정리**
```xml
<!-- 제거할 파일 참조들 -->
<ClCompile Include="src\Pipeline\ThreadedDecoder.cpp" />
<ClCompile Include="src\Pipeline\OverlappedProcessor.cpp" />
<ClCompile Include="src\Pipeline\DependencyScheduler.cpp" />
<ClCompile Include="src\Rendering\CommandListPool.cpp" />
<ClCompile Include="src\Common\PacketPool.cpp" />
<ClCompile Include="src\Common\FramePool.cpp" />
<!-- 유지할 핵심 파일들 -->
<ClCompile Include="src\FileIO\WebMFileReader.cpp" />
<ClCompile Include="src\Decoder\AV1Decoder.cpp" />
<ClCompile Include="src\Decoder\MediaFoundationAV1Decoder.cpp" />
<ClCompile Include="src\Rendering\D3D12VideoRenderer.cpp" />
```
---
## 🎯 **단계별 아키텍처 목표**
### **Phase 1 완료 후: 단순 안정화 아키텍처**
```
VideoPlayerControl
├── WebMFileReader (파일 파싱)
├── IVideoDecoder (AV1 디코딩)
└── SoftwareRenderer (CPU 렌더링, 100% 안정)
```
### **Phase 2 목표: 올바른 GPU 파이프라인**
```
VideoPlayerControl
├── WebMFileReader (파일 파싱)
├── IVideoDecoder (AV1 디코딩)
├── GPUTextureUploader (효율적 GPU 업로드)
├── YUVToRGBConverter (GPU 셰이더)
└── D3D12Presenter (화면 출력)
```
### **단계별 데이터 플로우**
```
Phase 1: WebM → Packet → Frame → CPU Render → Screen
Phase 2: WebM → Packet → Frame → GPU Pipeline → Screen
(Zero-copy, 단순 병렬)
```
### **코드 크기 목표**
| 컴포넌트 | 현재 | 목표 | 감소율 |
|----------|------|------|--------|
| VideoPlayerControl.xaml.cpp | 2500줄 | 400줄 | -84% |
| Pipeline/* | 3000줄 | 0줄 | -100% |
| Rendering/* | 1500줄 | 800줄 | -47% |
| **전체** | **7000줄** | **1200줄** | **-83%** |
---
## ⚠️ **중요한 설계 원칙**
### **1. 단순성 우선 (Simplicity First)**
- **복잡한 최적화 < 단순한 동작**
- **멀티스레드 < 단일스레드 + 빠른 디코더**
- **GPU 파이프라인 < CPU 렌더링 + 선택적 GPU**
### **2. 확실성 우선 (Reliability First)**
- **100% 동작하는 기본 기능 > 50% 동작하는 고급 기능**
- **NULL 체크보다 NULL 생성 방지**
- **방어 코딩보다 원인 제거**
### **3. 유지보수성 우선 (Maintainability First)**
- **선형 처리 경로 > 복잡한 상태 머신**
- **명확한 에러 처리 > 복잡한 fallback**
- **적은 코드 > 많은 기능**
---
## 🚨 **작업 중 주의사항**
### **절대 하지 말 것**
**방어 코딩 추가**: NULL 체크, try-catch 남발
**기능 추가**: 새로운 파이프라인이나 최적화
**점진적 수정**: 기존 복잡한 코드를 조금씩 고치기
### **반드시 할 것**
**코드 삭제**: 의심스러우면 삭제
**단순화**: 복잡한 분기를 선형 처리로
**테스트**: 각 단계마다 기본 동작 확인
---
## 📝 **진행 상황 체크리스트**
### **Phase 1: 파이프라인 제거**
- [ ] ThreadedDecoder.* 삭제
- [ ] OverlappedProcessor.* 삭제
- [ ] DependencyScheduler.* 삭제
- [ ] CommandListPool.* 삭제
- [ ] VideoPlayerControl.xaml.h 멤버 정리
- [ ] VideoPlayerControl.xaml.cpp 메서드 정리
### **Phase 2: 로직 단순화**
- [ ] ProcessSingleFrame() 단순화 (1000줄→10줄)
- [ ] RenderFrameToScreen() 단순화
- [ ] LoadVideo() 초기화 로직 단순화
- [ ] 에러 처리 단순화
### **Phase 3: 프로젝트 정리**
- [ ] .vcxproj 파일 정리
- [ ] 빌드 테스트
- [ ] 기본 동작 테스트 (비디오 재생)
- [ ] 코드 라인 수 측정
---
## 🔄 **중간 중단 시 재시작 가이드**
### **상황 파악 질문**
1. "현재 어느 Phase까지 완료되었나?"
2. "빌드가 성공하는가?"
3. "기본 비디오 재생이 동작하는가?"
### **빠른 재시작 명령어**
```bash
# 1. 현재 상태 확인
find src/ -name "*.cpp" | grep -E "(Threaded|Overlapped|Dependency)" | wc -l
# 2. 빌드 테스트
cd "D:/Project/video-av1/vav2/Vav2Player/Vav2Player"
MSBuild Vav2Player.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal
# 3. 헤드리스 테스트
cd "x64/Debug/Headless"
./Vav2PlayerHeadless.exe "D:/Project/video-av1/sample/simple_test.webm"
```
### **우선순위 복구 순서**
1. **빌드 수정** (컴파일 에러 해결)
2. **기본 동작 복구** (ProcessSingleFrame 단순화)
3. **불필요한 코드 삭제** (Phase 1 계속)
---
## 💡 **성공 지표**
### **정량적 지표**
- 전체 코드 라인 수: < 1500줄
- 빌드 시간: < 30초
- 메모리 사용량: < 100MB
- 비디오 재생 성공률: 100%
### **정성적 지표**
- 코드 이해하기 쉬움
- 디버깅 시간 단축
- 새 기능 추가 용이성
- 크래시 발생률 0%
---
**⚡ 핵심 메시지: "삭제가 최고의 디버깅이다"**
*문서 작성일: 2025-09-21*
*최종 업데이트: 진행 중*