mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
cf363f9e97
commit
1fbe62c662
3 changed files with 35 additions and 26 deletions
|
|
@ -156,16 +156,12 @@ import java.util.List;
|
||||||
skipSamples = (inputBuffer.timeUs == 0) ? headerSkipSamples : headerSeekPreRollSamples;
|
skipSamples = (inputBuffer.timeUs == 0) ? headerSkipSamples : headerSeekPreRollSamples;
|
||||||
}
|
}
|
||||||
ByteBuffer inputData = inputBuffer.data;
|
ByteBuffer inputData = inputBuffer.data;
|
||||||
int inputSize = inputData.limit();
|
int result = opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(),
|
||||||
int outputSize = opusGetRequiredOutputBufferSize(inputData, inputSize, SAMPLE_RATE);
|
outputBuffer, 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);
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return new OpusDecoderException("Decode error: " + opusGetErrorMessage(result));
|
return new OpusDecoderException("Decode error: " + opusGetErrorMessage(result));
|
||||||
}
|
}
|
||||||
|
ByteBuffer outputData = outputBuffer.data;
|
||||||
outputData.position(0);
|
outputData.position(0);
|
||||||
outputData.limit(result);
|
outputData.limit(result);
|
||||||
if (skipSamples > 0) {
|
if (skipSamples > 0) {
|
||||||
|
|
@ -191,10 +187,8 @@ import java.util.List;
|
||||||
|
|
||||||
private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled,
|
private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled,
|
||||||
int gain, byte[] streamMap);
|
int gain, byte[] streamMap);
|
||||||
private native int opusDecode(long decoder, ByteBuffer inputBuffer, int inputSize,
|
private native int opusDecode(long decoder, long timeUs, ByteBuffer inputBuffer, int inputSize,
|
||||||
ByteBuffer outputBuffer, int outputSize);
|
SimpleOutputBuffer outputBuffer, int sampleRate);
|
||||||
private native int opusGetRequiredOutputBufferSize(
|
|
||||||
ByteBuffer inputBuffer, int inputSize, int sampleRate);
|
|
||||||
private native void opusClose(long decoder);
|
private native void opusClose(long decoder);
|
||||||
private native void opusReset(long decoder);
|
private native void opusReset(long decoder);
|
||||||
private native String opusGetErrorMessage(int errorCode);
|
private native String opusGetErrorMessage(int errorCode);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@
|
||||||
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_ ## NAME \
|
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_ ## NAME \
|
||||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
||||||
|
|
||||||
|
// JNI references for SimpleOutputBuffer class.
|
||||||
|
static jmethodID outputBufferInit;
|
||||||
|
|
||||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
JNIEnv* env;
|
JNIEnv* env;
|
||||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
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));
|
LOGE("Failed to set Opus header gain; status=%s", opus_strerror(status));
|
||||||
return 0;
|
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);
|
return reinterpret_cast<intptr_t>(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNC(jint, opusDecode, jlong jDecoder, jobject jInputBuffer, jint inputSize,
|
FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs, jobject jInputBuffer,
|
||||||
jobject jOutputBuffer, jint outputSize) {
|
jint inputSize, jobject jOutputBuffer, jint sampleRate) {
|
||||||
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
|
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
|
||||||
const uint8_t* inputBuffer =
|
const uint8_t* inputBuffer =
|
||||||
reinterpret_cast<const uint8_t*>(
|
reinterpret_cast<const uint8_t*>(
|
||||||
env->GetDirectBufferAddress(jInputBuffer));
|
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,
|
const int32_t inputSampleCount =
|
||||||
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);
|
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) {
|
FUNC(void, opusClose, jlong jDecoder) {
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,8 @@
|
||||||
-keepclasseswithmembernames class * {
|
-keepclasseswithmembernames class * {
|
||||||
native <methods>;
|
native <methods>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Some members of this class are being accessed from native methods. Keep them unobfuscated.
|
||||||
|
-keep class com.google.android.exoplayer2.decoder.SimpleOutputBuffer {
|
||||||
|
*;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue