Merge "Modify AAudio for new AudioTrack callback format"
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index 0f24771..38f3c24 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -37,15 +37,6 @@
: AudioStream() {
}
-// Called from AudioTrack.cpp or AudioRecord.cpp
-static void AudioStreamLegacy_callback(int event, void* userData, void *info) {
- AudioStreamLegacy *streamLegacy = (AudioStreamLegacy *) userData;
- streamLegacy->processCallback(event, info);
-}
-
-aaudio_legacy_callback_t AudioStreamLegacy::getLegacyCallback() {
- return AudioStreamLegacy_callback;
-}
aaudio_data_callback_result_t AudioStreamLegacy::callDataCallbackFrames(uint8_t *buffer,
int32_t numFrames) {
@@ -73,84 +64,77 @@
return (int32_t) callDataCallbackFrames(buffer, numFrames);
}
-void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
- aaudio_data_callback_result_t callbackResult;
+
+void AudioStreamLegacy::onNewIAudioTrack() {
+ ALOGD("%s stream disconnected", __func__);
+ forceDisconnect();
+ mCallbackEnabled.store(false);
+}
+
+size_t AudioStreamLegacy::onMoreData(const android::AudioTrack::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);
- switch (opcode) {
- case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: {
- (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.
- AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
- if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
- ALOGW("processCallbackCommon() data, stream disconnected");
- // This will kill the stream and prevent it from being restarted.
- // That is OK because the stream is disconnected.
- audioBuffer->size = SIZE_STOP_CALLBACKS;
- } else if (!mCallbackEnabled.load()) {
- ALOGW("processCallbackCommon() no data because callback disabled, set size=0");
- // 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".
- audioBuffer->size = 0;
- } else {
- if (audioBuffer->frameCount == 0) {
- ALOGW("processCallbackCommon() data, frameCount is zero");
- return;
- }
-
- // If the caller specified an exact size then use a block size adapter.
- if (mBlockAdapter != nullptr) {
- int32_t byteCount = audioBuffer->frameCount * getBytesPerDeviceFrame();
- callbackResult = mBlockAdapter->processVariableBlock(
- (uint8_t *) audioBuffer->raw, byteCount);
- } else {
- // Call using the AAudio callback interface.
- callbackResult = callDataCallbackFrames((uint8_t *)audioBuffer->raw,
- audioBuffer->frameCount);
- }
- if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
- audioBuffer->size = audioBuffer->frameCount * 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);
- }
- audioBuffer->size = 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);
- }
- }
+ // 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.frameCount == 0) {
+ ALOGW("%s() data, frameCount is zero", __func__);
+ return written;
}
- break;
- // Stream got rerouted so we disconnect.
- case AAUDIO_CALLBACK_OPERATION_DISCONNECTED:
- ALOGD("processCallbackCommon() stream disconnected");
+ // If the caller specified an exact size then use a block size adapter.
+ if (mBlockAdapter != nullptr) {
+ int32_t byteCount = buffer.frameCount * getBytesPerDeviceFrame();
+ callbackResult = mBlockAdapter->processVariableBlock(
+ static_cast<uint8_t*>(buffer.raw), byteCount);
+ } else {
+ // Call using the AAudio callback interface.
+ callbackResult = callDataCallbackFrames(static_cast<uint8_t *>(buffer.raw),
+ buffer.frameCount);
+ }
+ if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
+ written = buffer.frameCount * 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);
- break;
-
- default:
- break;
+ }
}
+ return written;
}
+
aaudio_result_t AudioStreamLegacy::checkForDisconnectRequest(bool errorCallbackEnabled) {
if (mRequestDisconnect.isRequested()) {
ALOGD("checkForDisconnectRequest() mRequestDisconnect acknowledged");
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.h b/media/libaaudio/src/legacy/AudioStreamLegacy.h
index d9ba990..c54d7e2 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.h
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.h
@@ -18,6 +18,7 @@
#define LEGACY_AUDIO_STREAM_LEGACY_H
#include <media/AudioTimestamp.h>
+#include <media/AudioTrack.h>
#include <media/AudioSystem.h>
#include <aaudio/AAudio.h>
@@ -30,8 +31,6 @@
namespace aaudio {
-typedef void (*aaudio_legacy_callback_t)(int event, void* user, void *info);
-
enum {
/**
* Request that the callback function should fill the data buffer of an output stream,
@@ -56,21 +55,17 @@
typedef int32_t aaudio_callback_operation_t;
-class AudioStreamLegacy : public AudioStream, public FixedBlockProcessor {
+class AudioStreamLegacy : public AudioStream,
+ public FixedBlockProcessor,
+ protected android::AudioTrack::IAudioTrackCallback {
public:
AudioStreamLegacy();
virtual ~AudioStreamLegacy() = default;
- aaudio_legacy_callback_t getLegacyCallback();
int32_t callDataCallbackFrames(uint8_t *buffer, int32_t numFrames);
- // This is public so it can be called from the C callback function.
- // This is called from the AudioTrack/AudioRecord client.
- virtual void processCallback(int event, void *info) = 0;
-
- void processCallbackCommon(aaudio_callback_operation_t opcode, void *info);
// Implement FixedBlockProcessor
int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) override;
@@ -86,7 +81,8 @@
}
protected:
-
+ size_t onMoreData(const android::AudioTrack::Buffer& buffer) override;
+ void onNewIAudioTrack() override;
aaudio_result_t getBestTimestamp(clockid_t clockId,
int64_t *framePosition,
int64_t *timeNanoseconds,
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 12771cc..a3f89f6 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -37,6 +37,10 @@
using namespace android;
using namespace aaudio;
+static void sCallbackWrapper(int event, void* userData, void* info) {
+ static_cast<AudioStreamRecord*>(userData)->processCallback(event, info);
+}
+
AudioStreamRecord::AudioStreamRecord()
: AudioStreamLegacy()
, mFixedBlockWriter(*this)
@@ -129,7 +133,7 @@
AudioRecord::transfer_type streamTransferType = AudioRecord::transfer_type::TRANSFER_SYNC;
if (builder.getDataCallbackProc() != nullptr) {
streamTransferType = AudioRecord::transfer_type::TRANSFER_CALLBACK;
- callback = getLegacyCallback();
+ callback = sCallbackWrapper;
callbackData = this;
}
mCallbackBufferSize = builder.getFramesPerDataCallback();
@@ -353,14 +357,15 @@
void AudioStreamRecord::processCallback(int event, void *info) {
switch (event) {
case AudioRecord::EVENT_MORE_DATA:
- processCallbackCommon(AAUDIO_CALLBACK_OPERATION_PROCESS_DATA, info);
+ {
+ AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
+ audioBuffer->size = onMoreData(*audioBuffer);
break;
-
+ }
// Stream got rerouted so we disconnect.
case AudioRecord::EVENT_NEW_IAUDIORECORD:
- processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info);
+ onNewIAudioTrack();
break;
-
default:
break;
}
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.h b/media/libaaudio/src/legacy/AudioStreamRecord.h
index 692651d..5ce73f9 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.h
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.h
@@ -65,7 +65,9 @@
}
// This is public so it can be called from the C callback function.
- void processCallback(int event, void *info) override;
+ void processCallback(int event, void *info);
+
+ void processCallbackRecord(aaudio_callback_operation_t opcode, void *info);
int64_t incrementClientFrameCounter(int32_t frames) override {
return incrementFramesRead(frames);
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index fe84ec5..17a6d0c 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -103,14 +103,12 @@
: getFormat();
// Setup the callback if there is one.
- AudioTrack::legacy_callback_t callback = nullptr;
- void *callbackData = nullptr;
+ wp<AudioTrack::IAudioTrackCallback> callback;
// Note that TRANSFER_SYNC does not allow FAST track
AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC;
if (builder.getDataCallbackProc() != nullptr) {
streamTransferType = AudioTrack::transfer_type::TRANSFER_CALLBACK;
- callback = getLegacyCallback();
- callbackData = this;
+ callback = wp<AudioTrack::IAudioTrackCallback>::fromExisting(this);
// If the total buffer size is unspecified then base the size on the burst size.
if (frameCount == 0
@@ -157,7 +155,6 @@
frameCount,
flags,
callback,
- callbackData,
notificationFrames,
nullptr, // DEFAULT sharedBuffer*/,
false, // DEFAULT threadCanCallJava
@@ -293,31 +290,19 @@
AudioStream::close_l();
}
-void AudioStreamTrack::processCallback(int event, void *info) {
- switch (event) {
- case AudioTrack::EVENT_MORE_DATA:
- processCallbackCommon(AAUDIO_CALLBACK_OPERATION_PROCESS_DATA, info);
- break;
-
- // Stream got rerouted so we disconnect.
- case AudioTrack::EVENT_NEW_IAUDIOTRACK:
- // request stream disconnect if the restored AudioTrack has properties not matching
- // what was requested initially
- if (mAudioTrack->channelCount() != getSamplesPerFrame()
- || mAudioTrack->format() != getFormat()
- || mAudioTrack->getSampleRate() != getSampleRate()
- || mAudioTrack->getRoutedDeviceId() != getDeviceId()
- || getBufferCapacityFromDevice() != getBufferCapacity()
- || getFramesPerBurstFromDevice() != getFramesPerBurst()) {
- processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info);
- }
- break;
-
- default:
- break;
+void AudioStreamTrack::onNewIAudioTrack() {
+ // Stream got rerouted so we disconnect.
+ // request stream disconnect if the restored AudioTrack has properties not matching
+ // what was requested initially
+ if (mAudioTrack->channelCount() != getSamplesPerFrame()
+ || mAudioTrack->format() != getFormat()
+ || mAudioTrack->getSampleRate() != getSampleRate()
+ || mAudioTrack->getRoutedDeviceId() != getDeviceId()
+ || getBufferCapacityFromDevice() != getBufferCapacity()
+ || getFramesPerBurstFromDevice() != getFramesPerBurst()) {
+ AudioStreamLegacy::onNewIAudioTrack();
}
- return;
}
aaudio_result_t AudioStreamTrack::requestStart_l() {
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index f604871..0f4d72b 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -81,9 +81,6 @@
aaudio_result_t updateStateMachine() override;
- // This is public so it can be called from the C callback function.
- void processCallback(int event, void *info) override;
-
int64_t incrementClientFrameCounter(int32_t frames) override {
return incrementFramesWritten(frames);
}
@@ -100,6 +97,7 @@
int32_t getFramesPerBurstFromDevice() const override;
int32_t getBufferCapacityFromDevice() const override;
+ void onNewIAudioTrack() override;
private: