390 lines
11 KiB
Markdown
390 lines
11 KiB
Markdown
|
|
# Godot용 Android dav1d 라이브러리 빌드 가이드
|
||
|
|
|
||
|
|
## 1. 개요
|
||
|
|
|
||
|
|
이 문서는 Godot 엔진에서 사용할 수 있는 Android용 dav1d AV1 디코더 라이브러리를 빌드하는 전체 과정을 설명합니다. ARM64 (aarch64)와 ARM32 (armv7a) 아키텍처를 모두 지원하며, Android NDK 26.0.10792818을 사용합니다.
|
||
|
|
|
||
|
|
## 2. 빌드 환경 설정
|
||
|
|
|
||
|
|
### 2.1 필요 도구
|
||
|
|
- **Android NDK**: 26.0.10792818
|
||
|
|
- **Meson Build System**: 최신 버전
|
||
|
|
- **Python**: 3.7 이상
|
||
|
|
- **Ninja**: Build backend
|
||
|
|
|
||
|
|
### 2.2 환경 변수 설정
|
||
|
|
```bash
|
||
|
|
# Android NDK 경로 설정
|
||
|
|
export ANDROID_NDK_HOME="C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818"
|
||
|
|
|
||
|
|
# 빌드 도구 경로 확인
|
||
|
|
export NDK_TOOLCHAIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/windows-x86_64/bin"
|
||
|
|
```
|
||
|
|
|
||
|
|
## 3. Cross-compilation 설정 파일
|
||
|
|
|
||
|
|
### 3.1 ARM64 (aarch64) 설정
|
||
|
|
**파일**: `oss/dav1d/android-arm64.cross`
|
||
|
|
```ini
|
||
|
|
[binaries]
|
||
|
|
c = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android21-clang.cmd'
|
||
|
|
cpp = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android21-clang++.cmd'
|
||
|
|
ar = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-ar'
|
||
|
|
strip = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-strip'
|
||
|
|
pkgconfig = 'false'
|
||
|
|
|
||
|
|
[host_machine]
|
||
|
|
system = 'android'
|
||
|
|
cpu_family = 'aarch64'
|
||
|
|
cpu = 'aarch64'
|
||
|
|
endian = 'little'
|
||
|
|
|
||
|
|
[built-in options]
|
||
|
|
c_args = ['-fPIC']
|
||
|
|
cpp_args = ['-fPIC']
|
||
|
|
c_link_args = ['-static-libgcc']
|
||
|
|
cpp_link_args = ['-static-libgcc', '-static-libstdc++']
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.2 ARM32 (armv7a) 설정
|
||
|
|
**파일**: `oss/dav1d/android-arm32.cross`
|
||
|
|
```ini
|
||
|
|
[binaries]
|
||
|
|
c = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/armv7a-linux-androideabi21-clang.cmd'
|
||
|
|
cpp = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/armv7a-linux-androideabi21-clang++.cmd'
|
||
|
|
ar = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-ar'
|
||
|
|
strip = 'C:/Users/emocr/AppData/Local/Android/Sdk/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-strip'
|
||
|
|
pkgconfig = 'false'
|
||
|
|
|
||
|
|
[host_machine]
|
||
|
|
system = 'android'
|
||
|
|
cpu_family = 'arm'
|
||
|
|
cpu = 'armv7'
|
||
|
|
endian = 'little'
|
||
|
|
|
||
|
|
[built-in options]
|
||
|
|
c_args = ['-fPIC']
|
||
|
|
cpp_args = ['-fPIC']
|
||
|
|
c_link_args = ['-static-libgcc']
|
||
|
|
cpp_link_args = ['-static-libgcc', '-static-libstdc++']
|
||
|
|
```
|
||
|
|
|
||
|
|
## 4. 빌드 과정
|
||
|
|
|
||
|
|
### 4.1 ARM64 빌드
|
||
|
|
```bash
|
||
|
|
# dav1d 소스 디렉토리로 이동
|
||
|
|
cd D:\Project\video-av1\oss\dav1d
|
||
|
|
|
||
|
|
# ARM64 빌드 디렉토리 생성 및 설정
|
||
|
|
meson setup build-android-arm64 --cross-file android-arm64.cross --buildtype=release
|
||
|
|
|
||
|
|
# 빌드 실행
|
||
|
|
meson compile -C build-android-arm64
|
||
|
|
|
||
|
|
# 결과 확인
|
||
|
|
ls build-android-arm64/src/
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4.2 ARM32 빌드
|
||
|
|
```bash
|
||
|
|
# ARM32 빌드 디렉토리 생성 및 설정
|
||
|
|
meson setup build-android-arm32 --cross-file android-arm32.cross --buildtype=release
|
||
|
|
|
||
|
|
# 빌드 실행
|
||
|
|
meson compile -C build-android-arm32
|
||
|
|
|
||
|
|
# 결과 확인
|
||
|
|
ls build-android-arm32/src/
|
||
|
|
```
|
||
|
|
|
||
|
|
## 5. 빌드 결과물
|
||
|
|
|
||
|
|
### 5.1 생성된 라이브러리 파일
|
||
|
|
**ARM64 결과물**:
|
||
|
|
- `build-android-arm64/src/libdav1d.a` (정적 라이브러리)
|
||
|
|
- `build-android-arm64/src/libdav1d.so` (동적 라이브러리)
|
||
|
|
|
||
|
|
**ARM32 결과물**:
|
||
|
|
- `build-android-arm32/src/libdav1d.a` (정적 라이브러리)
|
||
|
|
- `build-android-arm32/src/libdav1d.so` (동적 라이브러리)
|
||
|
|
|
||
|
|
### 5.2 라이브러리 배치
|
||
|
|
Android 프로젝트에서 사용하기 위해 다음 구조로 배치:
|
||
|
|
|
||
|
|
```
|
||
|
|
vav2/platforms/android/
|
||
|
|
├── libs/
|
||
|
|
│ ├── arm64-v8a/
|
||
|
|
│ │ ├── libdav1d.so
|
||
|
|
│ │ └── libdav1d.a
|
||
|
|
│ └── armeabi-v7a/
|
||
|
|
│ ├── libdav1d.so
|
||
|
|
│ └── libdav1d.a
|
||
|
|
└── include/
|
||
|
|
└── dav1d/
|
||
|
|
├── dav1d.h
|
||
|
|
├── picture.h
|
||
|
|
└── headers.h
|
||
|
|
```
|
||
|
|
|
||
|
|
## 6. Android 프로젝트 통합
|
||
|
|
|
||
|
|
### 6.1 CMakeLists.txt 설정
|
||
|
|
**파일**: `vav2/platforms/android/CMakeLists.txt`
|
||
|
|
```cmake
|
||
|
|
cmake_minimum_required(VERSION 3.10)
|
||
|
|
project(VavCore-Android)
|
||
|
|
|
||
|
|
# Set Android ABI
|
||
|
|
if(NOT ANDROID_ABI)
|
||
|
|
set(ANDROID_ABI "arm64-v8a")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Set library directory based on ABI
|
||
|
|
if(ANDROID_ABI STREQUAL "arm64-v8a")
|
||
|
|
set(LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs/arm64-v8a")
|
||
|
|
elseif(ANDROID_ABI STREQUAL "armeabi-v7a")
|
||
|
|
set(LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs/armeabi-v7a")
|
||
|
|
else()
|
||
|
|
message(FATAL_ERROR "Unsupported Android ABI: ${ANDROID_ABI}")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Include directories
|
||
|
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||
|
|
|
||
|
|
# Import dav1d as prebuilt library
|
||
|
|
add_library(dav1d SHARED IMPORTED)
|
||
|
|
set_target_properties(dav1d PROPERTIES
|
||
|
|
IMPORTED_LOCATION ${LIB_DIR}/libdav1d.so
|
||
|
|
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||
|
|
)
|
||
|
|
|
||
|
|
# Also provide static library option
|
||
|
|
add_library(dav1d_static STATIC IMPORTED)
|
||
|
|
set_target_properties(dav1d_static PROPERTIES
|
||
|
|
IMPORTED_LOCATION ${LIB_DIR}/libdav1d.a
|
||
|
|
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||
|
|
)
|
||
|
|
|
||
|
|
# Create a simple test library that uses dav1d
|
||
|
|
add_library(vavcore-android SHARED
|
||
|
|
src/android_test.cpp
|
||
|
|
)
|
||
|
|
|
||
|
|
target_link_libraries(vavcore-android
|
||
|
|
dav1d
|
||
|
|
log # Android log library
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6.2 Gradle 빌드 설정
|
||
|
|
**파일**: `vav2/platforms/android/build.gradle`
|
||
|
|
```gradle
|
||
|
|
apply plugin: 'com.android.library'
|
||
|
|
|
||
|
|
android {
|
||
|
|
compileSdkVersion 34
|
||
|
|
buildToolsVersion "34.0.0"
|
||
|
|
|
||
|
|
defaultConfig {
|
||
|
|
minSdkVersion 21
|
||
|
|
targetSdkVersion 34
|
||
|
|
|
||
|
|
ndk {
|
||
|
|
abiFilters 'arm64-v8a', 'armeabi-v7a'
|
||
|
|
}
|
||
|
|
|
||
|
|
externalNativeBuild {
|
||
|
|
cmake {
|
||
|
|
cppFlags "-std=c++17"
|
||
|
|
arguments "-DANDROID_STL=c++_shared"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
externalNativeBuild {
|
||
|
|
cmake {
|
||
|
|
path "CMakeLists.txt"
|
||
|
|
version "3.22.1"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
sourceSets {
|
||
|
|
main {
|
||
|
|
java.srcDirs = ['src/main/java']
|
||
|
|
jniLibs.srcDirs = ['libs']
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 7. 테스트 및 검증
|
||
|
|
|
||
|
|
### 7.1 기본 테스트 코드
|
||
|
|
**파일**: `vav2/platforms/android/src/android_test.cpp`
|
||
|
|
```cpp
|
||
|
|
#include <jni.h>
|
||
|
|
#include <android/log.h>
|
||
|
|
#include <dav1d/dav1d.h>
|
||
|
|
|
||
|
|
#define LOG_TAG "VavCore"
|
||
|
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||
|
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||
|
|
|
||
|
|
extern "C" {
|
||
|
|
|
||
|
|
JNIEXPORT jstring JNICALL
|
||
|
|
Java_com_vavcore_android_VavCore_getDav1dVersion(JNIEnv *env, jclass clazz) {
|
||
|
|
const char* version = dav1d_version();
|
||
|
|
LOGI("dav1d version: %s", version);
|
||
|
|
return env->NewStringUTF(version);
|
||
|
|
}
|
||
|
|
|
||
|
|
JNIEXPORT jboolean JNICALL
|
||
|
|
Java_com_vavcore_android_VavCore_testDav1dDecoder(JNIEnv *env, jclass clazz) {
|
||
|
|
Dav1dSettings settings;
|
||
|
|
Dav1dContext *ctx = nullptr;
|
||
|
|
|
||
|
|
// Initialize default settings
|
||
|
|
dav1d_default_settings(&settings);
|
||
|
|
settings.n_threads = 1; // Use single thread for Android
|
||
|
|
|
||
|
|
// Create decoder context
|
||
|
|
int ret = dav1d_open(&ctx, &settings);
|
||
|
|
if (ret < 0) {
|
||
|
|
LOGE("Failed to create dav1d decoder context: %d", ret);
|
||
|
|
return JNI_FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOGI("dav1d decoder context created successfully");
|
||
|
|
|
||
|
|
// Clean up
|
||
|
|
dav1d_close(&ctx);
|
||
|
|
LOGI("dav1d decoder context closed");
|
||
|
|
|
||
|
|
return JNI_TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // extern "C"
|
||
|
|
```
|
||
|
|
|
||
|
|
### 7.2 Java 인터페이스
|
||
|
|
**파일**: `src/main/java/com/vavcore/android/VavCore.java`
|
||
|
|
```java
|
||
|
|
package com.vavcore.android;
|
||
|
|
|
||
|
|
public class VavCore {
|
||
|
|
static {
|
||
|
|
System.loadLibrary("vavcore-android");
|
||
|
|
}
|
||
|
|
|
||
|
|
public static native String getDav1dVersion();
|
||
|
|
public static native boolean testDav1dDecoder();
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 8. Godot 통합 가이드
|
||
|
|
|
||
|
|
### 8.1 GDExtension 구조
|
||
|
|
```
|
||
|
|
godot-project/
|
||
|
|
├── addons/
|
||
|
|
│ └── vavcore/
|
||
|
|
│ ├── bin/
|
||
|
|
│ │ ├── android/
|
||
|
|
│ │ │ ├── arm64/libvavcore.so
|
||
|
|
│ │ │ └── arm32/libvavcore.so
|
||
|
|
│ │ └── windows/
|
||
|
|
│ │ └── x64/vavcore.dll
|
||
|
|
│ ├── vavcore.gdextension
|
||
|
|
│ └── README.md
|
||
|
|
```
|
||
|
|
|
||
|
|
### 8.2 GDExtension 설정 파일
|
||
|
|
**파일**: `addons/vavcore/vavcore.gdextension`
|
||
|
|
```ini
|
||
|
|
[configuration]
|
||
|
|
entry_symbol = "vavcore_library_init"
|
||
|
|
|
||
|
|
[libraries]
|
||
|
|
android.debug.arm64 = "res://addons/vavcore/bin/android/arm64/libvavcore.so"
|
||
|
|
android.release.arm64 = "res://addons/vavcore/bin/android/arm64/libvavcore.so"
|
||
|
|
android.debug.arm32 = "res://addons/vavcore/bin/android/arm32/libvavcore.so"
|
||
|
|
android.release.arm32 = "res://addons/vavcore/bin/android/arm32/libvavcore.so"
|
||
|
|
windows.debug.x86_64 = "res://addons/vavcore/bin/windows/x64/vavcore.dll"
|
||
|
|
windows.release.x86_64 = "res://addons/vavcore/bin/windows/x64/vavcore.dll"
|
||
|
|
```
|
||
|
|
|
||
|
|
## 9. 성능 최적화
|
||
|
|
|
||
|
|
### 9.1 빌드 최적화 옵션
|
||
|
|
```bash
|
||
|
|
# Release 빌드 with 최적화
|
||
|
|
meson setup build-android-arm64 \
|
||
|
|
--cross-file android-arm64.cross \
|
||
|
|
--buildtype=release \
|
||
|
|
-Db_lto=true \
|
||
|
|
-Db_ndebug=true \
|
||
|
|
-Denable_asm=true \
|
||
|
|
-Denable_tools=false \
|
||
|
|
-Denable_tests=false
|
||
|
|
```
|
||
|
|
|
||
|
|
### 9.2 런타임 최적화
|
||
|
|
- **스레드 수 조정**: Android 기기의 CPU 코어 수에 맞춰 설정
|
||
|
|
- **메모리 사용량 최적화**: 작은 해상도 우선 처리
|
||
|
|
- **배터리 최적화**: GPU 가속 사용 시 전력 소비 고려
|
||
|
|
|
||
|
|
## 10. 트러블슈팅
|
||
|
|
|
||
|
|
### 10.1 일반적인 문제들
|
||
|
|
|
||
|
|
**문제**: NDK 경로 오류
|
||
|
|
```
|
||
|
|
ERROR: C compiler not found
|
||
|
|
```
|
||
|
|
**해결책**: NDK 경로와 실행 파일 확장자(.cmd) 확인
|
||
|
|
|
||
|
|
**문제**: 링크 오류
|
||
|
|
```
|
||
|
|
undefined reference to 'dav1d_version'
|
||
|
|
```
|
||
|
|
**해결책**: 라이브러리 경로와 아키텍처 일치 확인
|
||
|
|
|
||
|
|
**문제**: 런타임 크래시
|
||
|
|
```
|
||
|
|
java.lang.UnsatisfiedLinkError
|
||
|
|
```
|
||
|
|
**해결책**: JNI 함수 시그니처와 실제 구현 일치 확인
|
||
|
|
|
||
|
|
### 10.2 디버깅 도구
|
||
|
|
- **Android Studio Logcat**: 런타임 로그 확인
|
||
|
|
- **ndk-stack**: 네이티브 크래시 분석
|
||
|
|
- **objdump**: 라이브러리 심볼 확인
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 라이브러리 심볼 확인
|
||
|
|
objdump -T libdav1d.so | grep dav1d_version
|
||
|
|
|
||
|
|
# 아키텍처 확인
|
||
|
|
file libdav1d.so
|
||
|
|
```
|
||
|
|
|
||
|
|
## 11. 결론
|
||
|
|
|
||
|
|
이 가이드를 통해 Android용 dav1d 라이브러리를 성공적으로 빌드하고 Godot 프로젝트에 통합할 수 있습니다. ARM64와 ARM32 아키텍처를 모두 지원하므로 다양한 Android 기기에서 AV1 비디오 디코딩이 가능합니다.
|
||
|
|
|
||
|
|
주요 성과:
|
||
|
|
- ✅ **Cross-platform 빌드 시스템**: Meson 기반 안정적인 빌드
|
||
|
|
- ✅ **멀티 아키텍처 지원**: ARM64/ARM32 동시 지원
|
||
|
|
- ✅ **Godot 통합 준비**: GDExtension 구조 완성
|
||
|
|
- ✅ **테스트 검증**: JNI 인터페이스를 통한 동작 확인
|
||
|
|
|
||
|
|
향후 VavCore Android MediaCodec 통합 시 이 dav1d 라이브러리가 소프트웨어 fallback으로 사용되어 안정적인 AV1 디코딩 환경을 제공할 것입니다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
*문서 버전: 1.0*
|
||
|
|
*작성일: 2025-09-27*
|
||
|
|
*작성자: Claude Code AI Assistant*
|