/* * Copyright (c) 2021 Taner Sener * * This file is part of FFmpegKit. * * FFmpegKit is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FFmpegKit is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FFmpegKit. If not, see . */ package com.arthenica.ffmpegkit; import android.os.Build; import com.arthenica.smartexception.java.Exceptions; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; import java.util.List; /** *

Responsible of loading native libraries. */ public class NativeLoader { static final String[] FFMPEG_LIBRARIES = {"avutil", "swscale", "swresample", "avcodec", "avformat", "avfilter", "avdevice"}; static boolean isTestModeDisabled() { return (System.getProperty("enable.ffmpeg.kit.test.mode") == null); } private static void loadLibrary(final String libraryName) { if (isTestModeDisabled()) { System.loadLibrary(libraryName); } } private static List loadExternalLibraries() { if (isTestModeDisabled()) { return Packages.getExternalLibraries(); } else { return Collections.emptyList(); } } private static String loadNativeAbi() { if (isTestModeDisabled()) { return AbiDetect.getNativeAbi(); } else { return Abi.ABI_X86_64.getName(); } } static String loadAbi() { if (isTestModeDisabled()) { return AbiDetect.getAbi(); } else { return Abi.ABI_X86_64.getName(); } } static String loadPackageName() { if (isTestModeDisabled()) { return Packages.getPackageName(); } else { return "test"; } } static String loadVersion() { final String version = "4.4"; if (isTestModeDisabled()) { return FFmpegKitConfig.getVersion(); } else if (loadIsLTSBuild()) { return String.format("%s-lts", version); } else { return version; } } static boolean loadIsLTSBuild() { if (isTestModeDisabled()) { return AbiDetect.isNativeLTSBuild(); } else { return true; } } static int loadLogLevel() { if (isTestModeDisabled()) { return FFmpegKitConfig.getNativeLogLevel(); } else { return Level.AV_LOG_DEBUG.getValue(); } } static String loadBuildDate() { if (isTestModeDisabled()) { return FFmpegKitConfig.getBuildDate(); } else { return new SimpleDateFormat("yyyyMMdd").format(new Date()); } } static void enableRedirection() { if (isTestModeDisabled()) { FFmpegKitConfig.enableRedirection(); } } static void loadFFmpegKitAbiDetect() { loadLibrary("ffmpegkit_abidetect"); } static boolean loadFFmpeg() { boolean nativeFFmpegLoaded = false; boolean nativeFFmpegTriedAndFailed = false; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { /* LOADING LINKED LIBRARIES MANUALLY ON API < 21 */ final List externalLibrariesEnabled = loadExternalLibraries(); if (externalLibrariesEnabled.contains("tesseract") || externalLibrariesEnabled.contains("x265") || externalLibrariesEnabled.contains("snappy") || externalLibrariesEnabled.contains("openh264") || externalLibrariesEnabled.contains("rubberband")) { loadLibrary("c++_shared"); } if (AbiDetect.ARM_V7A.equals(loadNativeAbi())) { try { for (String ffmpegLibrary : FFMPEG_LIBRARIES) { loadLibrary(ffmpegLibrary + "_neon"); } nativeFFmpegLoaded = true; } catch (final UnsatisfiedLinkError e) { android.util.Log.i(FFmpegKitConfig.TAG, String.format("NEON supported armeabi-v7a ffmpeg library not found. Loading default armeabi-v7a library.%s", Exceptions.getStackTraceString(e))); nativeFFmpegTriedAndFailed = true; } } if (!nativeFFmpegLoaded) { for (String ffmpegLibrary : FFMPEG_LIBRARIES) { loadLibrary(ffmpegLibrary); } } } return nativeFFmpegTriedAndFailed; } static void loadFFmpegKit(final boolean nativeFFmpegTriedAndFailed) { boolean nativeFFmpegKitLoaded = false; if (!nativeFFmpegTriedAndFailed && AbiDetect.ARM_V7A.equals(loadNativeAbi())) { try { /* * THE TRY TO LOAD ARM-V7A-NEON FIRST. IF NOT LOAD DEFAULT ARM-V7A */ loadLibrary("ffmpegkit_armv7a_neon"); nativeFFmpegKitLoaded = true; AbiDetect.setArmV7aNeonLoaded(); } catch (final UnsatisfiedLinkError e) { android.util.Log.i(FFmpegKitConfig.TAG, String.format("NEON supported armeabi-v7a ffmpegkit library not found. Loading default armeabi-v7a library.%s", Exceptions.getStackTraceString(e))); } } if (!nativeFFmpegKitLoaded) { loadLibrary("ffmpegkit"); } } }