Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit deebf381 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio HAL V7: Update track metadata

Add channel mask and audio attributes tags to playback
and record track metadata sent to audio HAL.

The legacy HAL wrapper supports older legacy HAL versions
by sending partial metadata when the legay HAL version is
less than 3.2.

Bug: 168751366
Test: make
Change-Id: Iba3ee3b669e4300201374d4a0d5cf45a04872274
parent f468b740
Loading
Loading
Loading
Loading
+14 −0
Original line number Original line Diff line number Diff line
@@ -274,10 +274,21 @@ struct AudioConfig {
    uint64_t frameCount;
    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. */
/** Metadata of a playback track for a StreamOut. */
struct PlaybackTrackMetadata {
struct PlaybackTrackMetadata {
    AudioUsage usage;
    AudioUsage usage;
    AudioContentType contentType;
    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,
     * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation,
     * 2 means double amplification...
     * 2 means double amplification...
@@ -294,6 +305,9 @@ struct SourceMetadata {
/** Metadata of a record track for a StreamIn. */
/** Metadata of a record track for a StreamIn. */
struct RecordTrackMetadata {
struct RecordTrackMetadata {
    AudioSource source;
    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,
     * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation,
     * 2 means double amplification...
     * 2 means double amplification...
+3 −0
Original line number Original line Diff line number Diff line
@@ -77,6 +77,8 @@ struct HidlUtils {
#endif
#endif


#if MAJOR_VERSION >= 7
#if MAJOR_VERSION >= 7
    static constexpr char sAudioTagSeparator = ';';

    static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
    static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
                                            AudioChannelMask* channelMask);
                                            AudioChannelMask* channelMask);
    static status_t audioChannelMasksFromHal(const std::vector<std::string>& halChannelMasks,
    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_device_ext* device,
                                               struct audio_port_config_mix_ext* mix,
                                               struct audio_port_config_mix_ext* mix,
                                               struct audio_port_config_session_ext* session);
                                               struct audio_port_config_session_ext* session);

#endif  // MAJOR_VERSION >= 7
#endif  // MAJOR_VERSION >= 7


    // V4 and below have DeviceAddress defined in the 'core' interface.
    // V4 and below have DeviceAddress defined in the 'core' interface.
+69 −13
Original line number Original line Diff line number Diff line
@@ -478,29 +478,85 @@ Return<void> StreamIn::debug(const hidl_handle& fd, const hidl_vec<hidl_string>&
}
}


#if MAJOR_VERSION >= 4
#if MAJOR_VERSION >= 4
Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) {

    if (mStream->update_sink_metadata == nullptr) {
record_track_metadata StreamIn::convertRecordTrackMetadata(
        return Void();  // not supported by the HAL
        const RecordTrackMetadata& trackMetadata) {
    }
    record_track_metadata halTrackMetadata = {.gain = trackMetadata.gain};
    std::vector<record_track_metadata> halTracks;
    (void)HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source);
    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 MAJOR_VERSION >= 5
        if (metadata.destination.getDiscriminator() ==
    if (trackMetadata.destination.getDiscriminator() ==
        RecordTrackMetadata::Destination::hidl_discriminator::device) {
        RecordTrackMetadata::Destination::hidl_discriminator::device) {
            (void)deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device,
        (void)deviceAddressToHal(trackMetadata.destination.device(), &halTrackMetadata.dest_device,
                                 halTrackMetadata.dest_device_address);
                                 halTrackMetadata.dest_device_address);
    }
    }
#endif
#endif
        halTracks.push_back(halTrackMetadata);
    return halTrackMetadata;
}

void StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) {
    std::vector<record_track_metadata> halTracks;
    halTracks.reserve(sinkMetadata.tracks.size());
    for (auto& metadata : sinkMetadata.tracks) {
        halTracks.push_back(convertRecordTrackMetadata(metadata));
    }
    }
    const sink_metadata_t halMetadata = {
    const sink_metadata_t halMetadata = {
        .track_count = halTracks.size(),
        .track_count = halTracks.size(),
        .tracks = halTracks.data(),
        .tracks = halTracks.data(),
    };
    };
    mStream->update_sink_metadata(mStream, &halMetadata);
    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();
    return Void();
}
}


+65 −9
Original line number Original line Diff line number Diff line
@@ -585,26 +585,82 @@ Return<void> StreamOut::debug(const hidl_handle& fd, const hidl_vec<hidl_string>
}
}


#if MAJOR_VERSION >= 4
#if MAJOR_VERSION >= 4
Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
playback_track_metadata StreamOut::convertPlaybackTrackMetadata(
    if (mStream->update_source_metadata == nullptr) {
        const PlaybackTrackMetadata& trackMetadata) {
        return Void();  // not supported by the HAL
    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;
    std::vector<playback_track_metadata_t> halTracks;
    halTracks.reserve(sourceMetadata.tracks.size());
    halTracks.reserve(sourceMetadata.tracks.size());
    for (auto& metadata : sourceMetadata.tracks) {
    for (auto& metadata : sourceMetadata.tracks) {
        playback_track_metadata_t halTrackMetadata = {.gain = metadata.gain};
        halTracks.push_back(convertPlaybackTrackMetadata(metadata));
        (void)HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage);
        (void)HidlUtils::audioContentTypeToHal(metadata.contentType,
                                               &halTrackMetadata.content_type);
        halTracks.push_back(std::move(halTrackMetadata));
    }
    }
    const source_metadata_t halMetadata = {
    const source_metadata_t halMetadata = {
        .track_count = halTracks.size(),
        .track_count = halTracks.size(),
        .tracks = halTracks.data(),
        .tracks = halTracks.data(),
    };
    };
    mStream->update_source_metadata(mStream, &halMetadata);
    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 Void();
}
}

Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) {
Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) {
    return Result::NOT_SUPPORTED;  // TODO: propagate to legacy
    return Result::NOT_SUPPORTED;  // TODO: propagate to legacy
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -146,6 +146,8 @@ struct Device : public IDevice, public ParametersUtil {
    void closeOutputStream(audio_stream_out_t* stream);
    void closeOutputStream(audio_stream_out_t* stream);
    audio_hw_device_t* device() const { return mDevice; }
    audio_hw_device_t* device() const { return mDevice; }


    uint32_t version() const { return mDevice->common.version; }

  private:
  private:
    bool mIsClosed;
    bool mIsClosed;
    audio_hw_device_t* mDevice;
    audio_hw_device_t* mDevice;
@@ -161,8 +163,6 @@ struct Device : public IDevice, public ParametersUtil {
    // Methods from ParametersUtil.
    // Methods from ParametersUtil.
    char* halGetParameters(const char* keys) override;
    char* halGetParameters(const char* keys) override;
    int halSetParameters(const char* keysAndValues) override;
    int halSetParameters(const char* keysAndValues) override;

    uint32_t version() const { return mDevice->common.version; }
};
};


}  // namespace implementation
}  // namespace implementation
Loading