83 lines
2.4 KiB
C++
83 lines
2.4 KiB
C++
// Copyright (C) 2021 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "RingBufferUtil.h"
|
|
|
|
#include <android-base/logging.h>
|
|
|
|
namespace audio_proxy::service {
|
|
namespace {
|
|
struct CopyDesc {
|
|
int8_t* dst = nullptr;
|
|
const int8_t* src = nullptr;
|
|
size_t len = 0;
|
|
};
|
|
} // namespace
|
|
|
|
void copyRingBuffer(int8_t* dstBuf1, size_t dstLen1, int8_t* dstBuf2,
|
|
size_t dstLen2, const int8_t* srcBuf1, size_t srcLen1,
|
|
const int8_t* srcBuf2, size_t srcLen2) {
|
|
// Caller should make sure the dst buffer has more space.
|
|
DCHECK_GE(dstLen1 + dstLen2, srcLen1 + srcLen2);
|
|
|
|
CopyDesc cp1 = {dstBuf1, srcBuf1, 0};
|
|
CopyDesc cp2;
|
|
CopyDesc cp3;
|
|
|
|
if (srcLen1 == dstLen1) {
|
|
cp1 = {dstBuf1, srcBuf1, srcLen1};
|
|
|
|
DCHECK_LE(srcLen2, dstLen2);
|
|
cp2 = {dstBuf2, srcBuf2, srcLen2};
|
|
|
|
// No need to copy more data, thus no need to update cp3.
|
|
} else if (srcLen1 < dstLen1) {
|
|
cp1 = {dstBuf1, srcBuf1, srcLen1};
|
|
|
|
if (dstLen1 <= srcLen1 + srcLen2) {
|
|
// Copy data into both dstBuf1 and dstBuf2.
|
|
cp2 = {cp1.dst + cp1.len, srcBuf2, dstLen1 - srcLen1};
|
|
cp3 = {dstBuf2, cp2.src + cp2.len, srcLen1 + srcLen2 - dstLen1};
|
|
} else {
|
|
// dstBuf1 is bigger enough to hold all the data from src.
|
|
cp2 = {cp1.dst + cp1.len, srcBuf2, srcLen2};
|
|
|
|
// No need to copy more data, thus no need to update cp3.
|
|
}
|
|
} else { // srcLen1 > dstLen1
|
|
cp1 = {dstBuf1, srcBuf1, dstLen1};
|
|
cp2 = {dstBuf2, cp1.src + cp1.len, srcLen1 - dstLen1};
|
|
cp3 = {cp2.dst + cp2.len, srcBuf2, srcLen2};
|
|
}
|
|
|
|
if (cp1.len > 0) {
|
|
DCHECK(cp1.dst);
|
|
DCHECK(cp1.src);
|
|
std::memcpy(cp1.dst, cp1.src, cp1.len);
|
|
}
|
|
|
|
if (cp2.len > 0) {
|
|
DCHECK(cp2.dst);
|
|
DCHECK(cp2.src);
|
|
std::memcpy(cp2.dst, cp2.src, cp2.len);
|
|
}
|
|
|
|
if (cp3.len > 0) {
|
|
DCHECK(cp3.dst);
|
|
DCHECK(cp3.src);
|
|
std::memcpy(cp3.dst, cp3.src, cp3.len);
|
|
}
|
|
}
|
|
|
|
} // namespace audio_proxy::service
|