Consolidate libaudioclient buffers p1
Prepare for libaudioclient buffer refactor by updating
clients of libaudioclient to use new buffer interface.
libaudioclient
- Wrap existing buffers with new interface
- Modify internal calls to be compatible with wrap
AAudio
- Update to use new buffer interface
- Update record to use callback
TrackPlayerBase
- Used for SLES (in different repo). Update to use sp<>
ToneGenerator/MediaPlayerService/AudioPlayer
- Update to use new buffer interface
StageFright
- Update to new callback interface
- Update to use new buffer interface
Bug: 216175830 - shared buffer
Bug: 199156212 - callback interface
Test: atest AudioTrackTest AudioRecordTest
atest AudioTrackOffloadTest
OboeTester non-exclusive, non-MMAP, power-saving for both
AAudio and SLES, input and output
No-Typo-Check: Existing class members
Change-Id: Ib1241f2e530bc509b2d4dde956ec5188f2287994
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index 38f3c24..dd11169 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -76,6 +76,7 @@
// This takes advantage of them killing the stream when they see a size out of range.
// That is an undocumented behavior.
// TODO add to API in AudioRecord and AudioTrack
+ // TODO(b/216175830) cleanup size re-computation
const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
aaudio_data_callback_result_t callbackResult;
(void) checkForDisconnectRequest(true);
@@ -83,7 +84,7 @@
// Note that this code assumes an AudioTrack::Buffer is the same as
// AudioRecord::Buffer
// TODO define our own AudioBuffer and pass it from the subclasses.
- size_t written = buffer.size;
+ size_t written = buffer.size();
if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
ALOGW("%s() data, stream disconnected", __func__);
// This will kill the stream and prevent it from being restarted.
@@ -96,23 +97,23 @@
// caused by Legacy callbacks running after the track is "stopped".
written = 0;
} else {
- if (buffer.frameCount == 0) {
+ if (buffer.getFrameCount() == 0) {
ALOGW("%s() data, frameCount is zero", __func__);
return written;
}
// If the caller specified an exact size then use a block size adapter.
if (mBlockAdapter != nullptr) {
- int32_t byteCount = buffer.frameCount * getBytesPerDeviceFrame();
+ int32_t byteCount = buffer.getFrameCount() * getBytesPerDeviceFrame();
callbackResult = mBlockAdapter->processVariableBlock(
- static_cast<uint8_t*>(buffer.raw), byteCount);
+ buffer.data(), byteCount);
} else {
// Call using the AAudio callback interface.
- callbackResult = callDataCallbackFrames(static_cast<uint8_t *>(buffer.raw),
- buffer.frameCount);
+ callbackResult = callDataCallbackFrames(buffer.data(),
+ buffer.getFrameCount());
}
if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
- written = buffer.frameCount * getBytesPerDeviceFrame();
+ written = buffer.getFrameCount() * getBytesPerDeviceFrame();
} else {
if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
@@ -134,6 +135,70 @@
return written;
}
+// TODO (b/216175830) this method is duplicated in order to ease refactoring which will
+// reconsolidate.
+size_t AudioStreamLegacy::onMoreData(const android::AudioRecord::Buffer& buffer) {
+ // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
+ // This takes advantage of them killing the stream when they see a size out of range.
+ // That is an undocumented behavior.
+ // TODO add to API in AudioRecord and AudioTrack
+ const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
+ aaudio_data_callback_result_t callbackResult;
+ (void) checkForDisconnectRequest(true);
+
+ // Note that this code assumes an AudioTrack::Buffer is the same as
+ // AudioRecord::Buffer
+ // TODO define our own AudioBuffer and pass it from the subclasses.
+ size_t written = buffer.size();
+ if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+ ALOGW("%s() data, stream disconnected", __func__);
+ // This will kill the stream and prevent it from being restarted.
+ // That is OK because the stream is disconnected.
+ written = SIZE_STOP_CALLBACKS;
+ } else if (!mCallbackEnabled.load()) {
+ ALOGW("%s() no data because callback disabled, set size=0", __func__);
+ // Do NOT use SIZE_STOP_CALLBACKS here because that will kill the stream and
+ // prevent it from being restarted. This can occur because of a race condition
+ // caused by Legacy callbacks running after the track is "stopped".
+ written = 0;
+ } else {
+ if (buffer.getFrameCount() == 0) {
+ ALOGW("%s() data, frameCount is zero", __func__);
+ return written;
+ }
+
+ // If the caller specified an exact size then use a block size adapter.
+ if (mBlockAdapter != nullptr) {
+ int32_t byteCount = buffer.getFrameCount() * getBytesPerDeviceFrame();
+ callbackResult = mBlockAdapter->processVariableBlock(
+ buffer.data(), byteCount);
+ } else {
+ // Call using the AAudio callback interface.
+ callbackResult = callDataCallbackFrames(buffer.data(),
+ buffer.getFrameCount());
+ }
+ if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
+ written = buffer.getFrameCount() * getBytesPerDeviceFrame();
+ } else {
+ if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
+ ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+ } else {
+ ALOGW("%s() callback returned invalid result = %d",
+ __func__, callbackResult);
+ }
+ written = 0;
+ systemStopInternal();
+ // Disable the callback just in case the system keeps trying to call us.
+ mCallbackEnabled.store(false);
+ }
+
+ if (updateStateMachine() != AAUDIO_OK) {
+ forceDisconnect();
+ mCallbackEnabled.store(false);
+ }
+ }
+ return written;
+}
aaudio_result_t AudioStreamLegacy::checkForDisconnectRequest(bool errorCallbackEnabled) {
if (mRequestDisconnect.isRequested()) {