Merge "audio HAL V7: Update track metadata"

This commit is contained in:
Treehugger Robot 2021-01-07 21:52:06 +00:00 committed by Gerrit Code Review
commit 88a2210fc4
10 changed files with 220 additions and 37 deletions

View file

@ -274,10 +274,21 @@ struct AudioConfig {
uint64_t frameCount;
};
/**
* AudioTag is an additional use case qualifier complementing
* AudioUsage and AudioContentType. Tags are set by vendor specific applications
* and must be prefixed by "VX_". Vendor must namespace their tag
* names to avoid conflicts.
*/
typedef string AudioTag;
/** Metadata of a playback track for a StreamOut. */
struct PlaybackTrackMetadata {
AudioUsage usage;
AudioContentType contentType;
/** Tags from AudioTrack audio atttributes */
vec<AudioTag> tags;
AudioChannelMask channelMask;
/**
* Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation,
* 2 means double amplification...
@ -294,6 +305,9 @@ struct SourceMetadata {
/** Metadata of a record track for a StreamIn. */
struct RecordTrackMetadata {
AudioSource source;
/** Tags from AudioTrack audio atttributes */
vec<AudioTag> tags;
AudioChannelMask channelMask;
/**
* Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation,
* 2 means double amplification...

View file

@ -77,6 +77,8 @@ struct HidlUtils {
#endif
#if MAJOR_VERSION >= 7
static constexpr char sAudioTagSeparator = ';';
static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
AudioChannelMask* channelMask);
static status_t audioChannelMasksFromHal(const std::vector<std::string>& halChannelMasks,
@ -126,6 +128,7 @@ struct HidlUtils {
struct audio_port_config_device_ext* device,
struct audio_port_config_mix_ext* mix,
struct audio_port_config_session_ext* session);
#endif // MAJOR_VERSION >= 7
// V4 and below have DeviceAddress defined in the 'core' interface.

View file

@ -478,29 +478,85 @@ Return<void> StreamIn::debug(const hidl_handle& fd, const hidl_vec<hidl_string>&
}
#if MAJOR_VERSION >= 4
Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
if (mStream->update_sink_metadata == nullptr) {
return Void(); // not supported by the HAL
record_track_metadata StreamIn::convertRecordTrackMetadata(
const RecordTrackMetadata& trackMetadata) {
record_track_metadata halTrackMetadata = {.gain = trackMetadata.gain};
(void)HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source);
#if MAJOR_VERSION >= 5
if (trackMetadata.destination.getDiscriminator() ==
RecordTrackMetadata::Destination::hidl_discriminator::device) {
(void)deviceAddressToHal(trackMetadata.destination.device(), &halTrackMetadata.dest_device,
halTrackMetadata.dest_device_address);
}
#endif
return halTrackMetadata;
}
void StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) {
std::vector<record_track_metadata> halTracks;
halTracks.reserve(sinkMetadata.tracks.size());
for (auto& metadata : sinkMetadata.tracks) {
record_track_metadata halTrackMetadata = {.gain = metadata.gain};
(void)HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source);
#if MAJOR_VERSION >= 5
if (metadata.destination.getDiscriminator() ==
RecordTrackMetadata::Destination::hidl_discriminator::device) {
(void)deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device,
halTrackMetadata.dest_device_address);
}
#endif
halTracks.push_back(halTrackMetadata);
halTracks.push_back(convertRecordTrackMetadata(metadata));
}
const sink_metadata_t halMetadata = {
.track_count = halTracks.size(),
.tracks = halTracks.data(),
};
mStream->update_sink_metadata(mStream, &halMetadata);
}
#if MAJOR_VERSION >= 7
record_track_metadata_v7 StreamIn::convertRecordTrackMetadataV7(
const RecordTrackMetadata& trackMetadata) {
record_track_metadata_v7 halTrackMetadata;
halTrackMetadata.base = convertRecordTrackMetadata(trackMetadata);
(void)HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask,
&halTrackMetadata.channel_mask);
std::string halTags;
for (const auto& tag : trackMetadata.tags) {
if (&tag != &trackMetadata.tags[0]) {
halTags += HidlUtils::sAudioTagSeparator;
}
halTags += tag.c_str();
}
strncpy(halTrackMetadata.tags, halTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
return halTrackMetadata;
}
void StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) {
std::vector<record_track_metadata_v7> halTracks;
halTracks.reserve(sinkMetadata.tracks.size());
for (auto& metadata : sinkMetadata.tracks) {
halTracks.push_back(convertRecordTrackMetadataV7(metadata));
}
const sink_metadata_v7_t halMetadata = {
.track_count = halTracks.size(),
.tracks = halTracks.data(),
};
mStream->update_sink_metadata_v7(mStream, &halMetadata);
}
#endif // MAJOR_VERSION >= 7
Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
#if MAJOR_VERSION < 7
if (mStream->update_sink_metadata == nullptr) {
return Void(); // not supported by the HAL
}
doUpdateSinkMetadata(sinkMetadata);
#else
if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) {
if (mStream->update_sink_metadata == nullptr) {
return Void(); // not supported by the HAL
}
doUpdateSinkMetadata(sinkMetadata);
} else {
if (mStream->update_sink_metadata_v7 == nullptr) {
return Void(); // not supported by the HAL
}
doUpdateSinkMetadataV7(sinkMetadata);
}
#endif // MAJOR_VERSION < 7
return Void();
}

View file

@ -585,26 +585,82 @@ Return<void> StreamOut::debug(const hidl_handle& fd, const hidl_vec<hidl_string>
}
#if MAJOR_VERSION >= 4
Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
if (mStream->update_source_metadata == nullptr) {
return Void(); // not supported by the HAL
}
playback_track_metadata StreamOut::convertPlaybackTrackMetadata(
const PlaybackTrackMetadata& trackMetadata) {
playback_track_metadata_t halTrackMetadata = {.gain = trackMetadata.gain};
(void)HidlUtils::audioUsageToHal(trackMetadata.usage, &halTrackMetadata.usage);
(void)HidlUtils::audioContentTypeToHal(trackMetadata.contentType,
&halTrackMetadata.content_type);
return halTrackMetadata;
}
void StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) {
std::vector<playback_track_metadata_t> halTracks;
halTracks.reserve(sourceMetadata.tracks.size());
for (auto& metadata : sourceMetadata.tracks) {
playback_track_metadata_t halTrackMetadata = {.gain = metadata.gain};
(void)HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage);
(void)HidlUtils::audioContentTypeToHal(metadata.contentType,
&halTrackMetadata.content_type);
halTracks.push_back(std::move(halTrackMetadata));
halTracks.push_back(convertPlaybackTrackMetadata(metadata));
}
const source_metadata_t halMetadata = {
.track_count = halTracks.size(),
.tracks = halTracks.data(),
};
mStream->update_source_metadata(mStream, &halMetadata);
}
#if MAJOR_VERSION >= 7
playback_track_metadata_v7 StreamOut::convertPlaybackTrackMetadataV7(
const PlaybackTrackMetadata& trackMetadata) {
playback_track_metadata_v7 halTrackMetadata;
halTrackMetadata.base = convertPlaybackTrackMetadata(trackMetadata);
(void)HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask,
&halTrackMetadata.channel_mask);
std::string halTags;
for (const auto& tag : trackMetadata.tags) {
if (&tag != &trackMetadata.tags[0]) {
halTags += HidlUtils::sAudioTagSeparator;
}
halTags += tag.c_str();
}
strncpy(halTrackMetadata.tags, halTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
return halTrackMetadata;
}
void StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) {
std::vector<playback_track_metadata_v7> halTracks;
halTracks.reserve(sourceMetadata.tracks.size());
for (auto& metadata : sourceMetadata.tracks) {
halTracks.push_back(convertPlaybackTrackMetadataV7(metadata));
}
const source_metadata_v7_t halMetadata = {
.track_count = halTracks.size(),
.tracks = halTracks.data(),
};
mStream->update_source_metadata_v7(mStream, &halMetadata);
}
#endif // MAJOR_VERSION >= 7
Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
#if MAJOR_VERSION < 7
if (mStream->update_source_metadata == nullptr) {
return Void(); // not supported by the HAL
}
doUpdateSourceMetadata(sourceMetadata);
#else
if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) {
if (mStream->update_source_metadata == nullptr) {
return Void(); // not supported by the HAL
}
doUpdateSourceMetadata(sourceMetadata);
} else {
if (mStream->update_source_metadata_v7 == nullptr) {
return Void(); // not supported by the HAL
}
doUpdateSourceMetadataV7(sourceMetadata);
}
#endif // MAJOR_VERSION < 7
return Void();
}
Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) {
return Result::NOT_SUPPORTED; // TODO: propagate to legacy
}

View file

@ -146,6 +146,8 @@ struct Device : public IDevice, public ParametersUtil {
void closeOutputStream(audio_stream_out_t* stream);
audio_hw_device_t* device() const { return mDevice; }
uint32_t version() const { return mDevice->common.version; }
private:
bool mIsClosed;
audio_hw_device_t* mDevice;
@ -161,8 +163,6 @@ struct Device : public IDevice, public ParametersUtil {
// Methods from ParametersUtil.
char* halGetParameters(const char* keys) override;
int halSetParameters(const char* keysAndValues) override;
uint32_t version() const { return mDevice->common.version; }
};
} // namespace implementation

View file

@ -124,7 +124,16 @@ struct StreamIn : public IStreamIn {
static Result getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames,
uint64_t* time);
private:
private:
#if MAJOR_VERSION >= 4
record_track_metadata convertRecordTrackMetadata(const RecordTrackMetadata& trackMetadata);
void doUpdateSinkMetadata(const SinkMetadata& sinkMetadata);
#if MAJOR_VERSION >= 7
record_track_metadata_v7 convertRecordTrackMetadataV7(const RecordTrackMetadata& trackMetadata);
void doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata);
#endif
#endif
const sp<Device> mDevice;
audio_stream_in_t* mStream;
const sp<Stream> mStreamCommon;

View file

@ -143,6 +143,17 @@ struct StreamOut : public IStreamOut {
#endif
private:
#if MAJOR_VERSION >= 4
playback_track_metadata convertPlaybackTrackMetadata(
const PlaybackTrackMetadata& trackMetadata);
void doUpdateSourceMetadata(const SourceMetadata& sourceMetadata);
#if MAJOR_VERSION >= 7
playback_track_metadata_v7 convertPlaybackTrackMetadataV7(
const PlaybackTrackMetadata& trackMetadata);
void doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata);
#endif
#endif
const sp<Device> mDevice;
audio_stream_out_t* mStream;
const sp<Stream> mStreamCommon;

View file

@ -72,7 +72,10 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) {
config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
hidl_vec<hidl_string> flags;
const SinkMetadata initMetadata = {
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}};
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC),
.gain = 1,
.tags = {},
.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
#endif
EventFlag* efGroup;
for (auto microphone : microphones) {
@ -246,7 +249,11 @@ TEST_P(InputStreamTest, updateSinkMetadata) {
#if MAJOR_VERSION <= 6
const SinkMetadata metadata = {{{.source = source, .gain = volume}}};
#elif MAJOR_VERSION >= 7
const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}};
const SinkMetadata metadata = {
{{.source = toString(source),
.gain = volume,
.tags = {},
.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
#endif
ASSERT_OK(stream->updateSinkMetadata(metadata))
<< "source=" << toString(source) << ", volume=" << volume;
@ -284,7 +291,12 @@ TEST_P(OutputStreamTest, updateSourceMetadata) {
#if MAJOR_VERSION <= 6
const SourceMetadata metadata = {{{usage, content, volume}}};
#elif MAJOR_VERSION >= 7
const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}};
const SourceMetadata metadata = {
{{toString(usage),
toString(content),
{} /* tags */,
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
volume}}};
#endif
ASSERT_OK(stream->updateSourceMetadata(metadata))
<< "usage=" << toString(usage) << ", content=" << toString(content)
@ -303,13 +315,25 @@ TEST_P(OutputStreamTest, updateSourceMetadata) {
{AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}}
#elif MAJOR_VERSION >= 7
{{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1},
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
{},
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
0.1},
{toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0},
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH),
{}, // tags
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO),
1.0},
{toString(xsd::AudioUsage::AUDIO_USAGE_ALARM),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0},
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION),
{}, // tags
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
0.0},
{toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}}
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN),
{},
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO),
0.3}}}
#endif
));
// clang-format on

View file

@ -98,9 +98,11 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
#elif MAJOR_VERSION >= 7
DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)};
SourceMetadata initMetadata = {
{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}};
SourceMetadata initMetadata = {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
{} /* tags */,
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
1 /* gain */}}};
hidl_vec<AudioInOutFlag> flags;
#endif
AudioConfig config{};
@ -131,7 +133,10 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
#elif MAJOR_VERSION >= 7
DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)};
SinkMetadata initMetadata = {
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}};
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC),
.gain = 1,
.tags = {},
.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
hidl_vec<AudioInOutFlag> flags;
#endif
AudioConfig config{};

View file

@ -926,6 +926,8 @@ class OutputStreamTest : public OpenStreamTest<IStreamOut> {
const SourceMetadata initMetadata = {
{ { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
{},
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
1 /* gain */ } }};
#endif
};
@ -991,7 +993,10 @@ class InputStreamTest : public OpenStreamTest<IStreamIn> {
const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }};
#elif MAJOR_VERSION >= 7
const SinkMetadata initMetadata = {
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}};
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT),
.gain = 1,
.tags = {},
.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
#endif
};