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:
Eric Laurent
2016-12-15 19:15:45 -08:00
parent ed9fa0ed01
commit 7deb7dad39
7 changed files with 169 additions and 18 deletions

View File

@@ -33,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \
libhidlbase \
libhidltransport \
libhwbinder \
libcutils \
libutils \
libhardware \
liblog \

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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();
};

View File

@@ -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, &timestampUs));
}
@@ -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

View File

@@ -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();