зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1872003 uninline AudioSegment::Resample() to remove MediaTrackGraph.h include r=padenot
Depends on D197876 Differential Revision: https://phabricator.services.mozilla.com/D197877
This commit is contained in:
Родитель
6fb77931ec
Коммит
0263de1ada
|
@ -6,6 +6,7 @@
|
|||
#include "AudioSegment.h"
|
||||
#include "AudioMixer.h"
|
||||
#include "AudioChannelFormat.h"
|
||||
#include "MediaTrackGraph.h" // for nsAutoRefTraits<SpeexResamplerState>
|
||||
#include <speex/speex_resampler.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -30,6 +31,64 @@ void AudioSegment::ApplyVolume(float aVolume) {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AudioSegment::Resample(nsAutoRef<SpeexResamplerState>& aResampler,
|
||||
uint32_t* aResamplerChannelCount, uint32_t aInRate,
|
||||
uint32_t aOutRate) {
|
||||
mDuration = 0;
|
||||
|
||||
for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
|
||||
AutoTArray<nsTArray<T>, GUESS_AUDIO_CHANNELS> output;
|
||||
AutoTArray<const T*, GUESS_AUDIO_CHANNELS> bufferPtrs;
|
||||
AudioChunk& c = *ci;
|
||||
// If this chunk is null, don't bother resampling, just alter its duration
|
||||
if (c.IsNull()) {
|
||||
c.mDuration = (c.mDuration * aOutRate) / aInRate;
|
||||
mDuration += c.mDuration;
|
||||
continue;
|
||||
}
|
||||
uint32_t channels = c.mChannelData.Length();
|
||||
// This might introduce a discontinuity, but a channel count change in the
|
||||
// middle of a stream is not that common. This also initializes the
|
||||
// resampler as late as possible.
|
||||
if (channels != *aResamplerChannelCount) {
|
||||
SpeexResamplerState* state =
|
||||
speex_resampler_init(channels, aInRate, aOutRate,
|
||||
SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
|
||||
MOZ_ASSERT(state);
|
||||
aResampler.own(state);
|
||||
*aResamplerChannelCount = channels;
|
||||
}
|
||||
output.SetLength(channels);
|
||||
bufferPtrs.SetLength(channels);
|
||||
uint32_t inFrames = c.mDuration;
|
||||
// Round up to allocate; the last frame may not be used.
|
||||
NS_ASSERTION((UINT64_MAX - aInRate + 1) / c.mDuration >= aOutRate,
|
||||
"Dropping samples");
|
||||
uint32_t outSize =
|
||||
(static_cast<uint64_t>(c.mDuration) * aOutRate + aInRate - 1) / aInRate;
|
||||
for (uint32_t i = 0; i < channels; i++) {
|
||||
T* out = output[i].AppendElements(outSize);
|
||||
uint32_t outFrames = outSize;
|
||||
|
||||
const T* in = static_cast<const T*>(c.mChannelData[i]);
|
||||
dom::WebAudioUtils::SpeexResamplerProcess(aResampler.get(), i, in,
|
||||
&inFrames, out, &outFrames);
|
||||
MOZ_ASSERT(inFrames == c.mDuration);
|
||||
|
||||
bufferPtrs[i] = out;
|
||||
output[i].SetLength(outFrames);
|
||||
}
|
||||
MOZ_ASSERT(channels > 0);
|
||||
c.mDuration = output[0].Length();
|
||||
c.mBuffer = new mozilla::SharedChannelArrayBuffer<T>(std::move(output));
|
||||
for (uint32_t i = 0; i < channels; i++) {
|
||||
c.mChannelData[i] = bufferPtrs[i];
|
||||
}
|
||||
mDuration += c.mDuration;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSegment::ResampleChunks(nsAutoRef<SpeexResamplerState>& aResampler,
|
||||
uint32_t* aResamplerChannelCount,
|
||||
uint32_t aInRate, uint32_t aOutRate) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define MOZILLA_AUDIOSEGMENT_H_
|
||||
|
||||
#include <speex/speex_resampler.h>
|
||||
#include "MediaTrackGraph.h"
|
||||
#include "MediaSegment.h"
|
||||
#include "AudioSampleFormat.h"
|
||||
#include "AudioChannelFormat.h"
|
||||
|
@ -337,65 +336,6 @@ class AudioSegment : public MediaSegmentBase<AudioSegment, AudioChunk> {
|
|||
// function finds a chunk with more channels, `aResampler` is destroyed and a
|
||||
// new resampler is created, and `aResamplerChannelCount` is updated with the
|
||||
// new channel count value.
|
||||
template <typename T>
|
||||
void Resample(nsAutoRef<SpeexResamplerState>& aResampler,
|
||||
uint32_t* aResamplerChannelCount, uint32_t aInRate,
|
||||
uint32_t aOutRate) {
|
||||
mDuration = 0;
|
||||
|
||||
for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
|
||||
AutoTArray<nsTArray<T>, GUESS_AUDIO_CHANNELS> output;
|
||||
AutoTArray<const T*, GUESS_AUDIO_CHANNELS> bufferPtrs;
|
||||
AudioChunk& c = *ci;
|
||||
// If this chunk is null, don't bother resampling, just alter its duration
|
||||
if (c.IsNull()) {
|
||||
c.mDuration = (c.mDuration * aOutRate) / aInRate;
|
||||
mDuration += c.mDuration;
|
||||
continue;
|
||||
}
|
||||
uint32_t channels = c.mChannelData.Length();
|
||||
// This might introduce a discontinuity, but a channel count change in the
|
||||
// middle of a stream is not that common. This also initializes the
|
||||
// resampler as late as possible.
|
||||
if (channels != *aResamplerChannelCount) {
|
||||
SpeexResamplerState* state =
|
||||
speex_resampler_init(channels, aInRate, aOutRate,
|
||||
SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
|
||||
MOZ_ASSERT(state);
|
||||
aResampler.own(state);
|
||||
*aResamplerChannelCount = channels;
|
||||
}
|
||||
output.SetLength(channels);
|
||||
bufferPtrs.SetLength(channels);
|
||||
uint32_t inFrames = c.mDuration;
|
||||
// Round up to allocate; the last frame may not be used.
|
||||
NS_ASSERTION((UINT64_MAX - aInRate + 1) / c.mDuration >= aOutRate,
|
||||
"Dropping samples");
|
||||
uint32_t outSize =
|
||||
(static_cast<uint64_t>(c.mDuration) * aOutRate + aInRate - 1) /
|
||||
aInRate;
|
||||
for (uint32_t i = 0; i < channels; i++) {
|
||||
T* out = output[i].AppendElements(outSize);
|
||||
uint32_t outFrames = outSize;
|
||||
|
||||
const T* in = static_cast<const T*>(c.mChannelData[i]);
|
||||
dom::WebAudioUtils::SpeexResamplerProcess(aResampler.get(), i, in,
|
||||
&inFrames, out, &outFrames);
|
||||
MOZ_ASSERT(inFrames == c.mDuration);
|
||||
|
||||
bufferPtrs[i] = out;
|
||||
output[i].SetLength(outFrames);
|
||||
}
|
||||
MOZ_ASSERT(channels > 0);
|
||||
c.mDuration = output[0].Length();
|
||||
c.mBuffer = new mozilla::SharedChannelArrayBuffer<T>(std::move(output));
|
||||
for (uint32_t i = 0; i < channels; i++) {
|
||||
c.mChannelData[i] = bufferPtrs[i];
|
||||
}
|
||||
mDuration += c.mDuration;
|
||||
}
|
||||
}
|
||||
|
||||
void ResampleChunks(nsAutoRef<SpeexResamplerState>& aResampler,
|
||||
uint32_t* aResamplerChannelCount, uint32_t aInRate,
|
||||
uint32_t aOutRate);
|
||||
|
@ -509,6 +449,12 @@ class AudioSegment : public MediaSegmentBase<AudioSegment, AudioChunk> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void Resample(nsAutoRef<SpeexResamplerState>& aResampler,
|
||||
uint32_t* aResamplerChannelCount, uint32_t aInRate,
|
||||
uint32_t aOutRate);
|
||||
};
|
||||
|
||||
template <typename SrcT>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "AudioVerifier.h"
|
||||
#include "MediaEventSource.h"
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/ThreadSafeWeakPtr.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class AudioData;
|
|||
class VideoData;
|
||||
struct PlaybackInfoInit;
|
||||
class ProcessedMediaTrack;
|
||||
struct SharedDummyTrack;
|
||||
class TimeStamp;
|
||||
|
||||
template <class T>
|
||||
|
|
Загрузка…
Ссылка в новой задаче