From 7deb7dad39e58b6e5de812075950adc27cd51d95 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 15 Dec 2016 19:15:45 -0800 Subject: [PATCH] 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 --- audio/2.0/default/Android.mk | 1 + audio/2.0/default/Stream.cpp | 26 ++++++++++++- audio/2.0/default/Stream.h | 81 ++++++++++++++++++++++++++++++++++++++++- audio/2.0/default/StreamIn.cpp | 26 +++++++++++-- audio/2.0/default/StreamIn.h | 6 +++ audio/2.0/default/StreamOut.cpp | 42 +++++++++++++++------ audio/2.0/default/StreamOut.h | 5 +++ 7 files changed, 169 insertions(+), 18 deletions(-) diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk index 2b1aa4f2..c3cfd699 100644 --- a/audio/2.0/default/Android.mk +++ b/audio/2.0/default/Android.mk @@ -33,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \ libhidlbase \ libhidltransport \ libhwbinder \ + libcutils \ libutils \ libhardware \ liblog \ diff --git a/audio/2.0/default/Stream.cpp b/audio/2.0/default/Stream.cpp index 40f67f07..f214eed9 100644 --- a/audio/2.0/default/Stream.cpp +++ b/audio/2.0/default/Stream.cpp @@ -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 Stream::debugDump(const hidl_handle& fd) { return Void(); } +Return Stream::start() { + return Result::NOT_SUPPORTED; +} + +Return Stream::stop() { + return Result::NOT_SUPPORTED; +} + +Return Stream::createMmapBuffer(int32_t minSizeFrames __unused, + createMmapBuffer_cb _hidl_cb) { + Result retval(Result::NOT_SUPPORTED); + MmapBufferInfo info; + _hidl_cb(retval, info); + return Void(); +} + +Return 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 diff --git a/audio/2.0/default/Stream.h b/audio/2.0/default/Stream.h index 0ebd723e..819bbf7c 100644 --- a/audio/2.0/default/Stream.h +++ b/audio/2.0/default/Stream.h @@ -18,6 +18,7 @@ #define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H #include +#include #include #include @@ -71,9 +72,13 @@ struct Stream : public IStream, public ParametersUtil { const hidl_vec& keys, getParameters_cb _hidl_cb) override; Return setParameters(const hidl_vec& parameters) override; Return debugDump(const hidl_handle& fd) override; + Return start() override; + Return stop() override; + Return createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; + Return 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 +struct StreamMmap : public RefBase { + explicit StreamMmap(T* stream) : mStream(stream) {} + + Return start(); + Return stop(); + Return createMmapBuffer( + int32_t minSizeFrames, size_t frameSize, IStream::createMmapBuffer_cb _hidl_cb); + Return getMmapPosition(IStream::getMmapPosition_cb _hidl_cb); + + private: + StreamMmap() {} + + T *mStream; +}; + +template +Return StreamMmap::start() { + if (mStream->start == NULL) return Result::NOT_SUPPORTED; + int result = mStream->start(mStream); + return Stream::analyzeStatus("start", result); +} + +template +Return StreamMmap::stop() { + if (mStream->stop == NULL) return Result::NOT_SUPPORTED; + int result = mStream->stop(mStream); + return Stream::analyzeStatus("stop", result); +} + +template +Return StreamMmap::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 +Return StreamMmap::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 diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp index 1bc9dfb4..1441e74c 100644 --- a/audio/2.0/default/StreamIn.cpp +++ b/audio/2.0/default/StreamIn.cpp @@ -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(stream)) { } StreamIn::~StreamIn() { @@ -130,6 +132,22 @@ Return StreamIn::debugDump(const hidl_handle& fd) { return mStreamCommon->debugDump(fd); } +Return StreamIn::start() { + return mStreamMmap->start(); +} + +Return StreamIn::stop() { + return mStreamMmap->stop(); +} + +Return StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) { + return mStreamMmap->createMmapBuffer( + minSizeFrames, audio_stream_in_frame_size(mStream), _hidl_cb); +} + +Return StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) { + return mStreamMmap->getMmapPosition(_hidl_cb); +} // Methods from ::android::hardware::audio::V2_0::IStreamIn follow. Return StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) { @@ -144,7 +162,7 @@ Return StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) { } Return 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 StreamIn::read(uint64_t size, read_cb _hidl_cb) { @@ -157,7 +175,7 @@ Return 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 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) { diff --git a/audio/2.0/default/StreamIn.h b/audio/2.0/default/StreamIn.h index f7c17b7a..65e94bbf 100644 --- a/audio/2.0/default/StreamIn.h +++ b/audio/2.0/default/StreamIn.h @@ -80,11 +80,17 @@ struct StreamIn : public IStreamIn { Return read(uint64_t size, read_cb _hidl_cb) override; Return getInputFramesLost() override; Return getCapturePosition(getCapturePosition_cb _hidl_cb) override; + Return start() override; + Return stop() override; + Return createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; + Return getMmapPosition(getMmapPosition_cb _hidl_cb) override; private: audio_hw_device_t *mDevice; audio_stream_in_t *mStream; sp mStreamCommon; + sp> mStreamMmap; + virtual ~StreamIn(); }; diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp index 913b6ae7..1ccd2a9c 100644 --- a/audio/2.0/default/StreamOut.cpp +++ b/audio/2.0/default/StreamOut.cpp @@ -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(stream)) { } StreamOut::~StreamOut() { @@ -132,7 +134,6 @@ Return StreamOut::debugDump(const hidl_handle& fd) { return mStreamCommon->debugDump(fd); } - // Methods from ::android::hardware::audio::V2_0::IStreamOut follow. Return StreamOut::getLatency() { return mStream->get_latency(mStream); @@ -141,7 +142,7 @@ Return StreamOut::getLatency() { Return 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 StreamOut::write(const hidl_vec& 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 StreamOut::write(const hidl_vec& data, write_cb _hidl_cb) Return 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 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 StreamOut::setCallback(const sp& callback) { if (result == 0) { mCallback = callback; } - return mStreamCommon->analyzeStatus("set_callback", result); + return Stream::analyzeStatus("set_callback", result); } Return StreamOut::clearCallback() { @@ -227,13 +228,13 @@ Return StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_c Return StreamOut::pause() { return mStream->pause != NULL ? - mStreamCommon->analyzeStatus("pause", mStream->pause(mStream)) : + Stream::analyzeStatus("pause", mStream->pause(mStream)) : Result::NOT_SUPPORTED; } Return 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 StreamOut::supportsDrain() { Return StreamOut::drain(AudioDrain type) { return mStream->drain != NULL ? - mStreamCommon->analyzeStatus( + Stream::analyzeStatus( "drain", mStream->drain(mStream, static_cast(type))) : Result::NOT_SUPPORTED; } Return 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 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 StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl return Void(); } +Return StreamOut::start() { + return mStreamMmap->start(); +} + +Return StreamOut::stop() { + return mStreamMmap->stop(); +} + +Return StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) { + return mStreamMmap->createMmapBuffer( + minSizeFrames, audio_stream_out_frame_size(mStream), _hidl_cb); +} + +Return StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) { + return mStreamMmap->getMmapPosition(_hidl_cb); +} + } // namespace implementation } // namespace V2_0 } // namespace audio diff --git a/audio/2.0/default/StreamOut.h b/audio/2.0/default/StreamOut.h index dc9a6049..9b7f9f83 100644 --- a/audio/2.0/default/StreamOut.h +++ b/audio/2.0/default/StreamOut.h @@ -91,11 +91,16 @@ struct StreamOut : public IStreamOut { Return drain(AudioDrain type) override; Return flush() override; Return getPresentationPosition(getPresentationPosition_cb _hidl_cb) override; + Return start() override; + Return stop() override; + Return createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; + Return getMmapPosition(getMmapPosition_cb _hidl_cb) override; private: audio_hw_device_t *mDevice; audio_stream_out_t *mStream; sp mStreamCommon; + sp> mStreamMmap; sp mCallback; virtual ~StreamOut(); -- 2.11.0