diff --git a/libraries/decoder_iamf/src/main/java/androidx/media3/decoder/iamf/IamfDecoder.java b/libraries/decoder_iamf/src/main/java/androidx/media3/decoder/iamf/IamfDecoder.java index 1f8f7cf2a0..f98c30cb91 100644 --- a/libraries/decoder_iamf/src/main/java/androidx/media3/decoder/iamf/IamfDecoder.java +++ b/libraries/decoder_iamf/src/main/java/androidx/media3/decoder/iamf/IamfDecoder.java @@ -43,6 +43,8 @@ public final class IamfDecoder private final byte[] initializationData; private final int soundSystem; + private long nativeDecoderPointer; + /** * Creates an IAMF decoder. * @@ -59,12 +61,14 @@ public final class IamfDecoder } soundSystem = spatializationSupported ? SOUND_SYSTEM_5POINT1 : SOUND_SYSTEM_STEREO; this.initializationData = initializationData.get(0); + this.nativeDecoderPointer = iamfOpen(); int status = iamfConfigDecoder( this.initializationData, Util.getByteDepth(OUTPUT_PCM_ENCODING) * C.BITS_PER_BYTE, OUTPUT_SAMPLE_RATE, - soundSystem); + soundSystem, + nativeDecoderPointer); if (status != 0) { throw new IamfDecoderException("Failed to configure decoder with returned status: " + status); } @@ -73,7 +77,7 @@ public final class IamfDecoder @Override public void release() { super.release(); - iamfClose(); + iamfClose(nativeDecoderPointer); } public int getBinauralLayoutChannelCount() { @@ -109,19 +113,23 @@ public final class IamfDecoder protected IamfDecoderException decode( DecoderInputBuffer inputBuffer, SimpleDecoderOutputBuffer outputBuffer, boolean reset) { if (reset) { - iamfClose(); + iamfClose(nativeDecoderPointer); + nativeDecoderPointer = iamfOpen(); iamfConfigDecoder( initializationData, Util.getByteDepth(OUTPUT_PCM_ENCODING) * C.BITS_PER_BYTE, OUTPUT_SAMPLE_RATE, - soundSystem); // reconfigure + soundSystem, + nativeDecoderPointer); // reconfigure } int bufferSize = - iamfGetMaxFrameSize() * getChannelCount() * Util.getByteDepth(OUTPUT_PCM_ENCODING); + iamfGetMaxFrameSize(nativeDecoderPointer) + * getChannelCount() + * Util.getByteDepth(OUTPUT_PCM_ENCODING); outputBuffer.init(inputBuffer.timeUs, bufferSize); ByteBuffer outputData = Util.castNonNull(outputBuffer.data); ByteBuffer inputData = Util.castNonNull(inputBuffer.data); - int ret = iamfDecode(inputData, inputData.limit(), outputData); + int ret = iamfDecode(inputData, inputData.limit(), outputData, nativeDecoderPointer); if (ret < 0) { return new IamfDecoderException("Failed to decode error= " + ret); } @@ -133,17 +141,24 @@ public final class IamfDecoder private native int iamfLayoutBinauralChannelsCount(); private native int iamfConfigDecoder( - byte[] initializationData, int bitDepth, int sampleRate, int soundSystem); + byte[] initializationData, + int bitDepth, + int sampleRate, + int soundSystem, + long decoderRawPointer); - private native void iamfClose(); + private native long iamfOpen(); - private native int iamfDecode(ByteBuffer inputBuffer, int inputSize, ByteBuffer outputBuffer); + private native void iamfClose(long decoderRawPointer); + + private native int iamfDecode( + ByteBuffer inputBuffer, int inputSize, ByteBuffer outputBuffer, long decoderRawPointer); /** * Returns the maximum expected number of PCM samples per channel in a compressed audio frame. * Used to initialize the output buffer. */ - private native int iamfGetMaxFrameSize(); + private native int iamfGetMaxFrameSize(long decoderRawPointer); private native int iamfGetChannelCount(int soundSystem); } diff --git a/libraries/decoder_iamf/src/main/jni/iamf_jni.cc b/libraries/decoder_iamf/src/main/jni/iamf_jni.cc index 74d3932027..13c4935540 100644 --- a/libraries/decoder_iamf/src/main/jni/iamf_jni.cc +++ b/libraries/decoder_iamf/src/main/jni/iamf_jni.cc @@ -54,23 +54,23 @@ DECODER_FUNC(jint, iamfLayoutBinauralChannelsCount) { return IAMF_layout_binaural_channels_count(); } -IAMF_DecoderHandle handle; - DECODER_FUNC(jint, iamfConfigDecoder, jbyteArray initializationDataArray, - jint bitDepth, jint sampleRate, jint layoutType) { - handle = IAMF_decoder_open(); - IAMF_decoder_peak_limiter_enable(handle, 0); - IAMF_decoder_set_bit_depth(handle, bitDepth); - IAMF_decoder_set_sampling_rate(handle, sampleRate); - IAMF_decoder_output_layout_set_sound_system(handle, - (IAMF_SoundSystem)layoutType); + jint bitDepth, jint sampleRate, jint soundSystem, + jlong decoderRawPointer) { + IAMF_DecoderHandle decoder = + reinterpret_cast(decoderRawPointer); + IAMF_decoder_peak_limiter_enable(decoder, 0); + IAMF_decoder_set_bit_depth(decoder, bitDepth); + IAMF_decoder_set_sampling_rate(decoder, sampleRate); + IAMF_decoder_output_layout_set_sound_system(decoder, + (IAMF_SoundSystem)soundSystem); uint32_t* bytes_read = nullptr; jbyte* initializationDataBytes = env->GetByteArrayElements(initializationDataArray, 0); int status = IAMF_decoder_configure( - handle, reinterpret_cast(initializationDataBytes), + decoder, reinterpret_cast(initializationDataBytes), env->GetArrayLength(initializationDataArray), bytes_read); env->ReleaseByteArrayElements(initializationDataArray, initializationDataBytes, 0); @@ -78,22 +78,30 @@ DECODER_FUNC(jint, iamfConfigDecoder, jbyteArray initializationDataArray, } DECODER_FUNC(jint, iamfDecode, jobject inputBuffer, jint inputSize, - jobject outputBuffer) { + jobject outputBuffer, jlong decoderRawPointer) { uint32_t* rsize = nullptr; return IAMF_decoder_decode( - handle, + reinterpret_cast(decoderRawPointer), reinterpret_cast( env->GetDirectBufferAddress(inputBuffer)), inputSize, rsize, reinterpret_cast(env->GetDirectBufferAddress(outputBuffer))); } -DECODER_FUNC(jint, iamfGetMaxFrameSize) { - return IAMF_decoder_get_stream_info(handle)->max_frame_size; +DECODER_FUNC(jint, iamfGetMaxFrameSize, jlong decoderRawPointer) { + return IAMF_decoder_get_stream_info( + reinterpret_cast(decoderRawPointer)) + ->max_frame_size; } -DECODER_FUNC(jint, iamfGetChannelCount, jint layoutType) { - return IAMF_layout_sound_system_channels_count((IAMF_SoundSystem)layoutType); +DECODER_FUNC(jint, iamfGetChannelCount, jint soundSystem) { + return IAMF_layout_sound_system_channels_count((IAMF_SoundSystem)soundSystem); } -DECODER_FUNC(void, iamfClose) { IAMF_decoder_close(handle); } +DECODER_FUNC(void, iamfClose, jlong decoderRawPointer) { + IAMF_decoder_close(reinterpret_cast(decoderRawPointer)); +} + +DECODER_FUNC(jlong, iamfOpen) { + return reinterpret_cast(IAMF_decoder_open()); +}