Skip to content

Commit

Permalink
[DO NOT MERGE] IAMF Android implementation
Browse files Browse the repository at this point in the history
b/341792042
  • Loading branch information
osagie98 committed Jan 14, 2025
1 parent ca2b1f5 commit 0d4126b
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Build;
import android.os.Build.VERSION;
import androidx.annotation.RequiresApi;
import dev.cobalt.coat.CobaltMediaSession;
import dev.cobalt.util.Log;
Expand Down Expand Up @@ -332,6 +333,16 @@ int getMinBufferSize(int sampleType, int sampleRate, int channelCount) {
case 6:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
break;
case 8:
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
break;
case 10:
if (VERSION.SDK_INT >= 32) {
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1POINT2;
} else {
throw new RuntimeException("Unsupported channel count: " + channelCount);
}
break;
default:
throw new RuntimeException("Unsupported channel count: " + channelCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.media.AudioTimestamp;
import android.media.AudioTrack;
import android.os.Build;
import android.os.Build.VERSION;
import androidx.annotation.RequiresApi;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
Expand Down Expand Up @@ -80,6 +81,16 @@ public AudioTrackBridge(
case 6:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
break;
case 8:
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
break;
case 10:
if (VERSION.SDK_INT >= 32) {
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1POINT2;
} else {
throw new RuntimeException("Unsupported channel count: " + channelCount);
}
break;
default:
throw new RuntimeException("Unsupported channel count: " + channelCount);
}
Expand Down Expand Up @@ -117,7 +128,7 @@ public AudioTrackBridge(
isWebAudio ? AudioAttributes.USAGE_NOTIFICATION : AudioAttributes.USAGE_MEDIA;
// TODO: Support ENCODING_E_AC3_JOC for api level 28 or later.
final boolean isSurround =
sampleType == AudioFormat.ENCODING_AC3 || sampleType == AudioFormat.ENCODING_E_AC3;
sampleType == AudioFormat.ENCODING_AC3 || sampleType == AudioFormat.ENCODING_E_AC3 || channelCount > 2;
final boolean useContentTypeMovie = isSurround || !isWebAudio;
attributes =
new AudioAttributes.Builder()
Expand Down
15 changes: 13 additions & 2 deletions starboard/android/shared/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ static_library("starboard_platform") {
"//starboard/shared/posix/socket_join_multicast_group.cc",
"//starboard/shared/posix/socket_listen.cc",
"//starboard/shared/posix/socket_receive_from.cc",
"//starboard/shared/posix/socket_receive_multi_msg_internal.cc",
"//starboard/shared/posix/socket_receive_multi_msg_internal.h",
"//starboard/shared/posix/socket_receive_multi_msg.cc",
"//starboard/shared/posix/socket_receive_multi_msg.h",
"//starboard/shared/posix/socket_receive_multi_msg_internal.cc",
"//starboard/shared/posix/socket_receive_multi_msg_internal.h",
"//starboard/shared/posix/socket_resolve.cc",
"//starboard/shared/posix/socket_send_to.cc",
"//starboard/shared/posix/socket_set_broadcast.cc",
Expand Down Expand Up @@ -497,6 +497,17 @@ static_library("starboard_platform") {
if (sb_evergreen_compatible_use_libunwind) {
deps += [ "//third_party/llvm-project/libunwind:unwind_starboard" ]
}

if (enable_iamf_decode) {
sources += [
"//starboard/shared/libiamf/iamf_audio_decoder.cc",
"//starboard/shared/libiamf/iamf_audio_decoder.h",
"//starboard/shared/libiamf/iamf_decoder_utils.cc",
"//starboard/shared/libiamf/iamf_decoder_utils.h",
]

defines = [ "ENABLE_IAMF_DECODE" ]
}
}

static_library("starboard_base_symbolize") {
Expand Down
5 changes: 5 additions & 0 deletions starboard/android/shared/media_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ inline const char* SupportedAudioCodecToMimeType(
if (audio_codec == kSbMediaAudioCodecOpus) {
return "audio/opus";
}
#if SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
if (audio_codec == kSbMediaAudioCodecIamf) {
return "audio/iamf";
}
#endif // SB_API_VERSION >= 15 && ENABLE_IAMF_DECOD
return nullptr;
}

Expand Down
32 changes: 32 additions & 0 deletions starboard/android/shared/media_is_audio_supported.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,23 @@
#include "starboard/configuration.h"
#include "starboard/configuration_constants.h"
#include "starboard/media.h"
#include "starboard/shared/starboard/media/iamf_util.h"

using starboard::android::shared::MediaCapabilitiesCache;
using starboard::android::shared::SupportedAudioCodecToMimeType;
using starboard::shared::starboard::media::IamfMimeUtil;
using starboard::shared::starboard::media::kIamfProfileBase;
using starboard::shared::starboard::media::kIamfProfileSimple;
using starboard::shared::starboard::media::kIamfSubstreamCodecOpus;
using starboard::shared::starboard::media::MimeType;

bool HasSupportedIamfProfile(const IamfMimeUtil* mime_util) {
return mime_util->primary_profile() == kIamfProfileSimple ||
mime_util->primary_profile() == kIamfProfileBase ||
mime_util->additional_profile() == kIamfProfileSimple ||
mime_util->additional_profile() == kIamfProfileBase;
}

bool SbMediaIsAudioSupported(SbMediaAudioCodec audio_codec,
const MimeType* mime_type,
int64_t bitrate) {
Expand Down Expand Up @@ -60,6 +72,26 @@ bool SbMediaIsAudioSupported(SbMediaAudioCodec audio_codec,
return true;
}

#if SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
if (audio_codec == kSbMediaAudioCodecIamf) {
if (!mime_type || !mime_type->is_valid()) {
return false;
}
const std::vector<std::string>& codecs = mime_type->GetCodecs();
for (auto& codec : codecs) {
IamfMimeUtil mime_util(codec);
// We support only IAMF Base or Simple profile streams with an Opus
// substream.
if (mime_util.is_valid() &&
mime_util.substream_codec() == kIamfSubstreamCodecOpus &&
HasSupportedIamfProfile(&mime_util)) {
return bitrate <= kSbMediaMaxAudioBitrateInBitsPerSecond;
}
}
return false;
}
#endif // SB_API_VERSION >= 15

bool media_codec_supported =
MediaCapabilitiesCache::GetInstance()->HasAudioDecoderFor(mime, bitrate);

Expand Down
4 changes: 4 additions & 0 deletions starboard/android/shared/platform_configuration/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ config("platform_configuration") {
"mediandk",
]

if (enable_iamf_decode) {
libs += [ "//third_party/libiamf/platforms/android/libiamf.a" ]
}

if (!cobalt_fastbuild && (is_debug || is_devel)) {
cflags += [ "-g" ]
}
Expand Down
17 changes: 17 additions & 0 deletions starboard/android/shared/player_components_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
#include "starboard/shared/starboard/player/filter/video_renderer_internal_impl.h"
#include "starboard/shared/starboard/player/filter/video_renderer_sink.h"

#if SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
#include "starboard/shared/libiamf/iamf_audio_decoder.h"
#endif // SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE

namespace starboard {
namespace android {
namespace shared {
Expand Down Expand Up @@ -178,6 +182,9 @@ class PlayerComponentsPassthrough
// into .cc file.
class PlayerComponentsFactory : public starboard::shared::starboard::player::
filter::PlayerComponents::Factory {
#if SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
typedef starboard::shared::libiamf::IamfAudioDecoder IamfAudioDecoder;
#endif // SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
typedef starboard::shared::starboard::media::MimeType MimeType;
typedef starboard::shared::opus::OpusAudioDecoder OpusAudioDecoder;
typedef starboard::shared::starboard::player::filter::AdaptiveAudioDecoder
Expand Down Expand Up @@ -444,6 +451,16 @@ class PlayerComponentsFactory : public starboard::shared::starboard::player::
return std::unique_ptr<AudioDecoderBase>(
std::move(audio_decoder_impl));
}
#if SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
} else if (audio_stream_info.codec == kSbMediaAudioCodecIamf &&
!SbDrmSystemIsValid(drm_system)) {
std::unique_ptr<IamfAudioDecoder> audio_decoder_impl(
new IamfAudioDecoder(audio_stream_info));
if (audio_decoder_impl->is_valid()) {
return std::unique_ptr<AudioDecoderBase>(
std::move(audio_decoder_impl));
}
#endif // SB_API_VERSION >= 15
} else {
SB_LOG(ERROR) << "Unsupported audio codec "
<< audio_stream_info.codec;
Expand Down
3 changes: 3 additions & 0 deletions starboard/android/shared/player_create.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ SbPlayer SbPlayerCreate(SbWindow window,
audio_codec != kSbMediaAudioCodecAac &&
audio_codec != kSbMediaAudioCodecAc3 &&
audio_codec != kSbMediaAudioCodecEac3 &&
#if SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
audio_codec != kSbMediaAudioCodecIamf &&
#endif // SB_API_VERSION >= 15 && ENABLE_IAMF_DECODE
audio_codec != kSbMediaAudioCodecOpus) {
SB_LOG(ERROR) << "Unsupported audio codec: "
<< starboard::GetMediaAudioCodecName(audio_codec) << ".";
Expand Down
7 changes: 4 additions & 3 deletions starboard/shared/libiamf/iamf_decoder_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ class BufferReader {
if (!HasBytes(1) || !ptr) {
return false;
}
int bytes_read = ReadLeb128Internal(
buf_ + pos_, ptr,
std::min(static_cast<uint64_t>(RemainingSize()), sizeof(uint32_t)));
int bytes_read =
ReadLeb128Internal(buf_ + pos_, ptr,
std::min(static_cast<uint64_t>(RemainingSize()),
static_cast<uint64_t>(sizeof(uint32_t))));
if (bytes_read < 0) {
return false;
}
Expand Down

0 comments on commit 0d4126b

Please sign in to comment.