audio: Fix glitching of remote submix

Align behavior with the HIDL implementation. This helps
to prevent glitches in the scenarios that use remote
submix for sending audio externally: Auto and Cast.

Bug: 322247032
Bug: 327220024
Test: Repro steps in b/327220024#comment14
Change-Id: If2e4ebd7145375a268ee5f0e4ab656bb3748b2fe
Merged-In: If2e4ebd7145375a268ee5f0e4ab656bb3748b2fe
This commit is contained in:
Mikhail Naganov 2024-03-05 17:42:20 -08:00
parent 4120b99ab6
commit 55e0afa49a
2 changed files with 12 additions and 4 deletions

View file

@ -212,7 +212,12 @@ class Module : public BnModule {
aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs,
sampleRateHz);
// Round up to nearest 16 frames since in the framework this is the size of a mixer burst.
return (rawSizeFrames + 15) & ~15;
const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15;
if (multipleOf16 <= 512) return multipleOf16;
// Larger buffers should use powers of 2.
int32_t powerOf2 = 1;
while (powerOf2 < multipleOf16) powerOf2 <<= 1;
return powerOf2;
}
ndk::ScopedAStatus bluetoothParametersUpdated();

View file

@ -136,10 +136,12 @@ void StreamRemoteSubmix::shutdown() {
mCurrentRoute->exitStandby(mIsInput);
RETURN_STATUS_IF_ERROR(mIsInput ? inRead(buffer, frameCount, actualFrameCount)
: outWrite(buffer, frameCount, actualFrameCount));
mFramesSinceStart += *actualFrameCount;
if (!mIsInput) return ::android::OK;
// Only input streams need to block, for output this is implemented by MonoPipe.
const long bufferDurationUs =
(*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
mFramesSinceStart += *actualFrameCount;
const long totalOffsetUs =
mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
@ -275,8 +277,9 @@ size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
char* buff = (char*)buffer;
size_t actuallyRead = 0;
long remainingFrames = frameCount;
const int64_t deadlineTimeNs = ::android::uptimeNanos() +
getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
const int64_t deadlineTimeNs =
::android::uptimeNanos() +
getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND / 2;
while (remainingFrames > 0) {
ssize_t framesRead = source->read(buff, remainingFrames);
LOG(VERBOSE) << __func__ << ": frames read " << framesRead;