mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1890689 Change AudioRingBuffer::SetLengthBytes() to EnsureLengthBytes() r=pehrsons
This now provides reasonable behavior if shorter lengths should be passed. SetLengthBytes() did not move buffered data to within a shorter new length and would not update mWriteIndexhandle. TestAudioRingBuffer.EnsureLengthShorter would crash with Assertion failure: aStart <= len && (aLength == dynamic_extent || (aStart + aLength <= len)), at obj/dist/include/mozilla/Span.h:660 SetLengthBytes() was called with shorter lengths only on memory allocation failure. This was not necessary. The warning is adjusted to indicate the size of the allocation attempted. Depends on D207659 Differential Revision: https://phabricator.services.mozilla.com/D207660
This commit is contained in:
parent
9a1ff71623
commit
6f843408fd
@ -270,10 +270,13 @@ class RingBuffer final {
|
|||||||
* Re-allocates memory if a larger buffer is requested than what is already
|
* Re-allocates memory if a larger buffer is requested than what is already
|
||||||
* allocated.
|
* allocated.
|
||||||
*/
|
*/
|
||||||
bool SetLengthBytes(uint32_t aLengthBytes) {
|
bool EnsureLengthBytes(uint32_t aLengthBytes) {
|
||||||
MOZ_ASSERT(aLengthBytes % sizeof(T) == 0,
|
MOZ_ASSERT(aLengthBytes % sizeof(T) == 0,
|
||||||
"Length in bytes is not a whole number of samples");
|
"Length in bytes is not a whole number of samples");
|
||||||
|
|
||||||
|
if (mMemoryBuffer.Length() >= aLengthBytes) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
uint32_t lengthSamples = aLengthBytes / sizeof(T);
|
uint32_t lengthSamples = aLengthBytes / sizeof(T);
|
||||||
uint32_t oldLengthSamples = Capacity();
|
uint32_t oldLengthSamples = Capacity();
|
||||||
uint32_t availableRead = AvailableRead();
|
uint32_t availableRead = AvailableRead();
|
||||||
@ -530,14 +533,17 @@ uint32_t AudioRingBuffer::Clear() {
|
|||||||
return mPtr->mFloatRingBuffer->Clear();
|
return mPtr->mFloatRingBuffer->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioRingBuffer::SetLengthBytes(uint32_t aLengthBytes) {
|
bool AudioRingBuffer::EnsureLengthBytes(uint32_t aLengthBytes) {
|
||||||
if (mPtr->mFloatRingBuffer) {
|
if (mPtr->mFloatRingBuffer) {
|
||||||
return mPtr->mFloatRingBuffer->SetLengthBytes(aLengthBytes);
|
return mPtr->mFloatRingBuffer->EnsureLengthBytes(aLengthBytes);
|
||||||
}
|
}
|
||||||
if (mPtr->mIntRingBuffer) {
|
if (mPtr->mIntRingBuffer) {
|
||||||
return mPtr->mIntRingBuffer->SetLengthBytes(aLengthBytes);
|
return mPtr->mIntRingBuffer->EnsureLengthBytes(aLengthBytes);
|
||||||
}
|
}
|
||||||
if (mPtr->mBackingBuffer) {
|
if (mPtr->mBackingBuffer) {
|
||||||
|
if (mPtr->mBackingBuffer->Length() >= aLengthBytes) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return mPtr->mBackingBuffer->SetLength(aLengthBytes);
|
return mPtr->mBackingBuffer->SetLength(aLengthBytes);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT_UNREACHABLE("Unexpected");
|
MOZ_ASSERT_UNREACHABLE("Unexpected");
|
||||||
|
@ -93,12 +93,12 @@ class AudioRingBuffer final {
|
|||||||
uint32_t Clear();
|
uint32_t Clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the length of the ring buffer in bytes. Must be divisible by the sample
|
* Increase the ring buffer size if necessary to at least the specified length
|
||||||
* size. Will not deallocate memory if the underlying buffer is large enough.
|
* in bytes. Must be divisible by the sample size.
|
||||||
* Returns false if setting the length requires allocating memory and the
|
* Will not deallocate memory if the underlying buffer is large enough.
|
||||||
* allocation fails.
|
* Returns false if memory allocation is required and fails.
|
||||||
*/
|
*/
|
||||||
bool SetLengthBytes(uint32_t aLengthBytes);
|
bool EnsureLengthBytes(uint32_t aLengthBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of samples this buffer can hold.
|
* Return the number of samples this buffer can hold.
|
||||||
|
@ -268,11 +268,12 @@ class DynamicResampler final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
duration = std::min(cap, duration);
|
duration = std::min(cap, duration);
|
||||||
|
const uint32_t newSizeInFrames =
|
||||||
|
static_cast<uint32_t>(duration.ToTicksAtRate(mInRate));
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (auto& b : mInternalInBuffer) {
|
for (auto& b : mInternalInBuffer) {
|
||||||
success = success &&
|
success = success && b.EnsureLengthBytes(sampleSize * newSizeInFrames);
|
||||||
b.SetLengthBytes(sampleSize * duration.ToTicksAtRate(mInRate));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
@ -281,16 +282,11 @@ class DynamicResampler final {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t sizeInFrames =
|
|
||||||
static_cast<uint32_t>(mSetBufferDuration.ToTicksAtRate(mInRate));
|
|
||||||
// Allocating an input buffer failed. We stick with the old buffer size.
|
// Allocating an input buffer failed. We stick with the old buffer size.
|
||||||
NS_WARNING(nsPrintfCString("Failed to allocate a buffer of %u bytes (%u "
|
NS_WARNING(nsPrintfCString("Failed to allocate a buffer of %u bytes (%u "
|
||||||
"frames). Expect glitches.",
|
"frames). Expect glitches.",
|
||||||
sampleSize * sizeInFrames, sizeInFrames)
|
sampleSize * newSizeInFrames, newSizeInFrames)
|
||||||
.get());
|
.get());
|
||||||
for (auto& b : mInternalInBuffer) {
|
|
||||||
MOZ_ALWAYS_TRUE(b.SetLengthBytes(sampleSize * sizeInFrames));
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1094,7 +1094,7 @@ TEST(TestAudioRingBuffer, PrependSilenceNoWrapShort)
|
|||||||
EXPECT_THAT(out, ElementsAre(2, 3, 4, 5, 0, 0, 6, 7));
|
EXPECT_THAT(out, ElementsAre(2, 3, 4, 5, 0, 0, 6, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestAudioRingBuffer, SetLengthBytesNoWrapFloat)
|
TEST(TestAudioRingBuffer, EnsureLengthBytesNoWrapFloat)
|
||||||
{
|
{
|
||||||
AudioRingBuffer rb(6 * sizeof(float));
|
AudioRingBuffer rb(6 * sizeof(float));
|
||||||
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
||||||
@ -1106,7 +1106,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesNoWrapFloat)
|
|||||||
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
EXPECT_EQ(rb.Capacity(), 6u);
|
EXPECT_EQ(rb.Capacity(), 6u);
|
||||||
|
|
||||||
EXPECT_TRUE(rb.SetLengthBytes(11 * sizeof(float)));
|
EXPECT_TRUE(rb.EnsureLengthBytes(11 * sizeof(float)));
|
||||||
float out[10] = {};
|
float out[10] = {};
|
||||||
rv = rb.Read(Span(out, 10));
|
rv = rb.Read(Span(out, 10));
|
||||||
EXPECT_EQ(rv, 5u);
|
EXPECT_EQ(rv, 5u);
|
||||||
@ -1116,7 +1116,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesNoWrapFloat)
|
|||||||
EXPECT_THAT(out, ElementsAre(.1, .2, .3, .4, .5, 0, 0, 0, 0, 0));
|
EXPECT_THAT(out, ElementsAre(.1, .2, .3, .4, .5, 0, 0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestAudioRingBuffer, SetLengthBytesNoWrapShort)
|
TEST(TestAudioRingBuffer, EnsureLengthBytesNoWrapShort)
|
||||||
{
|
{
|
||||||
AudioRingBuffer rb(6 * sizeof(short));
|
AudioRingBuffer rb(6 * sizeof(short));
|
||||||
rb.SetSampleFormat(AUDIO_FORMAT_S16);
|
rb.SetSampleFormat(AUDIO_FORMAT_S16);
|
||||||
@ -1128,7 +1128,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesNoWrapShort)
|
|||||||
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
EXPECT_EQ(rb.Capacity(), 6u);
|
EXPECT_EQ(rb.Capacity(), 6u);
|
||||||
|
|
||||||
EXPECT_TRUE(rb.SetLengthBytes(11 * sizeof(short)));
|
EXPECT_TRUE(rb.EnsureLengthBytes(11 * sizeof(short)));
|
||||||
short out[10] = {};
|
short out[10] = {};
|
||||||
rv = rb.Read(Span(out, 10));
|
rv = rb.Read(Span(out, 10));
|
||||||
EXPECT_EQ(rv, 5u);
|
EXPECT_EQ(rv, 5u);
|
||||||
@ -1138,7 +1138,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesNoWrapShort)
|
|||||||
EXPECT_THAT(out, ElementsAre(1, 2, 3, 4, 5, 0, 0, 0, 0, 0));
|
EXPECT_THAT(out, ElementsAre(1, 2, 3, 4, 5, 0, 0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestAudioRingBuffer, SetLengthBytesWrap1PartFloat)
|
TEST(TestAudioRingBuffer, EnsureLengthBytesWrap1PartFloat)
|
||||||
{
|
{
|
||||||
AudioRingBuffer rb(6 * sizeof(float));
|
AudioRingBuffer rb(6 * sizeof(float));
|
||||||
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
||||||
@ -1158,7 +1158,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap1PartFloat)
|
|||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
|
|
||||||
EXPECT_TRUE(rb.SetLengthBytes(11 * sizeof(float)));
|
EXPECT_TRUE(rb.EnsureLengthBytes(11 * sizeof(float)));
|
||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 5u);
|
EXPECT_EQ(rb.AvailableWrite(), 5u);
|
||||||
|
|
||||||
@ -1175,7 +1175,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap1PartFloat)
|
|||||||
EXPECT_THAT(out, ElementsAre(.1, .2, .3, .4, .5, .6, .7, 0, 0, 0));
|
EXPECT_THAT(out, ElementsAre(.1, .2, .3, .4, .5, .6, .7, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestAudioRingBuffer, SetLengthBytesWrap1PartShort)
|
TEST(TestAudioRingBuffer, EnsureLengthBytesWrap1PartShort)
|
||||||
{
|
{
|
||||||
AudioRingBuffer rb(6 * sizeof(short));
|
AudioRingBuffer rb(6 * sizeof(short));
|
||||||
rb.SetSampleFormat(AUDIO_FORMAT_S16);
|
rb.SetSampleFormat(AUDIO_FORMAT_S16);
|
||||||
@ -1195,7 +1195,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap1PartShort)
|
|||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
|
|
||||||
EXPECT_TRUE(rb.SetLengthBytes(11 * sizeof(short)));
|
EXPECT_TRUE(rb.EnsureLengthBytes(11 * sizeof(short)));
|
||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 5u);
|
EXPECT_EQ(rb.AvailableWrite(), 5u);
|
||||||
|
|
||||||
@ -1212,7 +1212,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap1PartShort)
|
|||||||
EXPECT_THAT(out, ElementsAre(1, 2, 3, 4, 5, 6, 7, 0, 0, 0));
|
EXPECT_THAT(out, ElementsAre(1, 2, 3, 4, 5, 6, 7, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestAudioRingBuffer, SetLengthBytesWrap2PartsFloat)
|
TEST(TestAudioRingBuffer, EnsureLengthBytesWrap2PartsFloat)
|
||||||
{
|
{
|
||||||
AudioRingBuffer rb(6 * sizeof(float));
|
AudioRingBuffer rb(6 * sizeof(float));
|
||||||
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
||||||
@ -1232,7 +1232,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap2PartsFloat)
|
|||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
|
|
||||||
EXPECT_TRUE(rb.SetLengthBytes(8 * sizeof(float)));
|
EXPECT_TRUE(rb.EnsureLengthBytes(8 * sizeof(float)));
|
||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 2u);
|
EXPECT_EQ(rb.AvailableWrite(), 2u);
|
||||||
|
|
||||||
@ -1249,7 +1249,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap2PartsFloat)
|
|||||||
EXPECT_THAT(out, ElementsAre(.1, .2, .3, .4, .5, .6, .7, 0));
|
EXPECT_THAT(out, ElementsAre(.1, .2, .3, .4, .5, .6, .7, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestAudioRingBuffer, SetLengthBytesWrap2PartsShort)
|
TEST(TestAudioRingBuffer, EnsureLengthBytesWrap2PartsShort)
|
||||||
{
|
{
|
||||||
AudioRingBuffer rb(6 * sizeof(short));
|
AudioRingBuffer rb(6 * sizeof(short));
|
||||||
rb.SetSampleFormat(AUDIO_FORMAT_S16);
|
rb.SetSampleFormat(AUDIO_FORMAT_S16);
|
||||||
@ -1269,7 +1269,7 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap2PartsShort)
|
|||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
|
|
||||||
EXPECT_TRUE(rb.SetLengthBytes(8 * sizeof(short)));
|
EXPECT_TRUE(rb.EnsureLengthBytes(8 * sizeof(short)));
|
||||||
EXPECT_EQ(rb.AvailableRead(), 5u);
|
EXPECT_EQ(rb.AvailableRead(), 5u);
|
||||||
EXPECT_EQ(rb.AvailableWrite(), 2u);
|
EXPECT_EQ(rb.AvailableWrite(), 2u);
|
||||||
|
|
||||||
@ -1285,3 +1285,29 @@ TEST(TestAudioRingBuffer, SetLengthBytesWrap2PartsShort)
|
|||||||
EXPECT_EQ(rb.Capacity(), 8u);
|
EXPECT_EQ(rb.Capacity(), 8u);
|
||||||
EXPECT_THAT(out, ElementsAre(1, 2, 3, 4, 5, 6, 7, 0));
|
EXPECT_THAT(out, ElementsAre(1, 2, 3, 4, 5, 6, 7, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestAudioRingBuffer, EnsureLengthShorter)
|
||||||
|
{
|
||||||
|
AudioRingBuffer rb(5 * sizeof(float));
|
||||||
|
rb.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
|
||||||
|
|
||||||
|
float in[5] = {.1, .2, .3, .4, .5};
|
||||||
|
EXPECT_EQ(rb.Write(Span(in, 5)), 4u);
|
||||||
|
EXPECT_EQ(rb.AvailableRead(), 4u);
|
||||||
|
EXPECT_EQ(rb.AvailableWrite(), 0u);
|
||||||
|
EXPECT_EQ(rb.Capacity(), 5u);
|
||||||
|
|
||||||
|
float out[5] = {};
|
||||||
|
EXPECT_EQ(rb.Read(Span(out, 3)), 3u);
|
||||||
|
EXPECT_THAT(out, ElementsAre(.1, .2, .3, 0, 0));
|
||||||
|
EXPECT_EQ(rb.AvailableRead(), 1u);
|
||||||
|
EXPECT_EQ(rb.AvailableWrite(), 3u);
|
||||||
|
|
||||||
|
EXPECT_TRUE(rb.EnsureLengthBytes(3 * sizeof(float)));
|
||||||
|
EXPECT_EQ(rb.AvailableRead(), 1u);
|
||||||
|
EXPECT_EQ(rb.AvailableWrite(), 3u);
|
||||||
|
EXPECT_EQ(rb.Capacity(), 5u);
|
||||||
|
EXPECT_EQ(rb.Write(Span(in, 5)), 3u);
|
||||||
|
EXPECT_EQ(rb.Read(Span(out, 5)), 4u);
|
||||||
|
EXPECT_THAT(out, ElementsAre(.4, .1, .2, .3, 0));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user