Bug 1378070 - Update AudioConverter to use destination buffer. r?jya
MozReview-Commit-ID: KCheY0DCjh4
--- a/dom/media/AudioConverter.cpp
+++ b/dom/media/AudioConverter.cpp
@@ -60,16 +60,19 @@ AudioConverter::CanWorkInPlace() const
// perform any upsampling in place (e.g. if incoming rate >= outgoing rate)
return !needUpmix && (!needDownmix || canDownmixInPlace) &&
(!needResample || canResampleInPlace);
}
size_t
AudioConverter::ProcessInternal(void* aOut, const void* aIn, size_t aFrames)
{
+ if (!aFrames) {
+ return 0;
+ }
if (mIn.Channels() > mOut.Channels()) {
return DownmixAudio(aOut, aIn, aFrames);
} else if (mIn.Channels() < mOut.Channels()) {
return UpmixAudio(aOut, aIn, aFrames);
} else if (mIn.Layout() != mOut.Layout() && CanReorderAudio()) {
ReOrderInterleavedChannels(aOut, aIn, aFrames);
} else if (aIn != aOut) {
memmove(aOut, aIn, FramesOutToBytes(aFrames));
--- a/dom/media/AudioConverter.h
+++ b/dom/media/AudioConverter.h
@@ -126,23 +126,18 @@ public:
// Providing an empty buffer and resampling is expected, the resampler
// will be drained.
template <AudioConfig::SampleFormat Format, typename Value>
AudioDataBuffer<Format, Value> Process(AudioDataBuffer<Format, Value>&& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
AudioDataBuffer<Format, Value> buffer = Move(aBuffer);
if (CanWorkInPlace()) {
- size_t frames = SamplesInToFrames(buffer.Length());
- frames = ProcessInternal(buffer.Data(), buffer.Data(), frames);
- if (frames && mIn.Rate() != mOut.Rate()) {
- frames = ResampleAudio(buffer.Data(), buffer.Data(), frames);
- }
AlignedBuffer<Value> temp = buffer.Forget();
- temp.SetLength(FramesOutToSamples(frames));
+ Process(temp, temp.Data(), SamplesInToFrames(temp.Length()));
return AudioDataBuffer<Format, Value>(Move(temp));;
}
return Process(buffer);
}
template <AudioConfig::SampleFormat Format, typename Value>
AudioDataBuffer<Format, Value> Process(const AudioDataBuffer<Format, Value>& aBuffer)
{
@@ -191,16 +186,48 @@ public:
}
size_t frames = ProcessInternal(aBuffer, aBuffer, aFrames);
if (frames && mIn.Rate() != mOut.Rate()) {
frames = ResampleAudio(aBuffer, aBuffer, aFrames);
}
return frames;
}
+ template <typename Value>
+ size_t Process(AlignedBuffer<Value>& aOutBuffer, const Value* aInBuffer, size_t aFrames)
+ {
+ MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format());
+ MOZ_ASSERT((aFrames && aInBuffer) || !aFrames);
+ // Up/down mixing first
+ if (!aOutBuffer.SetLength(FramesOutToSamples(aFrames))) {
+ MOZ_ALWAYS_TRUE(aOutBuffer.SetLength(0));
+ return 0;
+ }
+ size_t frames = ProcessInternal(aOutBuffer.Data(), aInBuffer, aFrames);
+ MOZ_ASSERT(frames == aFrames);
+ // Check if resampling is needed
+ if (mIn.Rate() == mOut.Rate()) {
+ return frames;
+ }
+ // Prepare output in cases of drain or up-sampling
+ if ((!frames || mOut.Rate() > mIn.Rate()) &&
+ !aOutBuffer.SetLength(FramesOutToSamples(ResampleRecipientFrames(frames)))) {
+ MOZ_ALWAYS_TRUE(aOutBuffer.SetLength(0));
+ return 0;
+ }
+ if (!frames) {
+ frames = DrainResampler(aOutBuffer.Data());
+ } else {
+ frames = ResampleAudio(aOutBuffer.Data(), aInBuffer, frames);
+ }
+ // Update with the actual buffer length
+ MOZ_ALWAYS_TRUE(aOutBuffer.SetLength(FramesOutToSamples(frames)));
+ return frames;
+ }
+
bool CanWorkInPlace() const;
bool CanReorderAudio() const
{
return mIn.Layout().MappingTable(mOut.Layout());
}
const AudioConfig& InputConfig() const { return mIn; }
const AudioConfig& OutputConfig() const { return mOut; }