11 KiB
11 KiB
Android 크로스 플랫폼 빌드 구현 계획
📋 프로젝트 개요
Android 플랫폼에서 VavCore 라이브러리의 완전한 네이티브 빌드를 구현하기 위한 단계별 계획입니다.
현재 상태: ✅ 플랫폼 구조 통일 완료, ❌ 크로스 플랫폼 빌드 미완성 목표: Android NDK를 사용한 완전한 VavCore 네이티브 라이브러리 빌드
🔍 현재 빌드 문제 분석
발견된 주요 문제들:
- Windows 전용 PCH 파일:
pch.h에서#include <windows.h>사용 - 플랫폼별 조건부 컴파일 부족: Windows와 Android 코드가 분리되지 않음
- 헤더 경로 문제:
VavCore/VavCore.h경로를 찾을 수 없음 - 디코더 팩토리 분기 필요: Windows 전용 디코더들이 Android에서 빌드 시도
성공한 부분:
- ✅ Android NDK 환경 구성 성공
- ✅ CMake 크로스 컴파일 설정 성공
- ✅ Clang 컴파일러 감지 성공
- ✅ 심볼릭 링크된 소스 코드 접근 성공
🎯 Phase 1: 기본 빌드 수정 ⭐ 최우선
목표: Android에서 기본적인 VavCore 빌드 성공 예상 시간: 2-3시간
1.1 Android 전용 PCH 파일 생성
파일: platforms/android/vavcore/src/pch_android.h
#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
#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
# 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 수정
#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 수정
// 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 완료 기준:
# Android NDK 빌드 성공
cd platforms/android/vavcore
export ANDROID_NDK_ROOT="/path/to/ndk"
bash build.sh
# → libVavCore.so 생성 성공
Phase 2 완료 기준:
// 플랫폼별 디코더 자동 선택 동작
auto decoder = VideoDecoderFactory::CreateDecoder(DecoderType::AUTO);
// Android: AndroidMediaCodecAV1Decoder 반환
// Windows: NVDECAV1Decoder 또는 다른 하드웨어 디코더 반환
Phase 3 완료 기준:
// 모든 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 크로스 플랫폼 빌드