libaudiohal: When starting write, consider the stream buffer size
When starting writing into a stream, use the bigger value from
the requested bytes to write and the stream buffer size.
This fixes a corner case when offload playback starts close
to the end of the track, and then jumps to the middle.
Bug: 63979005
Test: checked HAL logs for the repro case,
confirmed that Loopback, PM, YT, Camcoder, still work, also over BT
Change-Id: I924468619d2185fd679b739747c423babfb36ada
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 176abee..0cafa36 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -47,7 +47,8 @@
StreamHalHidl::StreamHalHidl(IStream *stream)
: ConversionHelperHidl("Stream"),
mStream(stream),
- mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT) {
+ mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT),
+ mCachedBufferSize(0){
// Instrument audio signal power logging.
// Note: This assumes channel mask, format, and sample rate do not change after creation.
@@ -73,7 +74,11 @@
status_t StreamHalHidl::getBufferSize(size_t *size) {
if (!mStream) return NO_INIT;
- return processReturn("getBufferSize", mStream->getBufferSize(), size);
+ status_t status = processReturn("getBufferSize", mStream->getBufferSize(), size);
+ if (status == OK) {
+ mCachedBufferSize = *size;
+ }
+ return status;
}
status_t StreamHalHidl::getChannelMask(audio_channel_mask_t *mask) {
@@ -202,6 +207,14 @@
return OK;
}
+status_t StreamHalHidl::getCachedBufferSize(size_t *size) {
+ if (mCachedBufferSize != 0) {
+ *size = mCachedBufferSize;
+ return OK;
+ }
+ return getBufferSize(size);
+}
+
bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
return true;
@@ -320,8 +333,19 @@
}
status_t status;
- if (!mDataMQ && (status = prepareForWriting(bytes)) != OK) {
- return status;
+ if (!mDataMQ) {
+ // In case if playback starts close to the end of a compressed track, the bytes
+ // that need to be written is less than the actual buffer size. Need to use
+ // full buffer size for the MQ since otherwise after seeking back to the middle
+ // data will be truncated.
+ size_t bufferSize;
+ if ((status = getCachedBufferSize(&bufferSize)) != OK) {
+ return status;
+ }
+ if (bytes > bufferSize) bufferSize = bytes;
+ if ((status = prepareForWriting(bufferSize)) != OK) {
+ return status;
+ }
}
status = callWriterThread(
diff --git a/media/libaudiohal/StreamHalHidl.h b/media/libaudiohal/StreamHalHidl.h
index a69cce8..d4ab943 100644
--- a/media/libaudiohal/StreamHalHidl.h
+++ b/media/libaudiohal/StreamHalHidl.h
@@ -102,6 +102,8 @@
// The destructor automatically closes the stream.
virtual ~StreamHalHidl();
+ status_t getCachedBufferSize(size_t *size);
+
bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
// mStreamPowerLog is used for audio signal power logging.
@@ -111,6 +113,7 @@
const int HAL_THREAD_PRIORITY_DEFAULT = -1;
IStream *mStream;
int mHalThreadPriority;
+ size_t mCachedBufferSize;
};
class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {