aaudio: fix problems with PlayerBase and ref counting
CTS test was crashing because of a multiple inheritance
problem involving PlayerBase.
We now implement separate PlayerBase class that sits between
AudioStream and the system.
Bug: 65450109
Test: CTS nativemedia/aaudio
Change-Id: I424663acc1eeacc9544769991495cb48f4110359
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 702b12a..d38fe46 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudio"
+#define LOG_TAG "AudioStreamTrack"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -115,7 +115,7 @@
ALOGD("AudioStreamTrack::open(), request notificationFrames = %d, frameCount = %u",
notificationFrames, (uint)frameCount);
- mAudioTrack = new AudioTrack();
+ mAudioTrack = new AudioTrack(); // TODO review
if (getDeviceId() != AAUDIO_UNSPECIFIED) {
mAudioTrack->setOutputDevice(getDeviceId());
}
@@ -143,8 +143,7 @@
return AAudioConvert_androidToAAudioResult(status);
}
- //TrackPlayerBase init
- init(mAudioTrack.get(), PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA);
+ doSetVolume();
// Get the actual values from the AudioTrack.
setSamplesPerFrame(mAudioTrack->channelCount());
@@ -199,7 +198,7 @@
aaudio_result_t AudioStreamTrack::close()
{
if (getState() != AAUDIO_STREAM_STATE_CLOSED) {
- destroy();
+ mAudioTrack->removeAudioDeviceCallback(mDeviceCallback);
setState(AAUDIO_STREAM_STATE_CLOSED);
}
mFixedBlockReader.close();
@@ -224,8 +223,7 @@
return;
}
-aaudio_result_t AudioStreamTrack::requestStart()
-{
+aaudio_result_t AudioStreamTrack::requestStart() {
std::lock_guard<std::mutex> lock(mStreamMutex);
if (mAudioTrack.get() == nullptr) {
@@ -238,7 +236,7 @@
return AAudioConvert_androidToAAudioResult(err);
}
- err = startWithStatus();
+ err = mAudioTrack->start();
if (err != OK) {
return AAudioConvert_androidToAAudioResult(err);
} else {
@@ -248,12 +246,11 @@
return AAUDIO_OK;
}
-aaudio_result_t AudioStreamTrack::requestPause()
-{
+aaudio_result_t AudioStreamTrack::requestPause() {
std::lock_guard<std::mutex> lock(mStreamMutex);
if (mAudioTrack.get() == nullptr) {
- ALOGE("AudioStreamTrack::requestPause() no AudioTrack");
+ ALOGE("requestPause() no AudioTrack");
return AAUDIO_ERROR_INVALID_STATE;
} else if (getState() != AAUDIO_STREAM_STATE_STARTING
&& getState() != AAUDIO_STREAM_STATE_STARTED) {
@@ -263,7 +260,7 @@
}
onStop();
setState(AAUDIO_STREAM_STATE_PAUSING);
- pause();
+ mAudioTrack->pause();
status_t err = mAudioTrack->getPosition(&mPositionWhenPausing);
if (err != OK) {
return AAudioConvert_androidToAAudioResult(err);
@@ -300,9 +297,9 @@
setState(AAUDIO_STREAM_STATE_STOPPING);
incrementFramesRead(getFramesWritten() - getFramesRead()); // TODO review
mTimestampPosition.set(getFramesWritten());
- stop();
mFramesWritten.reset32();
mTimestampPosition.reset32();
+ mAudioTrack->stop();
return AAUDIO_OK;
}
@@ -465,3 +462,36 @@
}
return result;
}
+
+status_t AudioStreamTrack::doSetVolume() {
+ status_t status = NO_INIT;
+ if (mAudioTrack.get() != nullptr) {
+ float volume = getDuckAndMuteVolume();
+ mAudioTrack->setVolume(volume, volume);
+ status = NO_ERROR;
+ }
+ return status;
+}
+
+#if AAUDIO_USE_VOLUME_SHAPER
+binder::Status AudioStreamTrack::applyVolumeShaper(
+ const VolumeShaper::Configuration& configuration,
+ const VolumeShaper::Operation& operation) {
+
+ sp<VolumeShaper::Configuration> spConfiguration = new VolumeShaper::Configuration(configuration);
+ sp<VolumeShaper::Operation> spOperation = new VolumeShaper::Operation(operation);
+
+ if (mAudioTrack.get() != nullptr) {
+ ALOGD("applyVolumeShaper() from IPlayer");
+ VolumeShaper::Status status = mAudioTrack->applyVolumeShaper(spConfiguration, spOperation);
+ if (status < 0) { // a non-negative value is the volume shaper id.
+ ALOGE("applyVolumeShaper() failed with status %d", status);
+ }
+ return binder::Status::fromStatusT(status);
+ } else {
+ ALOGD("applyVolumeShaper()"
+ " no AudioTrack for volume control from IPlayer");
+ return binder::Status::ok();
+ }
+}
+#endif