Merge "audio HAL V7: Update track metadata"
This commit is contained in:
commit
88a2210fc4
10 changed files with 220 additions and 37 deletions
|
@ -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...
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue