Add skeleton of the IAMF JNI wrapper for the native decoder in libiamf.

PiperOrigin-RevId: 652761237
This commit is contained in:
ktrajkovski 2024-07-16 02:51:49 -07:00 committed by Copybara-Service
parent c60baabb1c
commit 104fcc1c76
10 changed files with 359 additions and 0 deletions

View File

@ -0,0 +1,5 @@
# IAMF support in ExoPlayer
This is a Work-In-Progress for an extension which shall provide support for IAMF
in Exoplayer. Please await further announcements via Release Notes for
information on the full integration into the library.

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2024 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="androidx.media3.decoder.iamf.test">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-sdk/>
<application
android:name="androidx.multidex.MultiDexApplication"
android:allowBackup="false"
tools:ignore="MissingApplicationIcon,HardcodedDebugMode"/>
<instrumentation
android:targetPackage="androidx.media3.decoder.iamf.test"
android:name="androidx.test.runner.AndroidJUnitRunner"/>
</manifest>

View File

@ -0,0 +1,39 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.decoder.iamf;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test IAMF native functions. */
@RunWith(AndroidJUnit4.class)
public final class IamfDecoderTest {
@Before
public void setUp() {
assertThat(IamfLibrary.isAvailable()).isTrue();
}
@Test
public void iamfLayoutBinauralChannelsCountTest() {
IamfDecoder iamf = new IamfDecoder();
assertThat(iamf.getBinauralLayoutChannelCount()).isEqualTo(2);
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.decoder.iamf;
import static android.support.annotation.VisibleForTesting.PACKAGE_PRIVATE;
import androidx.annotation.VisibleForTesting;
import androidx.media3.decoder.DecoderInputBuffer;
import androidx.media3.decoder.SimpleDecoder;
import androidx.media3.decoder.SimpleDecoderOutputBuffer;
/** IAMF decoder. */
@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
public final class IamfDecoder
extends SimpleDecoder<DecoderInputBuffer, SimpleDecoderOutputBuffer, IamfDecoderException> {
public IamfDecoder() {
super(new DecoderInputBuffer[0], new SimpleDecoderOutputBuffer[0]);
}
public int getBinauralLayoutChannelCount() {
return iamfLayoutBinauralChannelsCount();
}
@Override
public String getName() {
return "libiamf";
}
@Override
protected DecoderInputBuffer createInputBuffer() {
throw new UnsupportedOperationException();
}
@Override
protected SimpleDecoderOutputBuffer createOutputBuffer() {
throw new UnsupportedOperationException();
}
@Override
protected IamfDecoderException createUnexpectedDecodeException(Throwable error) {
throw new UnsupportedOperationException();
}
@Override
protected IamfDecoderException decode(
DecoderInputBuffer inputBuffer, SimpleDecoderOutputBuffer outputBuffer, boolean reset) {
throw new UnsupportedOperationException();
}
private native int iamfLayoutBinauralChannelsCount();
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.decoder.iamf;
import androidx.media3.decoder.DecoderException;
/** Thrown when an IAMF decoder error occurs. */
final class IamfDecoderException extends DecoderException {
/* package */ IamfDecoderException(String message) {
super(message);
}
/* package */ IamfDecoderException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.decoder.iamf;
import androidx.media3.common.C;
import androidx.media3.common.MediaLibraryInfo;
import androidx.media3.common.util.LibraryLoader;
import androidx.media3.common.util.UnstableApi;
/** Configures and queries the underlying native library. */
@UnstableApi
public final class IamfLibrary {
static {
MediaLibraryInfo.registerModule("media3.decoder.iamf");
}
private static final LibraryLoader LOADER =
new LibraryLoader("iamfJNI") {
@Override
protected void loadLibrary(String name) {
System.loadLibrary(name);
}
};
private IamfLibrary() {}
/**
* Override the names of the IAMF native libraries. If an application wishes to call this method,
* it must do so before calling any other method defined by this class, and before instantiating a
* {@link LibiamfAudioRenderer} instance.
*
* @param cryptoType The {@link C.CryptoType} for which the decoder library supports decrypting
* protected content, or {@link C#CRYPTO_TYPE_UNSUPPORTED} if the library does not support
* decryption.
* @param libraries The names of the IAMF native libraries.
*/
public static void setLibraries(@C.CryptoType int cryptoType, String... libraries) {
LOADER.setLibraries(libraries);
}
/** Returns whether the underlying library is available, loading it if necessary. */
public static boolean isAvailable() {
return LOADER.isAvailable();
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.decoder.iamf;
import androidx.annotation.Nullable;
import androidx.media3.common.Format;
import androidx.media3.decoder.CryptoConfig;
import androidx.media3.decoder.DecoderException;
import androidx.media3.exoplayer.audio.DecoderAudioRenderer;
/** Decodes and renders audio using the native IAMF decoder. */
public class LibiamfAudioRenderer extends DecoderAudioRenderer<IamfDecoder> {
public LibiamfAudioRenderer() {}
@Override
protected int supportsFormatInternal(Format format) {
throw new UnsupportedOperationException();
}
@Override
protected IamfDecoder createDecoder(Format format, @Nullable CryptoConfig cryptoConfig)
throws DecoderException {
throw new UnsupportedOperationException();
}
@Override
protected Format getOutputFormat(IamfDecoder decoder) {
throw new UnsupportedOperationException();
}
@Override
public String getName() {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@NonNullApi
package androidx.media3.decoder.iamf;
import androidx.media3.common.util.NonNullApi;

View File

@ -0,0 +1,55 @@
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef __ANDROID__
#include <android/log.h>
#endif
#include <jni.h>
#include <cstdint>
#include <cstdlib>
#include "IAMF_decoder.h"
#include "IAMF_defines.h"
#ifdef __ANDROID__
#define LOG_TAG "iamf_jni"
#define LOGE(...) \
((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#else // __ANDROID__
#define LOGE(...) \
do { \
} while (0)
#endif // __ANDROID__
#define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
extern "C" { \
JNIEXPORT RETURN_TYPE Java_androidx_media3_decoder_iamf_IamfDecoder_##NAME( \
JNIEnv* env, jobject thiz, ##__VA_ARGS__); \
} \
JNIEXPORT RETURN_TYPE Java_androidx_media3_decoder_iamf_IamfDecoder_##NAME( \
JNIEnv* env, jobject thiz, ##__VA_ARGS__)
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
return JNI_VERSION_1_6;
}
DECODER_FUNC(jint, iamfLayoutBinauralChannelsCount) {
return IAMF_layout_binaural_channels_count();
}

View File

@ -0,0 +1,6 @@
# Proguard rules specific to the IAMF extension.
# This prevents the names of native methods from being obfuscated.
-keepclasseswithmembernames class * {
native <methods>;
}