Add nativeDecoderPointer field to IamfDecoder.

Moving this field to `IamfDecoder` instead of `iamf_jni` allows multiple instances of the IAMF decoder with possibly different configurations at the same time.

PiperOrigin-RevId: 662548068
This commit is contained in:
ktrajkovski 2024-08-13 09:35:44 -07:00 committed by Copybara-Service
parent 92cff64321
commit 0b23285bae
2 changed files with 50 additions and 27 deletions

View File

@ -43,6 +43,8 @@ public final class IamfDecoder
private final byte[] initializationData; private final byte[] initializationData;
private final int soundSystem; private final int soundSystem;
private long nativeDecoderPointer;
/** /**
* Creates an IAMF decoder. * Creates an IAMF decoder.
* *
@ -59,12 +61,14 @@ public final class IamfDecoder
} }
soundSystem = spatializationSupported ? SOUND_SYSTEM_5POINT1 : SOUND_SYSTEM_STEREO; soundSystem = spatializationSupported ? SOUND_SYSTEM_5POINT1 : SOUND_SYSTEM_STEREO;
this.initializationData = initializationData.get(0); this.initializationData = initializationData.get(0);
this.nativeDecoderPointer = iamfOpen();
int status = int status =
iamfConfigDecoder( iamfConfigDecoder(
this.initializationData, this.initializationData,
Util.getByteDepth(OUTPUT_PCM_ENCODING) * C.BITS_PER_BYTE, Util.getByteDepth(OUTPUT_PCM_ENCODING) * C.BITS_PER_BYTE,
OUTPUT_SAMPLE_RATE, OUTPUT_SAMPLE_RATE,
soundSystem); soundSystem,
nativeDecoderPointer);
if (status != 0) { if (status != 0) {
throw new IamfDecoderException("Failed to configure decoder with returned status: " + status); throw new IamfDecoderException("Failed to configure decoder with returned status: " + status);
} }
@ -73,7 +77,7 @@ public final class IamfDecoder
@Override @Override
public void release() { public void release() {
super.release(); super.release();
iamfClose(); iamfClose(nativeDecoderPointer);
} }
public int getBinauralLayoutChannelCount() { public int getBinauralLayoutChannelCount() {
@ -109,19 +113,23 @@ public final class IamfDecoder
protected IamfDecoderException decode( protected IamfDecoderException decode(
DecoderInputBuffer inputBuffer, SimpleDecoderOutputBuffer outputBuffer, boolean reset) { DecoderInputBuffer inputBuffer, SimpleDecoderOutputBuffer outputBuffer, boolean reset) {
if (reset) { if (reset) {
iamfClose(); iamfClose(nativeDecoderPointer);
nativeDecoderPointer = iamfOpen();
iamfConfigDecoder( iamfConfigDecoder(
initializationData, initializationData,
Util.getByteDepth(OUTPUT_PCM_ENCODING) * C.BITS_PER_BYTE, Util.getByteDepth(OUTPUT_PCM_ENCODING) * C.BITS_PER_BYTE,
OUTPUT_SAMPLE_RATE, OUTPUT_SAMPLE_RATE,
soundSystem); // reconfigure soundSystem,
nativeDecoderPointer); // reconfigure
} }
int bufferSize = int bufferSize =
iamfGetMaxFrameSize() * getChannelCount() * Util.getByteDepth(OUTPUT_PCM_ENCODING); iamfGetMaxFrameSize(nativeDecoderPointer)
* getChannelCount()
* Util.getByteDepth(OUTPUT_PCM_ENCODING);
outputBuffer.init(inputBuffer.timeUs, bufferSize); outputBuffer.init(inputBuffer.timeUs, bufferSize);
ByteBuffer outputData = Util.castNonNull(outputBuffer.data); ByteBuffer outputData = Util.castNonNull(outputBuffer.data);
ByteBuffer inputData = Util.castNonNull(inputBuffer.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) { if (ret < 0) {
return new IamfDecoderException("Failed to decode error= " + ret); return new IamfDecoderException("Failed to decode error= " + ret);
} }
@ -133,17 +141,24 @@ public final class IamfDecoder
private native int iamfLayoutBinauralChannelsCount(); private native int iamfLayoutBinauralChannelsCount();
private native int iamfConfigDecoder( 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. * Returns the maximum expected number of PCM samples per channel in a compressed audio frame.
* Used to initialize the output buffer. * Used to initialize the output buffer.
*/ */
private native int iamfGetMaxFrameSize(); private native int iamfGetMaxFrameSize(long decoderRawPointer);
private native int iamfGetChannelCount(int soundSystem); private native int iamfGetChannelCount(int soundSystem);
} }

View File

@ -54,23 +54,23 @@ DECODER_FUNC(jint, iamfLayoutBinauralChannelsCount) {
return IAMF_layout_binaural_channels_count(); return IAMF_layout_binaural_channels_count();
} }
IAMF_DecoderHandle handle;
DECODER_FUNC(jint, iamfConfigDecoder, jbyteArray initializationDataArray, DECODER_FUNC(jint, iamfConfigDecoder, jbyteArray initializationDataArray,
jint bitDepth, jint sampleRate, jint layoutType) { jint bitDepth, jint sampleRate, jint soundSystem,
handle = IAMF_decoder_open(); jlong decoderRawPointer) {
IAMF_decoder_peak_limiter_enable(handle, 0); IAMF_DecoderHandle decoder =
IAMF_decoder_set_bit_depth(handle, bitDepth); reinterpret_cast<IAMF_DecoderHandle>(decoderRawPointer);
IAMF_decoder_set_sampling_rate(handle, sampleRate); IAMF_decoder_peak_limiter_enable(decoder, 0);
IAMF_decoder_output_layout_set_sound_system(handle, IAMF_decoder_set_bit_depth(decoder, bitDepth);
(IAMF_SoundSystem)layoutType); IAMF_decoder_set_sampling_rate(decoder, sampleRate);
IAMF_decoder_output_layout_set_sound_system(decoder,
(IAMF_SoundSystem)soundSystem);
uint32_t* bytes_read = nullptr; uint32_t* bytes_read = nullptr;
jbyte* initializationDataBytes = jbyte* initializationDataBytes =
env->GetByteArrayElements(initializationDataArray, 0); env->GetByteArrayElements(initializationDataArray, 0);
int status = IAMF_decoder_configure( int status = IAMF_decoder_configure(
handle, reinterpret_cast<uint8_t*>(initializationDataBytes), decoder, reinterpret_cast<uint8_t*>(initializationDataBytes),
env->GetArrayLength(initializationDataArray), bytes_read); env->GetArrayLength(initializationDataArray), bytes_read);
env->ReleaseByteArrayElements(initializationDataArray, env->ReleaseByteArrayElements(initializationDataArray,
initializationDataBytes, 0); initializationDataBytes, 0);
@ -78,22 +78,30 @@ DECODER_FUNC(jint, iamfConfigDecoder, jbyteArray initializationDataArray,
} }
DECODER_FUNC(jint, iamfDecode, jobject inputBuffer, jint inputSize, DECODER_FUNC(jint, iamfDecode, jobject inputBuffer, jint inputSize,
jobject outputBuffer) { jobject outputBuffer, jlong decoderRawPointer) {
uint32_t* rsize = nullptr; uint32_t* rsize = nullptr;
return IAMF_decoder_decode( return IAMF_decoder_decode(
handle, reinterpret_cast<IAMF_DecoderHandle>(decoderRawPointer),
reinterpret_cast<const uint8_t*>( reinterpret_cast<const uint8_t*>(
env->GetDirectBufferAddress(inputBuffer)), env->GetDirectBufferAddress(inputBuffer)),
inputSize, rsize, inputSize, rsize,
reinterpret_cast<void*>(env->GetDirectBufferAddress(outputBuffer))); reinterpret_cast<void*>(env->GetDirectBufferAddress(outputBuffer)));
} }
DECODER_FUNC(jint, iamfGetMaxFrameSize) { DECODER_FUNC(jint, iamfGetMaxFrameSize, jlong decoderRawPointer) {
return IAMF_decoder_get_stream_info(handle)->max_frame_size; return IAMF_decoder_get_stream_info(
reinterpret_cast<IAMF_DecoderHandle>(decoderRawPointer))
->max_frame_size;
} }
DECODER_FUNC(jint, iamfGetChannelCount, jint layoutType) { DECODER_FUNC(jint, iamfGetChannelCount, jint soundSystem) {
return IAMF_layout_sound_system_channels_count((IAMF_SoundSystem)layoutType); 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<IAMF_DecoderHandle>(decoderRawPointer));
}
DECODER_FUNC(jlong, iamfOpen) {
return reinterpret_cast<intptr_t>(IAMF_decoder_open());
}