11 KiB
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 환경 변수 설정
# 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
[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
[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 빌드
# 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 빌드
# 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_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
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
#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
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
[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 빌드 최적화 옵션
# 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: 라이브러리 심볼 확인
# 라이브러리 심볼 확인
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