mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
audio treble HAL: implement methods and structures for stream in MMAP mode
Bug: 33398120 Test: make marlin-eng with ENABLE_TREBLE true Change-Id: I64f56526c7c775b03191439188545171b565ef31
This commit is contained in:
@@ -33,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libhidlbase \
|
||||
libhidltransport \
|
||||
libhwbinder \
|
||||
libcutils \
|
||||
libutils \
|
||||
libhardware \
|
||||
liblog \
|
||||
|
||||
@@ -43,9 +43,10 @@ Stream::~Stream() {
|
||||
mStream = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
Result Stream::analyzeStatus(const char* funcName, int status, int ignoreError) {
|
||||
if (status != 0 && status != -ignoreError) {
|
||||
ALOGW("Stream %p %s: %s", mStream, funcName, strerror(-status));
|
||||
ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status));
|
||||
}
|
||||
switch (status) {
|
||||
case 0: return Result::OK;
|
||||
@@ -229,6 +230,29 @@ Return<void> Stream::debugDump(const hidl_handle& fd) {
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Stream::start() {
|
||||
return Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<Result> Stream::stop() {
|
||||
return Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<void> Stream::createMmapBuffer(int32_t minSizeFrames __unused,
|
||||
createMmapBuffer_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
MmapBufferInfo info;
|
||||
_hidl_cb(retval, info);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
MmapPosition position;
|
||||
_hidl_cb(retval, position);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H
|
||||
|
||||
#include <android/hardware/audio/2.0/IStream.h>
|
||||
#include <hardware/audio.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
@@ -71,9 +72,13 @@ struct Stream : public IStream, public ParametersUtil {
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
|
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
|
||||
Return<void> debugDump(const hidl_handle& fd) override;
|
||||
Return<Result> start() override;
|
||||
Return<Result> stop() override;
|
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
|
||||
Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
|
||||
|
||||
// Utility methods for extending interfaces.
|
||||
Result analyzeStatus(const char* funcName, int status, int ignoreError = OK);
|
||||
static Result analyzeStatus(const char* funcName, int status, int ignoreError = OK);
|
||||
|
||||
private:
|
||||
audio_stream_t *mStream;
|
||||
@@ -85,6 +90,80 @@ struct Stream : public IStream, public ParametersUtil {
|
||||
int halSetParameters(const char* keysAndValues) override;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct StreamMmap : public RefBase {
|
||||
explicit StreamMmap(T* stream) : mStream(stream) {}
|
||||
|
||||
Return<Result> start();
|
||||
Return<Result> stop();
|
||||
Return<void> createMmapBuffer(
|
||||
int32_t minSizeFrames, size_t frameSize, IStream::createMmapBuffer_cb _hidl_cb);
|
||||
Return<void> getMmapPosition(IStream::getMmapPosition_cb _hidl_cb);
|
||||
|
||||
private:
|
||||
StreamMmap() {}
|
||||
|
||||
T *mStream;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Return<Result> StreamMmap<T>::start() {
|
||||
if (mStream->start == NULL) return Result::NOT_SUPPORTED;
|
||||
int result = mStream->start(mStream);
|
||||
return Stream::analyzeStatus("start", result);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Return<Result> StreamMmap<T>::stop() {
|
||||
if (mStream->stop == NULL) return Result::NOT_SUPPORTED;
|
||||
int result = mStream->stop(mStream);
|
||||
return Stream::analyzeStatus("stop", result);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Return<void> StreamMmap<T>::createMmapBuffer(int32_t minSizeFrames, size_t frameSize,
|
||||
IStream::createMmapBuffer_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
MmapBufferInfo info;
|
||||
|
||||
if (mStream->create_mmap_buffer != NULL) {
|
||||
struct audio_mmap_buffer_info halInfo;
|
||||
retval = Stream::analyzeStatus(
|
||||
"create_mmap_buffer",
|
||||
mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo));
|
||||
if (retval == Result::OK) {
|
||||
native_handle_t* hidlHandle = native_handle_create(1, 0);
|
||||
hidlHandle->data[0] = halInfo.shared_memory_fd;
|
||||
info.sharedMemory = hidl_memory("audio_buffer", hidlHandle,
|
||||
frameSize *halInfo.buffer_size_frames);
|
||||
info.bufferSizeFrames = halInfo.buffer_size_frames;
|
||||
info.burstSizeFrames = halInfo.burst_size_frames;
|
||||
}
|
||||
}
|
||||
_hidl_cb(retval, info);
|
||||
return Void();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Return<void> StreamMmap<T>::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
MmapPosition position;
|
||||
|
||||
if (mStream->get_mmap_position != NULL) {
|
||||
struct audio_mmap_position halPosition;
|
||||
retval = Stream::analyzeStatus(
|
||||
"get_mmap_position",
|
||||
mStream->get_mmap_position(mStream, &halPosition));
|
||||
if (retval == Result::OK) {
|
||||
position.timeNanoseconds = halPosition.time_nanoseconds;
|
||||
position.positionFrames = halPosition.position_frames;
|
||||
}
|
||||
}
|
||||
_hidl_cb(retval, position);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
|
||||
@@ -28,7 +28,9 @@ namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
StreamIn::StreamIn(audio_hw_device_t* device, audio_stream_in_t* stream)
|
||||
: mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
|
||||
: mDevice(device), mStream(stream),
|
||||
mStreamCommon(new Stream(&stream->common)),
|
||||
mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)) {
|
||||
}
|
||||
|
||||
StreamIn::~StreamIn() {
|
||||
@@ -130,6 +132,22 @@ Return<void> StreamIn::debugDump(const hidl_handle& fd) {
|
||||
return mStreamCommon->debugDump(fd);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::start() {
|
||||
return mStreamMmap->start();
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::stop() {
|
||||
return mStreamMmap->stop();
|
||||
}
|
||||
|
||||
Return<void> StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
|
||||
return mStreamMmap->createMmapBuffer(
|
||||
minSizeFrames, audio_stream_in_frame_size(mStream), _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) {
|
||||
return mStreamMmap->getMmapPosition(_hidl_cb);
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
|
||||
Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) {
|
||||
@@ -144,7 +162,7 @@ Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) {
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setGain(float gain) {
|
||||
return mStreamCommon->analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
|
||||
return Stream::analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
|
||||
}
|
||||
|
||||
Return<void> StreamIn::read(uint64_t size, read_cb _hidl_cb) {
|
||||
@@ -157,7 +175,7 @@ Return<void> StreamIn::read(uint64_t size, read_cb _hidl_cb) {
|
||||
data.resize(readResult);
|
||||
} else if (readResult < 0) {
|
||||
data.resize(0);
|
||||
retval = mStreamCommon->analyzeStatus("read", readResult);
|
||||
retval = Stream::analyzeStatus("read", readResult);
|
||||
}
|
||||
_hidl_cb(retval, data);
|
||||
return Void();
|
||||
@@ -172,7 +190,7 @@ Return<void> StreamIn::getCapturePosition(getCapturePosition_cb _hidl_cb) {
|
||||
uint64_t frames = 0, time = 0;
|
||||
if (mStream->get_capture_position != NULL) {
|
||||
int64_t halFrames, halTime;
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
retval = Stream::analyzeStatus(
|
||||
"get_capture_position",
|
||||
mStream->get_capture_position(mStream, &halFrames, &halTime));
|
||||
if (retval == Result::OK) {
|
||||
|
||||
@@ -80,11 +80,17 @@ struct StreamIn : public IStreamIn {
|
||||
Return<void> read(uint64_t size, read_cb _hidl_cb) override;
|
||||
Return<uint32_t> getInputFramesLost() override;
|
||||
Return<void> getCapturePosition(getCapturePosition_cb _hidl_cb) override;
|
||||
Return<Result> start() override;
|
||||
Return<Result> stop() override;
|
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
|
||||
Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
audio_hw_device_t *mDevice;
|
||||
audio_stream_in_t *mStream;
|
||||
sp<Stream> mStreamCommon;
|
||||
sp<StreamMmap<audio_stream_in_t>> mStreamMmap;
|
||||
|
||||
|
||||
virtual ~StreamIn();
|
||||
};
|
||||
|
||||
@@ -28,7 +28,9 @@ namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
StreamOut::StreamOut(audio_hw_device_t* device, audio_stream_out_t* stream)
|
||||
: mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
|
||||
: mDevice(device), mStream(stream),
|
||||
mStreamCommon(new Stream(&stream->common)),
|
||||
mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)) {
|
||||
}
|
||||
|
||||
StreamOut::~StreamOut() {
|
||||
@@ -132,7 +134,6 @@ Return<void> StreamOut::debugDump(const hidl_handle& fd) {
|
||||
return mStreamCommon->debugDump(fd);
|
||||
}
|
||||
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
|
||||
Return<uint32_t> StreamOut::getLatency() {
|
||||
return mStream->get_latency(mStream);
|
||||
@@ -141,7 +142,7 @@ Return<uint32_t> StreamOut::getLatency() {
|
||||
Return<Result> StreamOut::setVolume(float left, float right) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
if (mStream->set_volume != NULL) {
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
retval = Stream::analyzeStatus(
|
||||
"set_volume", mStream->set_volume(mStream, left, right));
|
||||
}
|
||||
return retval;
|
||||
@@ -155,7 +156,7 @@ Return<void> StreamOut::write(const hidl_vec<uint8_t>& data, write_cb _hidl_cb)
|
||||
if (writeResult >= 0) {
|
||||
written = writeResult;
|
||||
} else {
|
||||
retval = mStreamCommon->analyzeStatus("write", writeResult);
|
||||
retval = Stream::analyzeStatus("write", writeResult);
|
||||
written = 0;
|
||||
}
|
||||
_hidl_cb(retval, written);
|
||||
@@ -164,7 +165,7 @@ Return<void> StreamOut::write(const hidl_vec<uint8_t>& data, write_cb _hidl_cb)
|
||||
|
||||
Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) {
|
||||
uint32_t halDspFrames;
|
||||
Result retval = mStreamCommon->analyzeStatus(
|
||||
Result retval = Stream::analyzeStatus(
|
||||
"get_render_position", mStream->get_render_position(mStream, &halDspFrames));
|
||||
_hidl_cb(retval, halDspFrames);
|
||||
return Void();
|
||||
@@ -174,7 +175,7 @@ Return<void> StreamOut::getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb)
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
int64_t timestampUs = 0;
|
||||
if (mStream->get_next_write_timestamp != NULL) {
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
retval = Stream::analyzeStatus(
|
||||
"get_next_write_timestamp",
|
||||
mStream->get_next_write_timestamp(mStream, ×tampUs));
|
||||
}
|
||||
@@ -188,7 +189,7 @@ Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback) {
|
||||
if (result == 0) {
|
||||
mCallback = callback;
|
||||
}
|
||||
return mStreamCommon->analyzeStatus("set_callback", result);
|
||||
return Stream::analyzeStatus("set_callback", result);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::clearCallback() {
|
||||
@@ -227,13 +228,13 @@ Return<void> StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_c
|
||||
|
||||
Return<Result> StreamOut::pause() {
|
||||
return mStream->pause != NULL ?
|
||||
mStreamCommon->analyzeStatus("pause", mStream->pause(mStream)) :
|
||||
Stream::analyzeStatus("pause", mStream->pause(mStream)) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::resume() {
|
||||
return mStream->resume != NULL ?
|
||||
mStreamCommon->analyzeStatus("resume", mStream->resume(mStream)) :
|
||||
Stream::analyzeStatus("resume", mStream->resume(mStream)) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -243,14 +244,14 @@ Return<bool> StreamOut::supportsDrain() {
|
||||
|
||||
Return<Result> StreamOut::drain(AudioDrain type) {
|
||||
return mStream->drain != NULL ?
|
||||
mStreamCommon->analyzeStatus(
|
||||
Stream::analyzeStatus(
|
||||
"drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type))) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::flush() {
|
||||
return mStream->flush != NULL ?
|
||||
mStreamCommon->analyzeStatus("flush", mStream->flush(mStream)) :
|
||||
Stream::analyzeStatus("flush", mStream->flush(mStream)) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -260,7 +261,7 @@ Return<void> StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl
|
||||
TimeSpec timeStamp = { 0, 0 };
|
||||
if (mStream->get_presentation_position != NULL) {
|
||||
struct timespec halTimeStamp;
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
retval = Stream::analyzeStatus(
|
||||
"get_presentation_position",
|
||||
mStream->get_presentation_position(mStream, &frames, &halTimeStamp),
|
||||
// Don't logspam on EINVAL--it's normal for get_presentation_position
|
||||
@@ -275,6 +276,23 @@ Return<void> StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::start() {
|
||||
return mStreamMmap->start();
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::stop() {
|
||||
return mStreamMmap->stop();
|
||||
}
|
||||
|
||||
Return<void> StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) {
|
||||
return mStreamMmap->createMmapBuffer(
|
||||
minSizeFrames, audio_stream_out_frame_size(mStream), _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) {
|
||||
return mStreamMmap->getMmapPosition(_hidl_cb);
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
|
||||
@@ -91,11 +91,16 @@ struct StreamOut : public IStreamOut {
|
||||
Return<Result> drain(AudioDrain type) override;
|
||||
Return<Result> flush() override;
|
||||
Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) override;
|
||||
Return<Result> start() override;
|
||||
Return<Result> stop() override;
|
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
|
||||
Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
audio_hw_device_t *mDevice;
|
||||
audio_stream_out_t *mStream;
|
||||
sp<Stream> mStreamCommon;
|
||||
sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
|
||||
sp<IStreamOutCallback> mCallback;
|
||||
|
||||
virtual ~StreamOut();
|
||||
|
||||
Reference in New Issue
Block a user