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

Commit a8975a7e authored by Kevin Rocard's avatar Kevin Rocard
Browse files

Audio V4: propagate metadata to the HAL



This is needed for the earring aid use case.

Bug: 38184704
Bug: 69623109
Test: check that the correct metadata are propagate to the HALs.
Change-Id: I285aac9fbb5431cc32c6fbccebdbff4914e6ab92
Signed-off-by: default avatarKevin Rocard <krocard@google.com>
parent 83028d59
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -555,6 +555,11 @@ status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct time
    }
}

status_t StreamOutHalHidl::updateSourceMetadata(const SourceMetadata& /* sourceMetadata */) {
    // Audio HAL V2.0 does not support propagating source metadata
    return INVALID_OPERATION;
}

void StreamOutHalHidl::onWriteReady() {
    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
    if (callback == 0) return;
@@ -755,4 +760,9 @@ status_t StreamInHalHidl::getActiveMicrophones(
    return INVALID_OPERATION;
}

status_t StreamInHalHidl::updateSinkMetadata(const SinkMetadata& /* sinkMetadata */) {
    // Audio HAL V2.0 does not support propagating sink metadata
    return INVALID_OPERATION;
}

} // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -161,6 +161,9 @@ class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
    // Return a recent count of the number of audio frames presented to an external observer.
    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);

    // Called when the metadata of the stream's source has been changed.
    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;

    // Methods used by StreamOutCallback (HIDL).
    void onWriteReady();
    void onDrainReady();
@@ -213,6 +216,9 @@ class StreamInHalHidl : public StreamInHalInterface, public StreamHalHidl {
    // Get active microphones
    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);

    // Called when the metadata of the stream's sink has been changed.
    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;

  private:
    friend class DeviceHalHidl;
    typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
+26 −0
Original line number Diff line number Diff line
@@ -231,6 +231,19 @@ status_t StreamOutHalLocal::getPresentationPosition(uint64_t *frames, struct tim
    return mStream->get_presentation_position(mStream, frames, timestamp);
}

status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
    if (mStream->update_source_metadata == nullptr) {
        return INVALID_OPERATION;
    }
    const source_metadata_t metadata {
        .track_count = sourceMetadata.tracks.size(),
        // const cast is fine as it is in a const structure
        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
    };
    mStream->update_source_metadata(mStream, &metadata);
    return OK;
}

status_t StreamOutHalLocal::start() {
    if (mStream->start == NULL) return INVALID_OPERATION;
    return mStream->start(mStream);
@@ -292,6 +305,19 @@ status_t StreamInHalLocal::getCapturePosition(int64_t *frames, int64_t *time) {
    return mStream->get_capture_position(mStream, frames, time);
}

status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
    if (mStream->update_sink_metadata == nullptr) {
        return INVALID_OPERATION;
    }
    const sink_metadata_t metadata {
        .track_count = sinkMetadata.tracks.size(),
        // const cast is fine as it is in a const structure
        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
    };
    mStream->update_sink_metadata(mStream, &metadata);
    return OK;
}

status_t StreamInHalLocal::start() {
    if (mStream->start == NULL) return INVALID_OPERATION;
    return mStream->start(mStream);
+6 −0
Original line number Diff line number Diff line
@@ -149,6 +149,9 @@ class StreamOutHalLocal : public StreamOutHalInterface, public StreamHalLocal {
    // Get current read/write position in the mmap buffer
    virtual status_t getMmapPosition(struct audio_mmap_position *position);

    // Called when the metadata of the stream's source has been changed.
    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;

  private:
    audio_stream_out_t *mStream;
    wp<StreamOutHalInterfaceCallback> mCallback;
@@ -197,6 +200,9 @@ class StreamInHalLocal : public StreamInHalInterface, public StreamHalLocal {
    // Get active microphones
    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);

    // Called when the metadata of the stream's sink has been changed.
    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;

  private:
    audio_stream_in_t *mStream;

+39 −0
Original line number Diff line number Diff line
@@ -28,7 +28,10 @@
#include "VersionUtils.h"

using ::android::hardware::audio::common::V4_0::AudioChannelMask;
using ::android::hardware::audio::common::V4_0::AudioContentType;
using ::android::hardware::audio::common::V4_0::AudioFormat;
using ::android::hardware::audio::common::V4_0::AudioSource;
using ::android::hardware::audio::common::V4_0::AudioUsage;
using ::android::hardware::audio::common::V4_0::ThreadInfo;
using ::android::hardware::audio::V4_0::AudioDrain;
using ::android::hardware::audio::V4_0::IStreamOutCallback;
@@ -37,6 +40,8 @@ using ::android::hardware::audio::V4_0::MicrophoneInfo;
using ::android::hardware::audio::V4_0::MmapBufferInfo;
using ::android::hardware::audio::V4_0::MmapPosition;
using ::android::hardware::audio::V4_0::ParameterValue;
using ::android::hardware::audio::V4_0::PlaybackTrackMetadata;
using ::android::hardware::audio::V4_0::RecordTrackMetadata;
using ::android::hardware::audio::V4_0::Result;
using ::android::hardware::audio::V4_0::TimeSpec;
using ::android::hardware::MQDescriptorSync;
@@ -561,6 +566,28 @@ status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct time
    }
}

/** Transform a standard collection to an HIDL vector. */
template <class Values, class ElementConverter>
static auto transformToHidlVec(const Values& values, ElementConverter converter) {
    hidl_vec<decltype(converter(*values.begin()))> result{values.size()};
    using namespace std;
    transform(begin(values), end(values), begin(result), converter);
    return result;
}

status_t StreamOutHalHidl::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
    hardware::audio::V4_0::SourceMetadata halMetadata = {
        .tracks = transformToHidlVec(sourceMetadata.tracks,
              [](const playback_track_metadata& metadata) -> PlaybackTrackMetadata {
                  return {
                    .usage=static_cast<AudioUsage>(metadata.usage),
                    .contentType=static_cast<AudioContentType>(metadata.content_type),
                    .gain=metadata.gain,
                  };
              })};
    return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
}

void StreamOutHalHidl::onWriteReady() {
    sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
    if (callback == 0) return;
@@ -774,5 +801,17 @@ status_t StreamInHalHidl::getActiveMicrophones(
    return processReturn("getActiveMicrophones", ret, retval);
}

status_t StreamInHalHidl::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
    hardware::audio::V4_0::SinkMetadata halMetadata = {
        .tracks = transformToHidlVec(sinkMetadata.tracks,
              [](const record_track_metadata& metadata) -> RecordTrackMetadata {
                  return {
                    .source=static_cast<AudioSource>(metadata.source),
                    .gain=metadata.gain,
                  };
              })};
    return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
}

} // namespace V4_0
} // namespace android
Loading