mirror of
https://github.com/samsonjs/media.git
synced 2026-04-26 14:57:47 +00:00
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:
parent
383966b307
commit
45a5331e30
4 changed files with 119 additions and 64 deletions
|
|
@ -116,30 +116,10 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
|
||||||
outputMode = VpxDecoder.OUTPUT_MODE_NONE;
|
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
|
@Override
|
||||||
public int supportsFormat(Format format) {
|
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;
|
? (FORMAT_HANDLED | ADAPTIVE_SEAMLESS) : FORMAT_UNSUPPORTED_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,32 +30,6 @@ import java.nio.ByteBuffer;
|
||||||
public static final int OUTPUT_MODE_YUV = 0;
|
public static final int OUTPUT_MODE_YUV = 0;
|
||||||
public static final int OUTPUT_MODE_RGB = 1;
|
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 final long vpxDecContext;
|
||||||
|
|
||||||
private volatile int outputMode;
|
private volatile int outputMode;
|
||||||
|
|
@ -71,6 +45,9 @@ import java.nio.ByteBuffer;
|
||||||
public VpxDecoder(int numInputBuffers, int numOutputBuffers, int initialInputBufferSize)
|
public VpxDecoder(int numInputBuffers, int numOutputBuffers, int initialInputBufferSize)
|
||||||
throws VpxDecoderException {
|
throws VpxDecoderException {
|
||||||
super(new DecoderInputBuffer[numInputBuffers], new VpxOutputBuffer[numOutputBuffers]);
|
super(new DecoderInputBuffer[numInputBuffers], new VpxOutputBuffer[numOutputBuffers]);
|
||||||
|
if (!VpxNativeLibraryHelper.isLibvpxAvailable()) {
|
||||||
|
throw new VpxDecoderException("Failed to load decoder native libraries.");
|
||||||
|
}
|
||||||
vpxDecContext = vpxInit();
|
vpxDecContext = vpxInit();
|
||||||
if (vpxDecContext == 0) {
|
if (vpxDecContext == 0) {
|
||||||
throw new VpxDecoderException("Failed to initialize decoder");
|
throw new VpxDecoderException("Failed to initialize decoder");
|
||||||
|
|
@ -80,7 +57,7 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
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 long vpxDecode(long context, ByteBuffer encoded, int length);
|
||||||
private native int vpxGetFrame(long context, VpxOutputBuffer outputBuffer);
|
private native int vpxGetFrame(long context, VpxOutputBuffer outputBuffer);
|
||||||
private native String vpxGetErrorMessage(long context);
|
private native String vpxGetErrorMessage(long context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
|
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
|
||||||
__VA_ARGS__))
|
__VA_ARGS__))
|
||||||
|
|
||||||
#define FUNC(RETURN_TYPE, NAME, ...) \
|
#define VPX_DECODER_FUNC(RETURN_TYPE, NAME, ...) \
|
||||||
extern "C" { \
|
extern "C" { \
|
||||||
JNIEXPORT RETURN_TYPE \
|
JNIEXPORT RETURN_TYPE \
|
||||||
Java_com_google_android_exoplayer2_ext_vp9_VpxDecoder_ ## NAME \
|
Java_com_google_android_exoplayer2_ext_vp9_VpxDecoder_ ## NAME \
|
||||||
|
|
@ -44,6 +44,16 @@
|
||||||
Java_com_google_android_exoplayer2_ext_vp9_VpxDecoder_ ## NAME \
|
Java_com_google_android_exoplayer2_ext_vp9_VpxDecoder_ ## NAME \
|
||||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
(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.
|
// JNI references for VpxOutputBuffer class.
|
||||||
static jmethodID initForRgbFrame;
|
static jmethodID initForRgbFrame;
|
||||||
static jmethodID initForYuvFrame;
|
static jmethodID initForYuvFrame;
|
||||||
|
|
@ -58,7 +68,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
return JNI_VERSION_1_6;
|
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_ctx_t* context = new vpx_codec_ctx_t();
|
||||||
vpx_codec_dec_cfg_t cfg = {0, 0, 0};
|
vpx_codec_dec_cfg_t cfg = {0, 0, 0};
|
||||||
cfg.threads = android_getCpuCount();
|
cfg.threads = android_getCpuCount();
|
||||||
|
|
@ -81,7 +91,7 @@ FUNC(jlong, vpxInit) {
|
||||||
return reinterpret_cast<intptr_t>(context);
|
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);
|
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
|
||||||
const uint8_t* const buffer =
|
const uint8_t* const buffer =
|
||||||
reinterpret_cast<const uint8_t*>(env->GetDirectBufferAddress(encoded));
|
reinterpret_cast<const uint8_t*>(env->GetDirectBufferAddress(encoded));
|
||||||
|
|
@ -94,14 +104,14 @@ FUNC(jlong, vpxDecode, jlong jContext, jobject encoded, jint len) {
|
||||||
return 0;
|
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_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
|
||||||
vpx_codec_destroy(context);
|
vpx_codec_destroy(context);
|
||||||
delete context;
|
delete context;
|
||||||
return 0;
|
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_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_image_t* const img = vpx_codec_get_frame(context, &iter);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNC(jstring, getLibvpxVersion) {
|
VPX_DECODER_FUNC(jstring, vpxGetErrorMessage, jlong jContext) {
|
||||||
return env->NewStringUTF(vpx_codec_version_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNC(jstring, getLibvpxConfig) {
|
|
||||||
return env->NewStringUTF(vpx_codec_build_config());
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNC(jstring, vpxGetErrorMessage, jlong jContext) {
|
|
||||||
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
|
vpx_codec_ctx_t* const context = reinterpret_cast<vpx_codec_ctx_t*>(jContext);
|
||||||
return env->NewStringUTF(vpx_codec_error(context));
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue