450 lines
16 KiB
Markdown
450 lines
16 KiB
Markdown
|
|
# 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<jlong>(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<VulkanVideoRenderer*>(rendererPtr);
|
||
|
|
VavCoreVideoFrame* frame = reinterpret_cast<VavCoreVideoFrame*>(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<VulkanVideoRenderer*>(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 개발을 시작합니다.*
|