# Android Vulkan AV1 Player 설계 문서 **프로젝트**: VavCore Android Vulkan Surface AV1 Player **날짜**: 2025-09-29 **상태**: 🚧 설계 단계 **플랫폼**: Android (API Level 29+, Vulkan 1.0+) --- ## 🎯 **프로젝트 개요** Android에서 Vulkan Surface를 사용하여 직접 렌더링하는 고성능 AV1 비디오 플레이어를 구현합니다. VavCore JNI 라이브러리와 Android MediaCodec 하드웨어 가속을 활용하여 최적의 성능을 달성합니다. ### **핵심 목표** - **Vulkan Direct Rendering**: CPU 메모리 복사 없이 GPU Surface 직접 렌더링 - **하드웨어 가속**: MediaCodec + Vulkan 파이프라인으로 최대 성능 달성 - **실시간 성능**: 4K AV1 비디오 60fps 재생 목표 - **사용자 경험**: 직관적인 비디오 컨트롤 UI --- ## 🏗️ **전체 아키텍처** ### **시스템 구성도** ``` ┌─────────────────────────────────────────────────────────────┐ │ Android Application Layer │ ├─────────────────────────────────────────────────────────────┤ │ Java/Kotlin UI │ VulkanVideoView (Custom View) │ │ - Load Video Button │ - Vulkan Surface │ │ - Play/Pause/Stop │ - YUV → RGB Conversion │ │ - Progress Bar │ - AspectFit Rendering │ │ - Performance Stats │ - Touch Controls │ ├─────────────────────────────────────────────────────────────┤ │ JNI Bridge Layer │ │ - VavCore JNI Wrapper │ - Vulkan JNI Native │ │ - Video Control APIs │ - Surface Management │ │ - Performance Metrics │ - Texture Binding │ ├─────────────────────────────────────────────────────────────┤ │ Native C++ Layer │ │ VavCore Library │ Vulkan Renderer │ │ - MediaCodec Decoder │ - VkSurface Creation │ │ - dav1d Fallback │ - YUV Shader Pipeline │ │ - Frame Management │ - Command Buffer Management │ ├─────────────────────────────────────────────────────────────┤ │ Hardware Layer │ │ Android MediaCodec │ Vulkan GPU Driver │ │ - AV1 HW Decoding │ - GPU YUV Processing │ │ - Surface Output │ - Synchronized Rendering │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 📱 **Android 앱 구조** ### **프로젝트 디렉토리 구조** ``` vav2/platforms/android/applications/vav2player/ ├── app/ │ ├── src/main/ │ │ ├── java/com/vavcore/player/ │ │ │ ├── MainActivity.java # 메인 액티비티 │ │ │ ├── VulkanVideoView.java # 커스텀 Vulkan 뷰 │ │ │ ├── VideoController.java # 비디오 컨트롤 로직 │ │ │ └── PerformanceMonitor.java # 성능 모니터링 │ │ ├── cpp/ │ │ │ ├── vulkan_renderer.cpp # Vulkan 렌더링 엔진 │ │ │ ├── vulkan_jni.cpp # Vulkan JNI 바인딩 │ │ │ ├── yuv_shader.cpp # YUV → RGB 쉐이더 │ │ │ └── surface_manager.cpp # Surface 관리 │ │ ├── res/ │ │ │ ├── layout/ │ │ │ │ ├── activity_main.xml # 메인 UI 레이아웃 │ │ │ │ └── video_controls.xml # 비디오 컨트롤 UI │ │ │ ├── values/ │ │ │ │ ├── strings.xml # 문자열 리소스 │ │ │ │ └── colors.xml # 색상 테마 │ │ │ └── drawable/ # 아이콘 리소스 │ │ └── AndroidManifest.xml # 앱 매니페스트 │ ├── build.gradle # 앱 빌드 설정 │ └── CMakeLists.txt # 네이티브 빌드 설정 ├── vavcore/ # VavCore JNI 모듈 (기존) └── build.gradle # 프로젝트 빌드 설정 ``` --- ## 🎮 **UI 설계** ### **메인 화면 레이아웃** ``` ┌─────────────────────────────────────────────────────────────┐ │ App Title Bar │ ├─────────────────────────────────────────────────────────────┤ │ │ │ │ │ VulkanVideoView │ │ (Vulkan Surface) │ │ │ │ │ ├─────────────────────────────────────────────────────────────┤ │ [Load Video] [Play] [Pause] [Stop] Progress: 45% │ ├─────────────────────────────────────────────────────────────┤ │ Decoder: MediaCodec | FPS: 60 | Resolution: 3840x2160 │ │ Frame Time: 12ms | GPU Memory: 245MB | Dropped: 0 │ └─────────────────────────────────────────────────────────────┘ ``` ### **UI 컴포넌트 사양** #### **VulkanVideoView (커스텀 뷰)** - **기능**: Vulkan Surface 렌더링 및 비디오 표시 - **특징**: - Touch 이벤트 처리 (탭해서 Play/Pause) - AspectFit 자동 조정 - 성능 오버레이 표시 옵션 - **크기**: Match parent (전체 화면 비율 유지) #### **비디오 컨트롤 버튼** - **Load Video**: 파일 선택 다이얼로그 → AV1 파일 로드 - **Play**: 비디오 재생 시작 - **Pause**: 재생 일시정지 (Resume 가능) - **Stop**: 재생 중지 및 처음으로 되돌리기 #### **진행률 표시** - **Progress Bar**: 현재 재생 위치 (SeekBar로 탐색 가능) - **시간 표시**: "02:34 / 05:42" 형식 #### **성능 모니터링 패널** - **디코더 정보**: 현재 사용 중인 디코더 (MediaCodec/dav1d) - **실시간 FPS**: 현재 렌더링 프레임레이트 - **해상도**: 비디오 원본 해상도 - **프레임 타임**: 디코딩 + 렌더링 시간 - **GPU 메모리**: 현재 GPU 메모리 사용량 - **드롭된 프레임**: 성능 부족으로 건너뛴 프레임 수 --- ## 🔧 **Vulkan 렌더링 엔진** ### **Vulkan 파이프라인 설계** #### **1. Vulkan 초기화 시퀀스** ```cpp // 1. Vulkan Instance 생성 VkInstance instance; VkApplicationInfo appInfo = {}; appInfo.pApplicationName = "VavCore AV1 Player"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "VavCore Vulkan Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; // 2. Android Surface 생성 VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo = {}; surfaceCreateInfo.window = androidWindow; // ANativeWindow* // 3. Physical Device 및 Queue Family 선택 VkPhysicalDevice physicalDevice; uint32_t graphicsQueueFamilyIndex; uint32_t presentQueueFamilyIndex; // 4. Logical Device 생성 VkDevice device; VkQueue graphicsQueue; VkQueue presentQueue; // 5. Swapchain 설정 VkSwapchainKHR swapchain; VkFormat swapchainImageFormat = VK_FORMAT_R8G8B8A8_UNORM; VkExtent2D swapchainExtent; ``` #### **2. YUV → RGB 변환 쉐이더** **Vertex Shader (yuv_vertex.vert)**: ```glsl #version 450 layout(location = 0) in vec2 inPosition; layout(location = 1) in vec2 inTexCoord; layout(location = 0) out vec2 fragTexCoord; layout(push_constant) uniform PushConstants { mat4 transform; } pc; void main() { gl_Position = pc.transform * vec4(inPosition, 0.0, 1.0); fragTexCoord = inTexCoord; } ``` **Fragment Shader (yuv_fragment.frag)**: ```glsl #version 450 layout(location = 0) in vec2 fragTexCoord; layout(location = 0) out vec4 outColor; layout(binding = 0) uniform sampler2D yTexture; layout(binding = 1) uniform sampler2D uTexture; layout(binding = 2) uniform sampler2D vTexture; // BT.709 YUV to RGB conversion matrix const mat3 yuvToRgb = mat3( 1.0000, 1.0000, 1.0000, 0.0000, -0.1873, 1.8556, 1.5748, -0.4681, 0.0000 ); void main() { float y = texture(yTexture, fragTexCoord).r; float u = texture(uTexture, fragTexCoord).r - 0.5; float v = texture(vTexture, fragTexCoord).r - 0.5; vec3 yuv = vec3(y, u, v); vec3 rgb = yuvToRgb * yuv; outColor = vec4(rgb, 1.0); } ``` #### **3. 렌더링 파이프라인** ```cpp class VulkanVideoRenderer { public: struct VideoFrame { VkImage yImage, uImage, vImage; VkDeviceMemory yMemory, uMemory, vMemory; VkImageView yImageView, uImageView, vImageView; uint32_t width, height; }; // 프레임 렌더링 메인 함수 void RenderFrame(const VideoFrame& frame) { // 1. Command Buffer 시작 BeginCommandBuffer(); // 2. Render Pass 시작 BeginRenderPass(); // 3. YUV 텍스처 바인딩 BindYUVTextures(frame); // 4. 변환 행렬 업데이트 (AspectFit) UpdateTransformMatrix(frame.width, frame.height); // 5. 그리기 명령 DrawFullscreenQuad(); // 6. Render Pass 종료 EndRenderPass(); // 7. Command Buffer 제출 SubmitCommandBuffer(); // 8. Present PresentFrame(); } private: void UpdateTransformMatrix(uint32_t videoWidth, uint32_t videoHeight); void BindYUVTextures(const VideoFrame& frame); void DrawFullscreenQuad(); }; ``` --- ## 🔗 **JNI 통합 레이어** ### **VavCore JNI 확장** #### **vulkan_jni.cpp** ```cpp // Vulkan Surface 생성 및 관리 extern "C" JNIEXPORT jlong JNICALL Java_com_vavcore_player_VulkanVideoView_nativeCreateVulkanRenderer( JNIEnv* env, jobject thiz, jobject surface) { ANativeWindow* window = ANativeWindow_fromSurface(env, surface); VulkanVideoRenderer* renderer = new VulkanVideoRenderer(); if (renderer->Initialize(window)) { return reinterpret_cast(renderer); } delete renderer; return 0; } // 프레임 렌더링 (VavCore에서 디코딩된 프레임 받아서 Vulkan 렌더링) extern "C" JNIEXPORT void JNICALL Java_com_vavcore_player_VulkanVideoView_nativeRenderFrame( JNIEnv* env, jobject thiz, jlong rendererPtr, jlong framePtr) { VulkanVideoRenderer* renderer = reinterpret_cast(rendererPtr); VavCoreVideoFrame* frame = reinterpret_cast(framePtr); // VavCore 프레임을 Vulkan 텍스처로 변환 VulkanVideoRenderer::VideoFrame vulkanFrame; ConvertVavCoreFrameToVulkan(frame, vulkanFrame); // Vulkan 렌더링 renderer->RenderFrame(vulkanFrame); } // 성능 메트릭 수집 extern "C" JNIEXPORT jobject JNICALL Java_com_vavcore_player_VulkanVideoView_nativeGetPerformanceMetrics( JNIEnv* env, jobject thiz, jlong rendererPtr) { VulkanVideoRenderer* renderer = reinterpret_cast(rendererPtr); auto metrics = renderer->GetPerformanceMetrics(); // Java PerformanceMetrics 객체 생성 및 반환 return CreateJavaPerformanceMetrics(env, metrics); } ``` --- ## 📊 **성능 최적화 전략** ### **1. Zero-Copy 파이프라인** ``` MediaCodec → Surface → Vulkan Texture → GPU Rendering ↑ ↑ ↑ ↑ HW Decode Direct Bind GPU Memory Zero Copy ``` ### **2. 메모리 최적화** - **Texture Pooling**: 프레임 텍스처 재사용 - **Staging Buffer**: GPU 메모리 전송 최적화 - **Memory Mapping**: Persistent 메모리 매핑 사용 ### **3. 렌더링 최적화** - **Double Buffering**: Swapchain 이미지 2개 사용 - **Async Rendering**: 디코딩과 렌더링 파이프라인 분리 - **GPU Synchronization**: VkSemaphore로 동기화 ### **4. Android 특화 최적화** - **ANativeWindow 직접 사용**: Java Surface 오버헤드 제거 - **Vulkan 1.0 호환성**: 최대 디바이스 지원 - **Battery Optimization**: 불필요한 GPU 연산 최소화 --- ## 🛠️ **개발 단계별 계획** ### **Phase 1: Vulkan 기반 구조 구축** (1-2일) - [x] 설계 문서 작성 - [ ] Android 프로젝트 구조 생성 - [ ] Vulkan 초기화 및 Surface 생성 - [ ] 기본 렌더링 파이프라인 구현 ### **Phase 2: YUV 렌더링 시스템** (2-3일) - [ ] YUV → RGB 쉐이더 구현 - [ ] VavCore JNI 연동 - [ ] 텍스처 관리 시스템 - [ ] AspectFit 렌더링 로직 ### **Phase 3: UI 및 컨트롤** (1-2일) - [ ] Java/Kotlin UI 구현 - [ ] 비디오 컨트롤 버튼 기능 - [ ] 파일 로더 및 진행률 표시 - [ ] 터치 인터랙션 ### **Phase 4: 성능 최적화** (1-2일) - [ ] 성능 모니터링 시스템 - [ ] 메모리 및 GPU 최적화 - [ ] MediaCodec 벤치마킹 - [ ] 배터리 사용량 최적화 ### **Phase 5: 테스트 및 검증** (1일) - [ ] 다양한 AV1 파일 테스트 - [ ] 성능 벤치마크 수행 - [ ] 메모리 누수 검사 - [ ] 사용자 테스트 --- ## 📋 **기술 요구사항** ### **Android 요구사항** - **API Level**: 29+ (Android 10+) - **Vulkan 지원**: Vulkan 1.0 이상 - **NDK 버전**: r25+ - **Build Tools**: CMake 3.22+, Gradle 8.0+ ### **하드웨어 요구사항** - **GPU**: Vulkan 지원 GPU (Adreno 640+, Mali-G76+) - **메모리**: 4GB+ RAM 권장 - **저장공간**: 100MB+ 앱 크기 ### **성능 목표** - **4K AV1**: 30fps 안정적 재생 - **1080p AV1**: 60fps 재생 - **메모리 사용량**: 500MB 이하 - **배터리**: 1시간 재생 시 20% 이하 소모 --- ## 🔍 **리스크 및 대응방안** ### **기술적 리스크** 1. **Vulkan 호환성**: 일부 구형 디바이스 미지원 - **대응**: OpenGL ES 3.0 fallback 구현 2. **MediaCodec 안정성**: 디바이스별 구현 차이 - **대응**: dav1d 소프트웨어 디코더로 fallback 3. **메모리 사용량**: 4K 비디오의 높은 메모리 요구 - **대응**: 동적 해상도 조정 및 메모리 풀링 ### **플랫폼 리스크** 1. **Android 버전 호환성**: Vulkan API 변경 - **대응**: Vulkan 1.0 baseline 사용 2. **OEM 커스터마이징**: 제조사별 드라이버 이슈 - **대응**: 광범위한 디바이스 테스트 --- ## 📚 **참고 문서 및 리소스** ### **VavCore 관련** - [Android VavCore Lazy Initialization Success](../completed/milestones/Android_VavCore_Lazy_Initialization_Success_2025-09-29.md) - [VavCore Android MediaCodec Design](../completed/cross-platform/VavCore_Android_MediaCodec_Design.md) ### **Vulkan 참고자료** - [Vulkan Tutorial](https://vulkan-tutorial.com/) - [Android Vulkan API Guide](https://developer.android.com/ndk/guides/graphics/vulkan) - [Vulkan Memory Allocation Guide](https://gpuopen.com/vulkan-memory-allocator/) ### **Android MediaCodec** - [MediaCodec API Reference](https://developer.android.com/reference/android/media/MediaCodec) - [Surface to Surface Copy](https://developer.android.com/ndk/reference/group/media) --- **문서 작성일**: 2025-09-29 **작성자**: Claude Code **버전**: 1.0 **상태**: ✅ 설계 완료 → 구현 준비 *이 설계 문서를 기반으로 Android Vulkan AV1 Player 개발을 시작합니다.*