Skip to content

Commit

Permalink
Update Opus decoder, move init ouput buffer to native code
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=128192252
  • Loading branch information
botaydotcom authored and ojw28 committed Jul 28, 2016
1 parent 1c326a8 commit dfccb0c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,8 @@ public OpusDecoderException decode(InputBuffer inputBuffer, OpusOutputBuffer out
SampleHolder sampleHolder = inputBuffer.sampleHolder;
outputBuffer.timestampUs = sampleHolder.timeUs;
sampleHolder.data.position(sampleHolder.data.position() - sampleHolder.size);
int requiredOutputBufferSize =
opusGetRequiredOutputBufferSize(sampleHolder.data, sampleHolder.size, SAMPLE_RATE);
if (requiredOutputBufferSize < 0) {
return new OpusDecoderException("Error when computing required output buffer size.");
}
outputBuffer.init(requiredOutputBufferSize);
int result = opusDecode(nativeDecoderContext, sampleHolder.data, sampleHolder.size,
outputBuffer.data, outputBuffer.data.capacity());
outputBuffer, SAMPLE_RATE);
if (result < 0) {
return new OpusDecoderException("Decode error: " + opusGetErrorMessage(result));
}
Expand Down Expand Up @@ -199,9 +193,7 @@ public void release() {
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);
OpusOutputBuffer outputBuffer, int sampleRate);
private native void opusClose(long decoder);
private native void opusReset(long decoder);
private native String opusGetErrorMessage(int errorCode);
Expand Down
33 changes: 23 additions & 10 deletions extensions/opus/src/main/jni/opus_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
Java_com_google_android_exoplayer_ext_opus_OpusDecoder_ ## NAME \
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\

// JNI references for OpusOutputBuffer class.
static jmethodID initOpusOutputBuffer;
static jfieldID opusDataField;

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
Expand Down Expand Up @@ -66,15 +70,33 @@ 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/exoplayer/ext/opus/OpusOutputBuffer");
initOpusOutputBuffer = env->GetMethodID(outputBufferClass, "init", "(I)V");
opusDataField =
env->GetFieldID(outputBufferClass, "data", "Ljava/nio/ByteBuffer;");

return reinterpret_cast<intptr_t>(decoder);
}

FUNC(jint, opusDecode, jlong jDecoder, jobject jInputBuffer, jint inputSize,
jobject jOutputBuffer, jint outputSize) {
jobject jOpusOutputBuffer, jint sampleRate) {
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
const uint8_t* inputBuffer =
reinterpret_cast<const uint8_t*>(
env->GetDirectBufferAddress(jInputBuffer));

const int32_t inputSampleCount =
opus_packet_get_nb_samples(inputBuffer, inputSize, sampleRate);
const jint outputSize = inputSampleCount * kBytesPerSample * channelCount;

// resize buffer:
env->CallVoidMethod(jOpusOutputBuffer, initOpusOutputBuffer, outputSize);
const jobject jOutputBuffer =
env->GetObjectField(jOpusOutputBuffer, opusDataField);

int16_t* outputBuffer = reinterpret_cast<int16_t*>(
env->GetDirectBufferAddress(jOutputBuffer));
int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
Expand All @@ -83,15 +105,6 @@ FUNC(jint, opusDecode, jlong jDecoder, jobject jInputBuffer, jint inputSize,
: 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 =
opus_packet_get_nb_samples(inputBuffer, inputSize, sampleRate);
return sampleCount * kBytesPerSample * channelCount;
}

FUNC(void, opusClose, jlong jDecoder) {
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
opus_multistream_decoder_destroy(decoder);
Expand Down
5 changes: 5 additions & 0 deletions extensions/opus/src/main/proguard.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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.exoplayer.ext.opus.OpusOutputBuffer {
*;
}

0 comments on commit dfccb0c

Please sign in to comment.