From 19602ca4ca6dac92fa8aece86a7e48dccc97caa4 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Thu, 23 Jul 2020 16:41:10 +0100 Subject: [PATCH] Use CMake to build the ffmpeg audio extension PiperOrigin-RevId: 322793308 --- extensions/ffmpeg/README.md | 12 +----- extensions/ffmpeg/build.gradle | 9 ++++- .../exoplayer2/ext/ffmpeg/FfmpegLibrary.java | 2 +- extensions/ffmpeg/src/main/jni/Android.mk | 40 ------------------- extensions/ffmpeg/src/main/jni/Application.mk | 20 ---------- extensions/ffmpeg/src/main/jni/CMakeLists.txt | 38 ++++++++++++++++++ 6 files changed, 49 insertions(+), 72 deletions(-) delete mode 100644 extensions/ffmpeg/src/main/jni/Android.mk delete mode 100644 extensions/ffmpeg/src/main/jni/Application.mk create mode 100644 extensions/ffmpeg/src/main/jni/CMakeLists.txt diff --git a/extensions/ffmpeg/README.md b/extensions/ffmpeg/README.md index c7b7ee22f7..ed5d2aba32 100644 --- a/extensions/ffmpeg/README.md +++ b/extensions/ffmpeg/README.md @@ -18,8 +18,8 @@ its modules locally. Instructions for doing this can be found in ExoPlayer's [top level README][]. The extension is not provided via JCenter (see [#2781][] for more information). -In addition, it's necessary to build the extension's native components as -follows: +In addition, it's necessary to manually build the FFmpeg library, so that gradle +can bundle the FFmpeg binaries in the APK: * Set the following shell variable: @@ -73,14 +73,6 @@ cd "${FFMPEG_EXT_PATH}/jni" && \ "${FFMPEG_EXT_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ENABLED_DECODERS[@]}" ``` -* Build the JNI native libraries, setting `APP_ABI` to include the architectures - built in the previous step. For example: - -``` -cd "${FFMPEG_EXT_PATH}/jni" && \ -${NDK_PATH}/ndk-build APP_ABI="armeabi-v7a arm64-v8a x86 x86_64" -j4 -``` - ## Build instructions (Windows) ## We do not provide support for building this extension on Windows, however it diff --git a/extensions/ffmpeg/build.gradle b/extensions/ffmpeg/build.gradle index 09d7182a30..bf715b7760 100644 --- a/extensions/ffmpeg/build.gradle +++ b/extensions/ffmpeg/build.gradle @@ -15,11 +15,18 @@ apply from: "$gradle.ext.exoplayerSettingsDir/common_library_config.gradle" android { sourceSets.main { + // The directory from which to pick the ffmpeg binaries. jniLibs.srcDir 'src/main/libs' - jni.srcDirs = [] // Disable the automatic ndk-build call by Android Studio. } } +// Configure the native build only if ffmpeg is present to avoid gradle sync +// failures if ffmpeg hasn't been built according to the README instructions. +if (project.file('src/main/jni/ffmpeg').exists()) { + android.externalNativeBuild.cmake.path = 'src/main/jni/CMakeLists.txt' + android.externalNativeBuild.cmake.version = '3.7.1+' +} + dependencies { implementation project(modulePrefix + 'library-core') implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion diff --git a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java index 110de5ddad..71912aea2f 100644 --- a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java +++ b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java @@ -35,7 +35,7 @@ public final class FfmpegLibrary { private static final String TAG = "FfmpegLibrary"; private static final LibraryLoader LOADER = - new LibraryLoader("avutil", "swresample", "avcodec", "ffmpeg"); + new LibraryLoader("avutil", "swresample", "avcodec", "ffmpeg_jni"); private static @MonotonicNonNull String version; private static int inputBufferPaddingSize = C.LENGTH_UNSET; diff --git a/extensions/ffmpeg/src/main/jni/Android.mk b/extensions/ffmpeg/src/main/jni/Android.mk deleted file mode 100644 index bcaf12cd11..0000000000 --- a/extensions/ffmpeg/src/main/jni/Android.mk +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libavcodec -LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so -include $(PREBUILT_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libswresample -LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so -include $(PREBUILT_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libavutil -LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so -include $(PREBUILT_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := ffmpeg -LOCAL_SRC_FILES := ffmpeg_jni.cc -LOCAL_C_INCLUDES := ffmpeg -LOCAL_SHARED_LIBRARIES := libavcodec libswresample libavutil -LOCAL_LDLIBS := -Lffmpeg/android-libs/$(TARGET_ARCH_ABI) -llog -include $(BUILD_SHARED_LIBRARY) diff --git a/extensions/ffmpeg/src/main/jni/Application.mk b/extensions/ffmpeg/src/main/jni/Application.mk deleted file mode 100644 index 7d6f732548..0000000000 --- a/extensions/ffmpeg/src/main/jni/Application.mk +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -APP_OPTIM := release -APP_STL := c++_static -APP_CPPFLAGS := -frtti -APP_PLATFORM := android-9 diff --git a/extensions/ffmpeg/src/main/jni/CMakeLists.txt b/extensions/ffmpeg/src/main/jni/CMakeLists.txt new file mode 100644 index 0000000000..4f16509721 --- /dev/null +++ b/extensions/ffmpeg/src/main/jni/CMakeLists.txt @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.7.1 FATAL_ERROR) + +# Enable C++11 features. +set(CMAKE_CXX_STANDARD 11) + +project(libffmpeg_jni C CXX) + +set(ffmpeg_location "${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg") +set(ffmpeg_binaries "${ffmpeg_location}/android-libs/${ANDROID_ABI}") +set(ffmpeg_output_dir "${CMAKE_CURRENT_SOURCE_DIR}/../libs/${ANDROID_ABI}") + +foreach(ffmpeg_lib avutil swresample avcodec) + set(ffmpeg_lib_filename lib${ffmpeg_lib}.so) + set(ffmpeg_lib_file_path ${ffmpeg_binaries}/${ffmpeg_lib_filename}) + add_library( + ${ffmpeg_lib} + SHARED + IMPORTED) + set_target_properties( + ${ffmpeg_lib} PROPERTIES + IMPORTED_LOCATION + ${ffmpeg_lib_file_path}) + file(COPY ${ffmpeg_lib_file_path} DESTINATION ${ffmpeg_output_dir}) +endforeach() + +include_directories(${ffmpeg_location}) +find_library(android_log_lib log) + +add_library(ffmpeg_jni + SHARED + ffmpeg_jni.cc) + +target_link_libraries(ffmpeg_jni + PRIVATE android + PRIVATE avutil + PRIVATE swresample + PRIVATE avcodec + PRIVATE ${android_log_lib})