Update Opus decoder, move init ouput buffer to native code

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=131692317
This commit is contained in:
olly 2016-08-30 03:42:27 -07:00 committed by Oliver Woodman
parent cf363f9e97
commit 1fbe62c662
3 changed files with 35 additions and 26 deletions

View file

@ -156,16 +156,12 @@ import java.util.List;
skipSamples = (inputBuffer.timeUs == 0) ? headerSkipSamples : headerSeekPreRollSamples;
}
ByteBuffer inputData = inputBuffer.data;
int inputSize = inputData.limit();
int outputSize = opusGetRequiredOutputBufferSize(inputData, inputSize, SAMPLE_RATE);
if (outputSize < 0) {
return new OpusDecoderException("Error when computing required output buffer size.");
}
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, outputSize);
int result = opusDecode(nativeDecoderContext, inputData, inputSize, outputData, outputSize);
int result = opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(),
outputBuffer, SAMPLE_RATE);
if (result < 0) {
return new OpusDecoderException("Decode error: " + opusGetErrorMessage(result));
}
ByteBuffer outputData = outputBuffer.data;
outputData.position(0);
outputData.limit(result);
if (skipSamples > 0) {
@ -191,10 +187,8 @@ import java.util.List;
private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled,
int gain, byte[] streamMap);
private native int opusDecode(long decoder, ByteBuffer inputBuffer, int inputSize,
ByteBuffer outputBuffer, int outputSize);
private native int opusGetRequiredOutputBufferSize(
ByteBuffer inputBuffer, int inputSize, int sampleRate);
private native int opusDecode(long decoder, long timeUs, ByteBuffer inputBuffer, int inputSize,
SimpleOutputBuffer outputBuffer, int sampleRate);
private native void opusClose(long decoder);
private native void opusReset(long decoder);
private native String opusGetErrorMessage(int errorCode);

View file

@ -37,6 +37,9 @@
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_ ## NAME \
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
// JNI references for SimpleOutputBuffer class.
static jmethodID outputBufferInit;
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
@ -66,30 +69,37 @@ FUNC(jlong, opusInit, jint sampleRate, jint channelCount, jint numStreams,
LOGE("Failed to set Opus header gain; status=%s", opus_strerror(status));
return 0;
}
// Populate JNI References.
const jclass outputBufferClass = env->FindClass(
"com/google/android/exoplayer2/decoder/SimpleOutputBuffer");
outputBufferInit = env->GetMethodID(outputBufferClass, "init",
"(JI)Ljava/nio/ByteBuffer;");
return reinterpret_cast<intptr_t>(decoder);
}
FUNC(jint, opusDecode, jlong jDecoder, jobject jInputBuffer, jint inputSize,
jobject jOutputBuffer, jint outputSize) {
FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs, jobject jInputBuffer,
jint inputSize, jobject jOutputBuffer, jint sampleRate) {
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
const uint8_t* inputBuffer =
reinterpret_cast<const uint8_t*>(
env->GetDirectBufferAddress(jInputBuffer));
int16_t* outputBuffer = reinterpret_cast<int16_t*>(
env->GetDirectBufferAddress(jOutputBuffer));
int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
outputBuffer, outputSize, 0);
return (sampleCount < 0) ? sampleCount
: sampleCount * kBytesPerSample * channelCount;
}
FUNC(jint, opusGetRequiredOutputBufferSize, jobject jInputBuffer,
jint inputSize, jint sampleRate) {
const uint8_t* inputBuffer = reinterpret_cast<const uint8_t*>(
env->GetDirectBufferAddress(jInputBuffer));
const int32_t sampleCount =
const int32_t inputSampleCount =
opus_packet_get_nb_samples(inputBuffer, inputSize, sampleRate);
return sampleCount * kBytesPerSample * channelCount;
const jint outputSize = inputSampleCount * kBytesPerSample * channelCount;
env->CallObjectMethod(jOutputBuffer, outputBufferInit, jTimeUs, outputSize);
const jobject jOutputBufferData = env->CallObjectMethod(jOutputBuffer,
outputBufferInit, jTimeUs, outputSize);
int16_t* outputBufferData = reinterpret_cast<int16_t*>(
env->GetDirectBufferAddress(jOutputBufferData));
int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
outputBufferData, outputSize, 0);
return (sampleCount < 0) ? sampleCount
: sampleCount * kBytesPerSample * channelCount;
}
FUNC(void, opusClose, jlong jDecoder) {

View file

@ -4,3 +4,8 @@
-keepclasseswithmembernames class * {
native <methods>;
}
# Some members of this class are being accessed from native methods. Keep them unobfuscated.
-keep class com.google.android.exoplayer2.decoder.SimpleOutputBuffer {
*;
}