366 lines
11 KiB
Markdown
366 lines
11 KiB
Markdown
# Android 크로스 플랫폼 빌드 구현 계획
|
|
|
|
## 📋 **프로젝트 개요**
|
|
|
|
Android 플랫폼에서 VavCore 라이브러리의 완전한 네이티브 빌드를 구현하기 위한 단계별 계획입니다.
|
|
|
|
**현재 상태:** ✅ 플랫폼 구조 통일 완료, ❌ 크로스 플랫폼 빌드 미완성
|
|
**목표:** Android NDK를 사용한 완전한 VavCore 네이티브 라이브러리 빌드
|
|
|
|
---
|
|
|
|
## 🔍 **현재 빌드 문제 분석**
|
|
|
|
### **발견된 주요 문제들:**
|
|
1. **Windows 전용 PCH 파일**: `pch.h`에서 `#include <windows.h>` 사용
|
|
2. **플랫폼별 조건부 컴파일 부족**: Windows와 Android 코드가 분리되지 않음
|
|
3. **헤더 경로 문제**: `VavCore/VavCore.h` 경로를 찾을 수 없음
|
|
4. **디코더 팩토리 분기 필요**: Windows 전용 디코더들이 Android에서 빌드 시도
|
|
|
|
### **성공한 부분:**
|
|
- ✅ Android NDK 환경 구성 성공
|
|
- ✅ CMake 크로스 컴파일 설정 성공
|
|
- ✅ Clang 컴파일러 감지 성공
|
|
- ✅ 심볼릭 링크된 소스 코드 접근 성공
|
|
|
|
---
|
|
|
|
## 🎯 **Phase 1: 기본 빌드 수정** ⭐ **최우선**
|
|
|
|
**목표:** Android에서 기본적인 VavCore 빌드 성공
|
|
**예상 시간:** 2-3시간
|
|
|
|
### **1.1 Android 전용 PCH 파일 생성**
|
|
|
|
**파일:** `platforms/android/vavcore/src/pch_android.h`
|
|
```cpp
|
|
#pragma once
|
|
|
|
// Platform detection
|
|
#ifdef ANDROID
|
|
// Android platform specific includes
|
|
#include <android/log.h>
|
|
#include <media/NdkMediaCodec.h>
|
|
#include <media/NdkMediaFormat.h>
|
|
#include <media/NdkMediaCrypto.h>
|
|
#include <media/NdkMediaExtractor.h>
|
|
|
|
// Android logging macros
|
|
#define VAVCORE_LOG_TAG "VavCore"
|
|
#define VAVCORE_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, VAVCORE_LOG_TAG, __VA_ARGS__)
|
|
#define VAVCORE_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, VAVCORE_LOG_TAG, __VA_ARGS__)
|
|
#else
|
|
// Windows platform specific includes
|
|
#include <windows.h>
|
|
#include <d3d11.h>
|
|
#include <d3d12.h>
|
|
|
|
// Windows logging macros
|
|
#define VAVCORE_LOGD(...) OutputDebugStringA(__VA_ARGS__)
|
|
#define VAVCORE_LOGE(...) OutputDebugStringA(__VA_ARGS__)
|
|
#endif
|
|
|
|
// Common cross-platform includes
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <functional>
|
|
#include <cstdint>
|
|
#include <cassert>
|
|
|
|
// dav1d includes (available on both platforms)
|
|
#include <dav1d/dav1d.h>
|
|
#include <dav1d/picture.h>
|
|
#include <dav1d/data.h>
|
|
```
|
|
|
|
### **1.2 플랫폼별 조건부 컴파일 매크로 추가**
|
|
|
|
**파일:** `platforms/android/vavcore/src/Common/PlatformDefines.h`
|
|
```cpp
|
|
#pragma once
|
|
|
|
// Platform detection
|
|
#ifdef _WIN32
|
|
#define VAVCORE_PLATFORM_WINDOWS
|
|
#define VAVCORE_API __declspec(dllexport)
|
|
#define VAVCORE_CALLING_CONVENTION __stdcall
|
|
#elif defined(ANDROID)
|
|
#define VAVCORE_PLATFORM_ANDROID
|
|
#define VAVCORE_API __attribute__((visibility("default")))
|
|
#define VAVCORE_CALLING_CONVENTION
|
|
#else
|
|
#define VAVCORE_PLATFORM_LINUX
|
|
#define VAVCORE_API
|
|
#define VAVCORE_CALLING_CONVENTION
|
|
#endif
|
|
|
|
// Platform-specific GPU API support
|
|
#ifdef VAVCORE_PLATFORM_WINDOWS
|
|
#define VAVCORE_SUPPORT_D3D11
|
|
#define VAVCORE_SUPPORT_D3D12
|
|
#define VAVCORE_SUPPORT_NVDEC
|
|
#define VAVCORE_SUPPORT_VPL
|
|
#define VAVCORE_SUPPORT_AMF
|
|
#define VAVCORE_SUPPORT_MEDIA_FOUNDATION
|
|
#endif
|
|
|
|
#ifdef VAVCORE_PLATFORM_ANDROID
|
|
#define VAVCORE_SUPPORT_VULKAN
|
|
#define VAVCORE_SUPPORT_OPENGL_ES
|
|
#define VAVCORE_SUPPORT_MEDIACODEC
|
|
#endif
|
|
|
|
// Common support (available on all platforms)
|
|
#define VAVCORE_SUPPORT_DAV1D
|
|
#define VAVCORE_SUPPORT_WEBM
|
|
|
|
// Surface type definitions
|
|
#ifdef VAVCORE_PLATFORM_WINDOWS
|
|
typedef void* VavCoreSurfaceHandle; // Can be ID3D11Texture2D*, ID3D12Resource*
|
|
#elif defined(VAVCORE_PLATFORM_ANDROID)
|
|
typedef struct ANativeWindow* VavCoreSurfaceHandle; // Android Surface
|
|
#else
|
|
typedef void* VavCoreSurfaceHandle;
|
|
#endif
|
|
```
|
|
|
|
### **1.3 CMakeLists.txt 수정**
|
|
|
|
**파일:** `platforms/android/vavcore/CMakeLists.txt`
|
|
```cmake
|
|
# Platform-specific source selection
|
|
if(ANDROID)
|
|
# Android-only sources
|
|
set(PLATFORM_SPECIFIC_SOURCES
|
|
${VAVCORE_ROOT}/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
|
|
)
|
|
|
|
# Set Android PCH
|
|
set(VAVCORE_PCH ${VAVCORE_ROOT}/src/pch_android.h)
|
|
|
|
# Android-specific preprocessor definitions
|
|
add_definitions(-DVAVCORE_PLATFORM_ANDROID)
|
|
add_definitions(-DVAVCORE_SUPPORT_MEDIACODEC)
|
|
add_definitions(-DVAVCORE_SUPPORT_DAV1D)
|
|
else()
|
|
# Windows-only sources
|
|
set(PLATFORM_SPECIFIC_SOURCES
|
|
${VAVCORE_ROOT}/src/Decoder/NVDECAV1Decoder.cpp
|
|
${VAVCORE_ROOT}/src/Decoder/VPLAV1Decoder.cpp
|
|
${VAVCORE_ROOT}/src/Decoder/AMFAV1Decoder.cpp
|
|
${VAVCORE_ROOT}/src/Decoder/MediaFoundationAV1Decoder.cpp
|
|
)
|
|
|
|
# Set Windows PCH
|
|
set(VAVCORE_PCH ${VAVCORE_ROOT}/src/pch.h)
|
|
|
|
# Windows-specific preprocessor definitions
|
|
add_definitions(-DVAVCORE_PLATFORM_WINDOWS)
|
|
add_definitions(-DVAVCORE_SUPPORT_D3D11)
|
|
add_definitions(-DVAVCORE_SUPPORT_D3D12)
|
|
endif()
|
|
|
|
# Common sources (available on all platforms)
|
|
set(VAVCORE_COMMON_SOURCES
|
|
${VAVCORE_ROOT}/src/Decoder/VideoDecoderFactory.cpp
|
|
${VAVCORE_ROOT}/src/Decoder/AV1Decoder.cpp # dav1d decoder
|
|
${VAVCORE_ROOT}/src/FileIO/WebMFileReader.cpp
|
|
${VAVCORE_ROOT}/src/VavCore.cpp
|
|
)
|
|
|
|
# All sources for current platform
|
|
set(VAVCORE_ALL_SOURCES
|
|
${VAVCORE_COMMON_SOURCES}
|
|
${PLATFORM_SPECIFIC_SOURCES}
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 **Phase 2: 디코더 분기 구현** ⭐⭐
|
|
|
|
**목표:** 플랫폼별 디코더 자동 선택 및 빌드
|
|
**예상 시간:** 4-6시간
|
|
|
|
### **2.1 VideoDecoderFactory 플랫폼별 분기**
|
|
|
|
**파일:** `src/Decoder/VideoDecoderFactory.cpp` 수정
|
|
```cpp
|
|
#include "PlatformDefines.h"
|
|
|
|
std::unique_ptr<IVideoDecoder> VideoDecoderFactory::CreateDecoder(DecoderType type) {
|
|
switch (type) {
|
|
case DecoderType::AUTO:
|
|
#ifdef VAVCORE_PLATFORM_WINDOWS
|
|
// Windows 우선순위: NVDEC → VPL → AMF → dav1d → MediaFoundation
|
|
if (auto decoder = CreateDecoder(DecoderType::NVDEC)) return decoder;
|
|
if (auto decoder = CreateDecoder(DecoderType::VPL)) return decoder;
|
|
if (auto decoder = CreateDecoder(DecoderType::AMF)) return decoder;
|
|
if (auto decoder = CreateDecoder(DecoderType::DAV1D)) return decoder;
|
|
return CreateDecoder(DecoderType::MEDIA_FOUNDATION);
|
|
#elif defined(VAVCORE_PLATFORM_ANDROID)
|
|
// Android 우선순위: MediaCodec → dav1d
|
|
if (auto decoder = CreateDecoder(DecoderType::ANDROID_MEDIACODEC)) return decoder;
|
|
return CreateDecoder(DecoderType::DAV1D);
|
|
#else
|
|
// Linux/기타: dav1d만
|
|
return CreateDecoder(DecoderType::DAV1D);
|
|
#endif
|
|
|
|
case DecoderType::ANDROID_MEDIACODEC:
|
|
#ifdef VAVCORE_SUPPORT_MEDIACODEC
|
|
return std::make_unique<AndroidMediaCodecAV1Decoder>();
|
|
#else
|
|
VAVCORE_LOGE("Android MediaCodec decoder not supported on this platform");
|
|
return nullptr;
|
|
#endif
|
|
|
|
case DecoderType::NVDEC:
|
|
#ifdef VAVCORE_SUPPORT_NVDEC
|
|
return std::make_unique<NVDECAV1Decoder>();
|
|
#else
|
|
VAVCORE_LOGE("NVDEC decoder not supported on this platform");
|
|
return nullptr;
|
|
#endif
|
|
|
|
case DecoderType::VPL:
|
|
#ifdef VAVCORE_SUPPORT_VPL
|
|
return std::make_unique<VPLAV1Decoder>();
|
|
#else
|
|
VAVCORE_LOGE("Intel VPL decoder not supported on this platform");
|
|
return nullptr;
|
|
#endif
|
|
|
|
case DecoderType::AMF:
|
|
#ifdef VAVCORE_SUPPORT_AMF
|
|
return std::make_unique<AMFAV1Decoder>();
|
|
#else
|
|
VAVCORE_LOGE("AMD AMF decoder not supported on this platform");
|
|
return nullptr;
|
|
#endif
|
|
|
|
case DecoderType::DAV1D:
|
|
#ifdef VAVCORE_SUPPORT_DAV1D
|
|
return std::make_unique<AV1Decoder>();
|
|
#else
|
|
VAVCORE_LOGE("dav1d decoder not supported on this platform");
|
|
return nullptr;
|
|
#endif
|
|
|
|
case DecoderType::MEDIA_FOUNDATION:
|
|
#ifdef VAVCORE_SUPPORT_MEDIA_FOUNDATION
|
|
return std::make_unique<MediaFoundationAV1Decoder>();
|
|
#else
|
|
VAVCORE_LOGE("Media Foundation decoder not supported on this platform");
|
|
return nullptr;
|
|
#endif
|
|
|
|
default:
|
|
VAVCORE_LOGE("Unknown decoder type: %d", static_cast<int>(type));
|
|
return nullptr;
|
|
}
|
|
}
|
|
```
|
|
|
|
### **2.2 Android MediaCodec 디코더 개선**
|
|
|
|
**파일:** `src/Decoder/AndroidMediaCodecAV1Decoder.cpp` 검토 및 개선
|
|
- Android NDK MediaCodec API 최신화
|
|
- 에러 처리 강화
|
|
- Surface 렌더링 지원 추가
|
|
|
|
---
|
|
|
|
## 🚀 **Phase 3: 완전한 크로스 플랫폼 구현** ⭐⭐⭐
|
|
|
|
**목표:** 모든 플랫폼별 기능 완전 지원
|
|
**예상 시간:** 8-12시간
|
|
|
|
### **3.1 Surface 타입 플랫폼별 지원**
|
|
|
|
**파일:** `include/VavCore/VavCore.h` 수정
|
|
```c
|
|
// Platform-specific surface types
|
|
typedef enum {
|
|
VAVCORE_SURFACE_TYPE_NONE = 0,
|
|
#ifdef VAVCORE_PLATFORM_WINDOWS
|
|
VAVCORE_SURFACE_TYPE_D3D11_TEXTURE2D = 1,
|
|
VAVCORE_SURFACE_TYPE_D3D12_RESOURCE = 2,
|
|
#endif
|
|
#ifdef VAVCORE_PLATFORM_ANDROID
|
|
VAVCORE_SURFACE_TYPE_ANDROID_SURFACE = 10,
|
|
VAVCORE_SURFACE_TYPE_ANDROID_SURFACE_TEXTURE = 11,
|
|
#endif
|
|
VAVCORE_SURFACE_TYPE_CPU_MEMORY = 100, // Available on all platforms
|
|
} VavCoreSurfaceType;
|
|
```
|
|
|
|
### **3.2 플랫폼별 빌드 스크립트 완성**
|
|
|
|
**파일:** `platforms/android/vavcore/build.sh` 개선
|
|
- 더 자세한 오류 진단
|
|
- 플랫폼별 라이브러리 링크
|
|
- 빌드 옵션 최적화
|
|
|
|
### **3.3 통합 테스트 및 검증**
|
|
|
|
**파일:** `platforms/android/tests/native/android_vavcore_test.cpp`
|
|
- Android 환경에서 VavCore API 전체 테스트
|
|
- MediaCodec 디코더 기능 검증
|
|
- dav1d fallback 동작 확인
|
|
|
|
---
|
|
|
|
## 📊 **작업 우선순위 및 일정**
|
|
|
|
| Phase | 작업 내용 | 예상 시간 | 우선순위 | 의존성 |
|
|
|-------|-----------|-----------|----------|---------|
|
|
| Phase 1 | 기본 빌드 수정 | 2-3시간 | ⭐ 최우선 | 없음 |
|
|
| Phase 2 | 디코더 분기 구현 | 4-6시간 | ⭐⭐ 높음 | Phase 1 완료 |
|
|
| Phase 3 | 완전한 크로스 플랫폼 | 8-12시간 | ⭐⭐⭐ 중간 | Phase 2 완료 |
|
|
|
|
**총 예상 시간: 14-21시간**
|
|
|
|
---
|
|
|
|
## 🔍 **검증 방법**
|
|
|
|
### **Phase 1 완료 기준:**
|
|
```bash
|
|
# Android NDK 빌드 성공
|
|
cd platforms/android/vavcore
|
|
export ANDROID_NDK_ROOT="/path/to/ndk"
|
|
bash build.sh
|
|
# → libVavCore.so 생성 성공
|
|
```
|
|
|
|
### **Phase 2 완료 기준:**
|
|
```cpp
|
|
// 플랫폼별 디코더 자동 선택 동작
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(DecoderType::AUTO);
|
|
// Android: AndroidMediaCodecAV1Decoder 반환
|
|
// Windows: NVDECAV1Decoder 또는 다른 하드웨어 디코더 반환
|
|
```
|
|
|
|
### **Phase 3 완료 기준:**
|
|
```cpp
|
|
// 모든 VavCore API가 Android에서 정상 동작
|
|
VavCorePlayer* player = vavcore_create_player();
|
|
vavcore_open_file(player, "test.webm");
|
|
// → Android MediaCodec 또는 dav1d로 성공적 디코딩
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 **참고 자료**
|
|
|
|
- **Android NDK 문서**: https://developer.android.com/ndk
|
|
- **Android MediaCodec**: https://developer.android.com/ndk/reference/group/media
|
|
- **CMake Android 툴체인**: https://developer.android.com/ndk/guides/cmake
|
|
- **dav1d 크로스 컴파일**: https://code.videolan.org/videolan/dav1d
|
|
|
|
---
|
|
|
|
*생성일: 2025-09-28*
|
|
*프로젝트: Vav2Player Android 크로스 플랫폼 빌드* |