Add support to VP9 extension for overriding the native library names

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=132874777
This commit is contained in:
benm 2016-09-12 08:03:48 -07:00 committed by Oliver Woodman
parent 383966b307
commit 45a5331e30
4 changed files with 119 additions and 64 deletions

View file

@ -116,30 +116,10 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
outputMode = VpxDecoder.OUTPUT_MODE_NONE;
}
/**
* Returns whether the underlying libvpx library is available.
*/
public static boolean isLibvpxAvailable() {
return VpxDecoder.IS_AVAILABLE;
}
/**
* Returns the version of the underlying libvpx library if available, otherwise {@code null}.
*/
public static String getLibvpxVersion() {
return isLibvpxAvailable() ? VpxDecoder.getLibvpxVersion() : null;
}
/**
* Returns the configuration string with which the underlying libvpx library was built.
*/
public static String getLibvpxConfig() {
return isLibvpxAvailable() ? VpxDecoder.getLibvpxConfig() : null;
}
@Override
public int supportsFormat(Format format) {
return isLibvpxAvailable() && MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)
return VpxNativeLibraryHelper.isLibvpxAvailable()
&& MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)
? (FORMAT_HANDLED | ADAPTIVE_SEAMLESS) : FORMAT_UNSUPPORTED_TYPE;
}

View file

@ -30,32 +30,6 @@ import java.nio.ByteBuffer;
public static final int OUTPUT_MODE_YUV = 0;
public static final int OUTPUT_MODE_RGB = 1;
/**
* Whether the underlying libvpx library is available.
*/
public static final boolean IS_AVAILABLE;
static {
boolean isAvailable;
try {
System.loadLibrary("vpx");
System.loadLibrary("vpxJNI");
isAvailable = true;
} catch (UnsatisfiedLinkError exception) {
isAvailable = false;
}
IS_AVAILABLE = isAvailable;
}
/**
* Returns the version string of the underlying libvpx decoder.
*/
public static native String getLibvpxVersion();
/**
* Returns the configuration string with which the underlying libvpx library was built.
*/
public static native String getLibvpxConfig();
private final long vpxDecContext;
private volatile int outputMode;
@ -71,6 +45,9 @@ import java.nio.ByteBuffer;
public VpxDecoder(int numInputBuffers, int numOutputBuffers, int initialInputBufferSize)
throws VpxDecoderException {
super(new DecoderInputBuffer[numInputBuffers], new VpxOutputBuffer[numOutputBuffers]);
if (!VpxNativeLibraryHelper.isLibvpxAvailable()) {
throw new VpxDecoderException("Failed to load decoder native libraries.");
}
vpxDecContext = vpxInit();
if (vpxDecContext == 0) {
throw new VpxDecoderException("Failed to initialize decoder");
@ -80,7 +57,7 @@ import java.nio.ByteBuffer;
@Override
public String getName() {
return "libvpx" + getLibvpxVersion();
return "libvpx" + VpxNativeLibraryHelper.getLibvpxVersion();
}
/**
@ -134,5 +111,4 @@ import java.nio.ByteBuffer;
private native long vpxDecode(long context, ByteBuffer encoded, int length);
private native int vpxGetFrame(long context, VpxOutputBuffer outputBuffer);
private native String vpxGetErrorMessage(long context);
}

View file

@ -0,0 +1,88 @@
/*
* 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.
*/
package com.google.android.exoplayer2.ext.vp9;
import com.google.android.exoplayer2.util.Assertions;
/**
* Configure the native libraries that are used by the {@link VpxDecoder}.
*/
public final class VpxNativeLibraryHelper {
private static boolean loadAttempted;
private static boolean isAvailable;
private static String[] nativeLibs = { "vpx", "vpxJNI" };
private static final Object lock = new Object();
private VpxNativeLibraryHelper() {}
/**
* Override the default set of native libraries loaded for Vpx decoder support.
* If an application wishes to call this method, it must do so before calling any other method
* defined by this class, and before instantiating a {@link LibvpxVideoRenderer} instance.
*/
public static void setNativeLibraries(String... libs) {
synchronized (lock) {
Assertions.checkState(!loadAttempted,
"Vpx native libs must be set earlier, they have already been loaded.");
nativeLibs = libs;
}
}
/**
* Returns whether the underlying libvpx library is available.
*/
public static boolean isLibvpxAvailable() {
return loadNativeLibraries();
}
/**
* Returns the version of the underlying libvpx library if available, otherwise {@code null}.
*/
public static String getLibvpxVersion() {
return isLibvpxAvailable() ? nativeGetLibvpxConfig() : null;
}
/**
* Returns the configuration string with which the underlying libvpx library was built.
*/
public static String getLibvpxConfig() {
return isLibvpxAvailable() ? nativeGetLibvpxVersion() : null;
}
private static boolean loadNativeLibraries() {
synchronized (lock) {
if (loadAttempted) {
return isAvailable;
}
loadAttempted = true;
try {
for (String lib : VpxNativeLibraryHelper.nativeLibs) {
System.loadLibrary(lib);
}
isAvailable = true;
} catch (UnsatisfiedLinkError exception) {
isAvailable = false;
}
return isAvailable;
}
}
private static native String nativeGetLibvpxConfig();
private static native String nativeGetLibvpxVersion();
}

View file

@ -34,7 +34,7 @@
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
__VA_ARGS__))
#define FUNC(RETURN_TYPE, NAME, ...) \
#define VPX_DECODER_FUNC(RETURN_TYPE, NAME, ...) \
extern "C" { \
JNIEXPORT RETURN_TYPE \
Java_com_google_android_exoplayer2_ext_vp9_VpxDecoder_ ## NAME \
@ -44,6 +44,16 @@
Java_com_google_android_exoplayer2_ext_vp9_VpxDecoder_ ## NAME \
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
#define VPX_NATIVE_LIBRARY_HELPER_FUNC(RETURN_TYPE, NAME, ...) \
extern "C" { \
JNIEXPORT RETURN_TYPE \
Java_com_google_android_exoplayer2_ext_vp9_VpxNativeLibraryHelper_ ## NAME \
(JNIEnv* env, jobject thiz, ##__VA_ARGS__);\
} \
JNIEXPORT RETURN_TYPE \
Java_com_google_android_exoplayer2_ext_vp9_VpxNativeLibraryHelper_ ## NAME \
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
// JNI references for VpxOutputBuffer class.
static jmethodID initForRgbFrame;
static jmethodID initForYuvFrame;
@ -58,7 +68,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return JNI_VERSION_1_6;
}
FUNC(jlong, vpxInit) {
VPX_DECODER_FUNC(jlong, vpxInit) {
vpx_codec_ctx_t* context = new vpx_codec_ctx_t();
vpx_codec_dec_cfg_t cfg = {0, 0, 0};
cfg.threads = android_getCpuCount();
@ -81,7 +91,7 @@ FUNC(jlong, vpxInit) {
return reinterpret_cast<intptr_t>(context);
}
FUNC(jlong, vpxDecode, jlong jContext, jobject encoded, jint len) {
VPX_DECODER_FUNC(jlong, vpxDecode, jlong jContext, jobject encoded, jint len) {
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
const uint8_t* const buffer =
reinterpret_cast<const uint8_t*>(env->GetDirectBufferAddress(encoded));
@ -94,14 +104,14 @@ FUNC(jlong, vpxDecode, jlong jContext, jobject encoded, jint len) {
return 0;
}
FUNC(jlong, vpxClose, jlong jContext) {
VPX_DECODER_FUNC(jlong, vpxClose, jlong jContext) {
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
vpx_codec_destroy(context);
delete context;
return 0;
}
FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
VPX_DECODER_FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
vpx_codec_iter_t iter = NULL;
const vpx_image_t* const img = vpx_codec_get_frame(context, &iter);
@ -166,15 +176,16 @@ FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
return 0;
}
FUNC(jstring, getLibvpxVersion) {
return env->NewStringUTF(vpx_codec_version_str());
}
FUNC(jstring, getLibvpxConfig) {
return env->NewStringUTF(vpx_codec_build_config());
}
FUNC(jstring, vpxGetErrorMessage, jlong jContext) {
VPX_DECODER_FUNC(jstring, vpxGetErrorMessage, jlong jContext) {
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
return env->NewStringUTF(vpx_codec_error(context));
}
VPX_NATIVE_LIBRARY_HELPER_FUNC(jstring, nativeGetLibvpxVersion) {
return env->NewStringUTF(vpx_codec_version_str());
}
VPX_NATIVE_LIBRARY_HELPER_FUNC(jstring, nativeGetLibvpxConfig) {
return env->NewStringUTF(vpx_codec_build_config());
}