1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.exoplayer2.ext.ffmpeg; 17 18 import androidx.annotation.Nullable; 19 import com.google.android.exoplayer2.ExoPlayerLibraryInfo; 20 import com.google.android.exoplayer2.util.LibraryLoader; 21 import com.google.android.exoplayer2.util.Log; 22 import com.google.android.exoplayer2.util.MimeTypes; 23 24 /** 25 * Configures and queries the underlying native library. 26 */ 27 public final class FfmpegLibrary { 28 29 static { 30 ExoPlayerLibraryInfo.registerModule("goog.exo.ffmpeg"); 31 } 32 33 private static final String TAG = "FfmpegLibrary"; 34 35 private static final LibraryLoader LOADER = 36 new LibraryLoader("avutil", "swresample", "avcodec", "ffmpeg"); 37 FfmpegLibrary()38 private FfmpegLibrary() {} 39 40 /** 41 * Override the names of the FFmpeg native libraries. If an application wishes to call this 42 * method, it must do so before calling any other method defined by this class, and before 43 * instantiating a {@link FfmpegAudioRenderer} or {@link FfmpegVideoRenderer} instance. 44 * 45 * @param libraries The names of the FFmpeg native libraries. 46 */ setLibraries(String... libraries)47 public static void setLibraries(String... libraries) { 48 LOADER.setLibraries(libraries); 49 } 50 51 /** 52 * Returns whether the underlying library is available, loading it if necessary. 53 */ isAvailable()54 public static boolean isAvailable() { 55 return LOADER.isAvailable(); 56 } 57 58 /** Returns the version of the underlying library if available, or null otherwise. */ getVersion()59 public static @Nullable String getVersion() { 60 return isAvailable() ? ffmpegGetVersion() : null; 61 } 62 63 /** 64 * Returns whether the underlying library supports the specified MIME type. 65 * 66 * @param mimeType The MIME type to check. 67 */ supportsFormat(String mimeType)68 public static boolean supportsFormat(String mimeType) { 69 if (!isAvailable()) { 70 return false; 71 } 72 String codecName = getCodecName(mimeType); 73 if (codecName == null) { 74 return false; 75 } 76 if (!ffmpegHasDecoder(codecName)) { 77 Log.w(TAG, "No " + codecName + " decoder available. Check the FFmpeg build configuration."); 78 return false; 79 } 80 return true; 81 } 82 83 /** 84 * Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null} 85 * if it's unsupported. 86 */ getCodecName(String mimeType)87 /* package */ static @Nullable String getCodecName(String mimeType) { 88 switch (mimeType) { 89 case MimeTypes.AUDIO_AAC: 90 return "aac"; 91 case MimeTypes.AUDIO_MPEG: 92 case MimeTypes.AUDIO_MPEG_L1: 93 case MimeTypes.AUDIO_MPEG_L2: 94 return "mp3"; 95 case MimeTypes.AUDIO_AC3: 96 return "ac3"; 97 case MimeTypes.AUDIO_E_AC3: 98 case MimeTypes.AUDIO_E_AC3_JOC: 99 return "eac3"; 100 case MimeTypes.AUDIO_TRUEHD: 101 return "truehd"; 102 case MimeTypes.AUDIO_DTS: 103 case MimeTypes.AUDIO_DTS_HD: 104 return "dca"; 105 case MimeTypes.AUDIO_VORBIS: 106 return "vorbis"; 107 case MimeTypes.AUDIO_OPUS: 108 return "opus"; 109 case MimeTypes.AUDIO_AMR_NB: 110 return "amrnb"; 111 case MimeTypes.AUDIO_AMR_WB: 112 return "amrwb"; 113 case MimeTypes.AUDIO_FLAC: 114 return "flac"; 115 case MimeTypes.AUDIO_ALAC: 116 return "alac"; 117 case MimeTypes.AUDIO_MLAW: 118 return "pcm_mulaw"; 119 case MimeTypes.AUDIO_ALAW: 120 return "pcm_alaw"; 121 case MimeTypes.VIDEO_H264: 122 return "h264"; 123 case MimeTypes.VIDEO_H265: 124 return "hevc"; 125 default: 126 return null; 127 } 128 } 129 ffmpegGetVersion()130 private static native String ffmpegGetVersion(); ffmpegHasDecoder(String codecName)131 private static native boolean ffmpegHasDecoder(String codecName); 132 133 } 134