Merge "libaudiohal@aidl: Fix position and latency reporting" into main am: cc7ef16ee2 am: 7b3e3d3fdc am: 47f9d132ac am: 1cc5d91f33
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2768547
Change-Id: I6eed07811db26fd26da3179e3597c98f8bdabd67
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index c058386..e74fc16 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -193,7 +193,7 @@
StreamDescriptor::Reply reply;
switch (state) {
case StreamDescriptor::State::ACTIVE:
- if (status_t status = pause(&reply); status != OK) return status;
+ RETURN_STATUS_IF_ERROR(pause(&reply));
if (reply.state != StreamDescriptor::State::PAUSED) {
ALOGE("%s: unexpected stream state: %s (expected PAUSED)",
__func__, toString(reply.state).c_str());
@@ -203,7 +203,7 @@
case StreamDescriptor::State::PAUSED:
case StreamDescriptor::State::DRAIN_PAUSED:
if (mIsInput) return flush();
- if (status_t status = flush(&reply); status != OK) return status;
+ RETURN_STATUS_IF_ERROR(flush(&reply));
if (reply.state != StreamDescriptor::State::IDLE) {
ALOGE("%s: unexpected stream state: %s (expected IDLE)",
__func__, toString(reply.state).c_str());
@@ -211,10 +211,8 @@
}
FALLTHROUGH_INTENDED;
case StreamDescriptor::State::IDLE:
- if (status_t status = sendCommand(makeHalCommand<HalCommand::Tag::standby>(),
- &reply, true /*safeFromNonWorkerThread*/); status != OK) {
- return status;
- }
+ RETURN_STATUS_IF_ERROR(sendCommand(makeHalCommand<HalCommand::Tag::standby>(),
+ &reply, true /*safeFromNonWorkerThread*/));
if (reply.state != StreamDescriptor::State::STANDBY) {
ALOGE("%s: unexpected stream state: %s (expected STANDBY)",
__func__, toString(reply.state).c_str());
@@ -244,10 +242,7 @@
const auto state = getState();
StreamDescriptor::Reply reply;
if (state == StreamDescriptor::State::STANDBY) {
- if (status_t status = sendCommand(makeHalCommand<HalCommand::Tag::start>(), &reply, true);
- status != OK) {
- return status;
- }
+ RETURN_STATUS_IF_ERROR(sendCommand(makeHalCommand<HalCommand::Tag::start>(), &reply, true));
return sendCommand(makeHalCommand<HalCommand::Tag::burst>(0), &reply, true);
}
@@ -264,10 +259,7 @@
ALOGV("%p %s::%s", this, getClassName().c_str(), __func__);
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
- if (status_t status = updateCountersIfNeeded(&reply); status != OK) {
- return status;
- }
-
+ RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
*latency = std::clamp(std::max<int32_t>(0, reply.latencyMs), 1, 3000);
ALOGW_IF(reply.latencyMs != static_cast<int32_t>(*latency),
"Suspicious latency value reported by HAL: %d, clamped to %u", reply.latencyMs,
@@ -279,11 +271,9 @@
ALOGV("%p %s::%s", this, getClassName().c_str(), __func__);
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
- if (status_t status = updateCountersIfNeeded(&reply); status != OK) {
- return status;
- }
- *frames = reply.observable.frames;
- *timestamp = reply.observable.timeNs;
+ RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
+ *frames = std::max<int64_t>(0, reply.observable.frames);
+ *timestamp = std::max<int64_t>(0, reply.observable.timeNs);
return OK;
}
@@ -292,12 +282,9 @@
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
// TODO: switch to updateCountersIfNeeded once we sort out mWorkerTid initialization
- if (status_t status = sendCommand(makeHalCommand<HalCommand::Tag::getStatus>(), &reply, true);
- status != OK) {
- return status;
- }
- *frames = reply.hardware.frames;
- *timestamp = reply.hardware.timeNs;
+ RETURN_STATUS_IF_ERROR(sendCommand(makeHalCommand<HalCommand::Tag::getStatus>(), &reply, true));
+ *frames = std::max<int64_t>(0, reply.hardware.frames);
+ *timestamp = std::max<int64_t>(0, reply.hardware.timeNs);
return OK;
}
@@ -305,10 +292,8 @@
ALOGV("%p %s::%s", this, getClassName().c_str(), __func__);
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
- if (status_t status = updateCountersIfNeeded(&reply); status != OK) {
- return status;
- }
- *frames = reply.xrunFrames;
+ RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
+ *frames = std::max<int32_t>(0, reply.xrunFrames);
return OK;
}
@@ -323,10 +308,7 @@
// stream state), however this scenario wasn't supported by the HIDL HAL.
if (getState() == StreamDescriptor::State::STANDBY) {
StreamDescriptor::Reply reply;
- if (status_t status = sendCommand(makeHalCommand<HalCommand::Tag::start>(), &reply);
- status != OK) {
- return status;
- }
+ RETURN_STATUS_IF_ERROR(sendCommand(makeHalCommand<HalCommand::Tag::start>(), &reply));
if (reply.state != StreamDescriptor::State::IDLE) {
ALOGE("%s: failed to get the stream out of standby, actual state: %s",
__func__, toString(reply.state).c_str());
@@ -345,9 +327,7 @@
}
}
StreamDescriptor::Reply reply;
- if (status_t status = sendCommand(burst, &reply); status != OK) {
- return status;
- }
+ RETURN_STATUS_IF_ERROR(sendCommand(burst, &reply));
*transferred = reply.fmqByteCount;
if (mIsInput) {
LOG_ALWAYS_FATAL_IF(*transferred > bytes,
@@ -385,11 +365,8 @@
if (state == StreamDescriptor::State::IDLE) {
StreamDescriptor::Reply localReply{};
StreamDescriptor::Reply* innerReply = reply ?: &localReply;
- if (status_t status =
- sendCommand(makeHalCommand<HalCommand::Tag::burst>(0), innerReply);
- status != OK) {
- return status;
- }
+ RETURN_STATUS_IF_ERROR(
+ sendCommand(makeHalCommand<HalCommand::Tag::burst>(0), innerReply));
if (innerReply->state != StreamDescriptor::State::ACTIVE) {
ALOGE("%s: unexpected stream state: %s (expected ACTIVE)",
__func__, toString(innerReply->state).c_str());
@@ -452,10 +429,7 @@
return BAD_VALUE;
}
int64_t aidlPosition = 0, aidlTimestamp = 0;
- if (status_t status = getHardwarePosition(&aidlPosition, &aidlTimestamp); status != OK) {
- return status;
- }
-
+ RETURN_STATUS_IF_ERROR(getHardwarePosition(&aidlPosition, &aidlTimestamp));
position->time_nanoseconds = aidlTimestamp;
position->position_frames = static_cast<int32_t>(aidlPosition);
return OK;
@@ -503,6 +477,11 @@
}
{
std::lock_guard l(mLock);
+ // Not every command replies with 'latencyMs' field filled out, substitute the last
+ // returned value in that case.
+ if (reply->latencyMs <= 0) {
+ reply->latencyMs = mLastReply.latencyMs;
+ }
mLastReply = *reply;
}
switch (reply->status) {
@@ -608,10 +587,8 @@
return BAD_VALUE;
}
int64_t aidlFrames = 0, aidlTimestamp = 0;
- if (status_t status = getObservablePosition(&aidlFrames, &aidlTimestamp); status != OK) {
- return OK;
- }
- *dspFrames = std::clamp<int64_t>(aidlFrames, 0, UINT32_MAX);
+ RETURN_STATUS_IF_ERROR(getObservablePosition(&aidlFrames, &aidlTimestamp));
+ *dspFrames = static_cast<uint32_t>(aidlFrames);
return OK;
}
@@ -680,10 +657,8 @@
return BAD_VALUE;
}
int64_t aidlFrames = 0, aidlTimestamp = 0;
- if (status_t status = getObservablePosition(&aidlFrames, &aidlTimestamp); status != OK) {
- return status;
- }
- *frames = std::max<int64_t>(0, aidlFrames);
+ RETURN_STATUS_IF_ERROR(getObservablePosition(&aidlFrames, &aidlTimestamp));
+ *frames = aidlFrames;
timestamp->tv_sec = aidlTimestamp / NANOS_PER_SECOND;
timestamp->tv_nsec = aidlTimestamp - timestamp->tv_sec * NANOS_PER_SECOND;
return OK;
@@ -901,9 +876,7 @@
return BAD_VALUE;
}
int32_t aidlXruns = 0;
- if (status_t status = getXruns(&aidlXruns); status != OK) {
- return status;
- }
+ RETURN_STATUS_IF_ERROR(getXruns(&aidlXruns));
*framesLost = std::max<int32_t>(0, aidlXruns);
return OK;
}
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 3b369bd..4acc6ac 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -207,10 +207,13 @@
status_t getLatency(uint32_t *latency);
+ // Always returns non-negative values.
status_t getObservablePosition(int64_t *frames, int64_t *timestamp);
+ // Always returns non-negative values.
status_t getHardwarePosition(int64_t *frames, int64_t *timestamp);
+ // Always returns non-negative values.
status_t getXruns(int32_t *frames);
status_t transfer(void *buffer, size_t bytes, size_t *transferred);