Refactor adjust channels buffer provider.

Combine adjust channels buffer provider and adjust channels non-destructive
buffer provider.
When contracting mono + haptic channels to mono, do not use
adjust_channels to avoid mixing haptic channel into audio channel.

Bug: 125915810
Test: play audio-haptic coupled files
Change-Id: I39916a3e0628a44ed4a148c265564af7135a2176
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index b764ccb..21d25e1 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -627,79 +627,68 @@
     }
 }
 
-AdjustChannelsBufferProvider::AdjustChannelsBufferProvider(audio_format_t format,
-        size_t inChannelCount, size_t outChannelCount, size_t frameCount) :
+AdjustChannelsBufferProvider::AdjustChannelsBufferProvider(
+        audio_format_t format, size_t inChannelCount, size_t outChannelCount,
+        size_t frameCount, audio_format_t contractedFormat, void* contractedBuffer) :
         CopyBufferProvider(
                 audio_bytes_per_frame(inChannelCount, format),
-                audio_bytes_per_frame(outChannelCount, format),
+                audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
                 frameCount),
         mFormat(format),
         mInChannelCount(inChannelCount),
         mOutChannelCount(outChannelCount),
-        mSampleSizeInBytes(audio_bytes_per_sample(format))
-{
-    ALOGV("AdjustBufferProvider(%p)(%#x, %zu, %zu, %zu)",
-            this, format, inChannelCount, outChannelCount, frameCount);
-}
-
-void AdjustChannelsBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
-{
-    adjust_channels(src, mInChannelCount, dst, mOutChannelCount, mSampleSizeInBytes,
-            frames * mInChannelCount * mSampleSizeInBytes);
-}
-
-AdjustChannelsNonDestructiveBufferProvider::AdjustChannelsNonDestructiveBufferProvider(
-        audio_format_t format, size_t inChannelCount, size_t outChannelCount,
-        audio_format_t contractedFormat, size_t contractedFrameCount, void* contractedBuffer) :
-        CopyBufferProvider(
-                audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
-                audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
-                contractedFrameCount),
-        mFormat(format),
-        mInChannelCount(inChannelCount),
-        mOutChannelCount(outChannelCount),
         mSampleSizeInBytes(audio_bytes_per_sample(format)),
+        mFrameCount(frameCount),
         mContractedChannelCount(inChannelCount - outChannelCount),
         mContractedFormat(contractedFormat),
-        mContractedFrameCount(contractedFrameCount),
         mContractedBuffer(contractedBuffer),
         mContractedWrittenFrames(0)
 {
-    ALOGV("AdjustChannelsNonDestructiveBufferProvider(%p)(%#x, %zu, %zu, %#x, %p)",
-            this, format, inChannelCount, outChannelCount, contractedFormat, contractedBuffer);
+    ALOGV("AdjustChannelsBufferProvider(%p)(%#x, %zu, %zu, %zu, %#x, %p)", this, format,
+            inChannelCount, outChannelCount, frameCount, contractedFormat, contractedBuffer);
     if (mContractedFormat != AUDIO_FORMAT_INVALID && mInChannelCount > mOutChannelCount) {
         mContractedFrameSize = audio_bytes_per_frame(mContractedChannelCount, mContractedFormat);
     }
 }
 
-status_t AdjustChannelsNonDestructiveBufferProvider::getNextBuffer(
-        AudioBufferProvider::Buffer* pBuffer)
+status_t AdjustChannelsBufferProvider::getNextBuffer(AudioBufferProvider::Buffer* pBuffer)
 {
-    const size_t outFramesLeft = mContractedFrameCount - mContractedWrittenFrames;
-    if (outFramesLeft < pBuffer->frameCount) {
-        // Restrict the frame count so that we don't write over the size of the output buffer.
-        pBuffer->frameCount = outFramesLeft;
+    if (mContractedBuffer != nullptr) {
+        // Restrict frame count only when it is needed to save contracted frames.
+        const size_t outFramesLeft = mFrameCount - mContractedWrittenFrames;
+        if (outFramesLeft < pBuffer->frameCount) {
+            // Restrict the frame count so that we don't write over the size of the output buffer.
+            pBuffer->frameCount = outFramesLeft;
+        }
     }
     return CopyBufferProvider::getNextBuffer(pBuffer);
 }
 
-void AdjustChannelsNonDestructiveBufferProvider::copyFrames(
-        void *dst, const void *src, size_t frames)
+void AdjustChannelsBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
 {
-    adjust_channels_non_destructive(src, mInChannelCount, dst, mOutChannelCount, mSampleSizeInBytes,
-            frames * mInChannelCount * mSampleSizeInBytes);
-    if (mContractedFormat != AUDIO_FORMAT_INVALID && mContractedBuffer != NULL
-            && mInChannelCount > mOutChannelCount) {
-        const size_t contractedIdx = frames * mOutChannelCount * mSampleSizeInBytes;
-        memcpy_by_audio_format(
-                (uint8_t*)mContractedBuffer + mContractedWrittenFrames * mContractedFrameSize,
-                mContractedFormat, (uint8_t*)dst + contractedIdx, mFormat,
-                mContractedChannelCount * frames);
-        mContractedWrittenFrames += frames;
+    if (mInChannelCount > mOutChannelCount) {
+        // For case multi to mono, adjust_channels has special logic that will mix first two input
+        // channels into a single output channel. In that case, use adjust_channels_non_destructive
+        // to keep only one channel data even when contracting to mono.
+        adjust_channels_non_destructive(src, mInChannelCount, dst, mOutChannelCount,
+                mSampleSizeInBytes, frames * mInChannelCount * mSampleSizeInBytes);
+        if (mContractedFormat != AUDIO_FORMAT_INVALID
+            && mContractedBuffer != nullptr) {
+            const size_t contractedIdx = frames * mOutChannelCount * mSampleSizeInBytes;
+            memcpy_by_audio_format(
+                    (uint8_t*) mContractedBuffer + mContractedWrittenFrames * mContractedFrameSize,
+                    mContractedFormat, (uint8_t*) dst + contractedIdx, mFormat,
+                    mContractedChannelCount * frames);
+            mContractedWrittenFrames += frames;
+        }
+    } else {
+        // Prefer expanding data from the end of each audio frame.
+        adjust_channels(src, mInChannelCount, dst, mOutChannelCount,
+                mSampleSizeInBytes, frames * mInChannelCount * mSampleSizeInBytes);
     }
 }
 
-void AdjustChannelsNonDestructiveBufferProvider::reset()
+void AdjustChannelsBufferProvider::reset()
 {
     mContractedWrittenFrames = 0;
     CopyBufferProvider::reset();