Add SAD to AudioPort and encapsulation type to AudioProfile.
Short audio descriptor(SAD) is defined in HDMI specification 1.4b
section 7 that is used to describe the audio capabilities over HDMI.
The encapsulation types represent the encapsulation formats that must be
used when sending the audio data with the format associated with the
AudioProfile to Android.
Bug: 131736540
Bug: 178619392
Test: atest AudioManagerTes
Change-Id: Ie9ab83c8147edfe211363d9676e9cb04dda5b489
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index 20d8632..fafabd9 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -16,7 +16,9 @@
#define LOG_TAG "AudioPort"
#include <algorithm>
+#include <utility>
+#include <android/media/ExtraAudioDescriptor.h>
#include <android-base/stringprintf.h>
#include <media/AudioPort.h>
#include <utils/Log.h>
@@ -46,11 +48,26 @@
port.audio_profiles->num_channel_masks),
SampleRateSet(port.audio_profiles[i].sample_rates,
port.audio_profiles[i].sample_rates +
- port.audio_profiles[i].num_sample_rates));
+ port.audio_profiles[i].num_sample_rates),
+ port.audio_profiles[i].encapsulation_type);
if (!mProfiles.contains(profile)) {
addAudioProfile(profile);
}
}
+
+ for (size_t i = 0; i < port.num_extra_audio_descriptors; ++i) {
+ auto convertedResult = legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(
+ port.extra_audio_descriptors[i]);
+ if (!convertedResult.ok()) {
+ ALOGE("%s, failed to convert extra audio descriptor", __func__);
+ continue;
+ }
+ if (std::find(mExtraAudioDescriptors.begin(),
+ mExtraAudioDescriptors.end(),
+ convertedResult.value()) == mExtraAudioDescriptors.end()) {
+ mExtraAudioDescriptors.push_back(std::move(convertedResult.value()));
+ }
+ }
}
void AudioPort::toAudioPort(struct audio_port *port) const {
@@ -98,7 +115,7 @@
channelMasks.size() > AUDIO_PORT_MAX_CHANNEL_MASKS ||
port->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
ALOGE("%s: bailing out: cannot export profiles to port config", __func__);
- return;
+ break;
}
auto& dstProfile = port->audio_profiles[port->num_audio_profiles++];
@@ -109,8 +126,25 @@
dstProfile.num_channel_masks = channelMasks.size();
std::copy(channelMasks.begin(), channelMasks.end(),
std::begin(dstProfile.channel_masks));
+ dstProfile.encapsulation_type = profile->getEncapsulationType();
}
}
+
+ port->num_extra_audio_descriptors = 0;
+ for (const auto& desc : mExtraAudioDescriptors) {
+ if (port->num_extra_audio_descriptors >= AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
+ ALOGE("%s: bailing out: cannot export extra audio descriptor to port config", __func__);
+ return;
+ }
+
+ auto convertedResult = aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(desc);
+ if (!convertedResult.ok()) {
+ ALOGE("%s: failed to convert extra audio descriptor", __func__);
+ continue;
+ }
+ port->extra_audio_descriptors[port->num_extra_audio_descriptors++] =
+ std::move(convertedResult.value());
+ }
}
void AudioPort::dump(std::string *dst, int spaces, bool verbose) const {
@@ -121,6 +155,22 @@
std::string profilesStr;
mProfiles.dump(&profilesStr, spaces);
dst->append(profilesStr);
+ if (!mExtraAudioDescriptors.empty()) {
+ dst->append(base::StringPrintf("%*s- extra audio descriptors: \n", spaces, ""));
+ const int eadSpaces = spaces + 4;
+ const int descSpaces = eadSpaces + 4;
+ for (size_t i = 0; i < mExtraAudioDescriptors.size(); i++) {
+ dst->append(
+ base::StringPrintf("%*s extra audio descriptor %zu:\n", eadSpaces, "", i));
+ dst->append(base::StringPrintf(
+ "%*s- standard: %u\n", descSpaces, "", mExtraAudioDescriptors[i].standard));
+ dst->append(base::StringPrintf("%*s- descriptor:", descSpaces, ""));
+ for (auto v : mExtraAudioDescriptors[i].audioDescriptor) {
+ dst->append(base::StringPrintf(" %02x", v));
+ }
+ dst->append("\n");
+ }
+ }
if (mGains.size() != 0) {
dst->append(base::StringPrintf("%*s- gains:\n", spaces, ""));
@@ -145,7 +195,8 @@
mName.compare(other->getName()) == 0 &&
mType == other->getType() &&
mRole == other->getRole() &&
- mProfiles.equals(other->getAudioProfiles());
+ mProfiles.equals(other->getAudioProfiles()) &&
+ mExtraAudioDescriptors == other->getExtraAudioDescriptors();
}
status_t AudioPort::writeToParcel(Parcel *parcel) const
@@ -160,6 +211,7 @@
parcelable->type = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_type_t_AudioPortType(mType));
parcelable->role = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_role_t_AudioPortRole(mRole));
parcelable->profiles = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioProfileVector(mProfiles));
+ parcelable->extraAudioDescriptors = mExtraAudioDescriptors;
parcelable->gains = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioGains(mGains));
return OK;
}
@@ -175,6 +227,7 @@
mType = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortType_audio_port_type_t(parcelable.type));
mRole = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortRole_audio_port_role_t(parcelable.role));
mProfiles = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioProfileVector(parcelable.profiles));
+ mExtraAudioDescriptors = parcelable.extraAudioDescriptors;
mGains = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioGains(parcelable.gains));
return OK;
}
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 65f7388..8ac3f73 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -58,10 +58,18 @@
AudioProfile::AudioProfile(audio_format_t format,
const ChannelMaskSet &channelMasks,
const SampleRateSet &samplingRateCollection) :
+ AudioProfile(format, channelMasks, samplingRateCollection,
+ AUDIO_ENCAPSULATION_TYPE_NONE) {}
+
+AudioProfile::AudioProfile(audio_format_t format,
+ const ChannelMaskSet &channelMasks,
+ const SampleRateSet &samplingRateCollection,
+ audio_encapsulation_type_t encapsulationType) :
mName(""),
mFormat(format),
mChannelMasks(channelMasks),
- mSamplingRates(samplingRateCollection) {}
+ mSamplingRates(samplingRateCollection),
+ mEncapsulationType(encapsulationType) {}
void AudioProfile::setChannels(const ChannelMaskSet &channelMasks)
{
@@ -116,6 +124,9 @@
}
dst->append("\n");
}
+
+ dst->append(base::StringPrintf(
+ "%*s- encapsulation type: %#x\n", spaces, "", mEncapsulationType));
}
bool AudioProfile::equals(const sp<AudioProfile>& other) const
@@ -127,7 +138,8 @@
mSamplingRates == other->getSampleRates() &&
mIsDynamicFormat == other->isDynamicFormat() &&
mIsDynamicChannels == other->isDynamicChannels() &&
- mIsDynamicRate == other->isDynamicRate();
+ mIsDynamicRate == other->isDynamicRate() &&
+ mEncapsulationType == other->getEncapsulationType();
}
AudioProfile& AudioProfile::operator=(const AudioProfile& other) {
@@ -135,6 +147,7 @@
mFormat = other.mFormat;
mChannelMasks = other.mChannelMasks;
mSamplingRates = other.mSamplingRates;
+ mEncapsulationType = other.mEncapsulationType;
mIsDynamicFormat = other.mIsDynamicFormat;
mIsDynamicChannels = other.mIsDynamicChannels;
mIsDynamicRate = other.mIsDynamicRate;
@@ -160,6 +173,8 @@
parcelable.isDynamicFormat = mIsDynamicFormat;
parcelable.isDynamicChannels = mIsDynamicChannels;
parcelable.isDynamicRate = mIsDynamicRate;
+ parcelable.encapsulationType = VALUE_OR_RETURN(
+ legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(mEncapsulationType));
return parcelable;
}
@@ -186,6 +201,9 @@
legacy->mIsDynamicFormat = parcelable.isDynamicFormat;
legacy->mIsDynamicChannels = parcelable.isDynamicChannels;
legacy->mIsDynamicRate = parcelable.isDynamicRate;
+ legacy->mEncapsulationType = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
+ parcelable.encapsulationType));
return legacy;
}
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index 633e4e3..1cee1c9 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -21,6 +21,7 @@
#include <android/media/AudioPort.h>
#include <android/media/AudioPortConfig.h>
+#include <android/media/ExtraAudioDescriptor.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <media/AudioGain.h>
@@ -67,6 +68,14 @@
void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
AudioProfileVector &getAudioProfiles() { return mProfiles; }
+ void setExtraAudioDescriptors(
+ const std::vector<media::ExtraAudioDescriptor> extraAudioDescriptors) {
+ mExtraAudioDescriptors = extraAudioDescriptors;
+ }
+ std::vector<media::ExtraAudioDescriptor> &getExtraAudioDescriptors() {
+ return mExtraAudioDescriptors;
+ }
+
virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
virtual void importAudioPort(const audio_port_v7& port);
@@ -102,6 +111,10 @@
audio_port_type_t mType;
audio_port_role_t mRole;
AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
+
+ // Audio capabilities that are defined by hardware descriptors when the format is unrecognized
+ // by the platform, e.g. short audio descriptor in EDID for HDMI.
+ std::vector<media::ExtraAudioDescriptor> mExtraAudioDescriptors;
private:
template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
|| std::is_same<T, struct audio_port_v7>::value, int> = 0>
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index 5051233..20c7ab9 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -38,6 +38,10 @@
AudioProfile(audio_format_t format,
const ChannelMaskSet &channelMasks,
const SampleRateSet &samplingRateCollection);
+ AudioProfile(audio_format_t format,
+ const ChannelMaskSet &channelMasks,
+ const SampleRateSet &samplingRateCollection,
+ audio_encapsulation_type_t encapsulationType);
audio_format_t getFormat() const { return mFormat; }
const ChannelMaskSet &getChannels() const { return mChannelMasks; }
@@ -68,6 +72,11 @@
bool isDynamic() { return mIsDynamicFormat || mIsDynamicChannels || mIsDynamicRate; }
+ audio_encapsulation_type_t getEncapsulationType() const { return mEncapsulationType; }
+ void setEncapsulationType(audio_encapsulation_type_t encapsulationType) {
+ mEncapsulationType = encapsulationType;
+ }
+
void dump(std::string *dst, int spaces) const;
bool equals(const sp<AudioProfile>& other) const;
@@ -79,6 +88,7 @@
static ConversionResult<sp<AudioProfile>> fromParcelable(const media::AudioProfile& parcelable);
private:
+
std::string mName;
audio_format_t mFormat; // The format for an audio profile should only be set when initialized.
ChannelMaskSet mChannelMasks;
@@ -88,6 +98,8 @@
bool mIsDynamicChannels = false;
bool mIsDynamicRate = false;
+ audio_encapsulation_type_t mEncapsulationType;
+
AudioProfile() = default;
AudioProfile& operator=(const AudioProfile& other);
};