/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef DOM_MEDIA_DRIFTCONTROL_AUDIODRIFTCORRECTION_H_ #define DOM_MEDIA_DRIFTCONTROL_AUDIODRIFTCORRECTION_H_ #include "AudioSegment.h" #include "TimeUnits.h" namespace mozilla { class AudioResampler; class DriftController; /** * Correct the drift between two independent clocks, the source, and the target * clock. The target clock is the master clock so the correction syncs the drift * of the source clock to the target. The nominal sampling rates of source and * target must be provided. * * It works with AudioSegment in order to be able to be used from the * MediaTrackGraph/MediaTrack. The audio buffers are pre-allocated so the only * new allocation taking place during operation happens if the input buffer * outgrows the memory allocated. The preallocation capacity is 100ms for input * and 100ms for output. The class consists of DriftController and * AudioResampler check there for more details. * * The class is not thread-safe. The construction can happen in any thread but * the member method must be used in a single thread that can be different than * the construction thread. Appropriate for being used in the high priority * audio thread. */ class AudioDriftCorrection final { public: AudioDriftCorrection(uint32_t aSourceRate, uint32_t aTargetRate, const PrincipalHandle& aPrincipalHandle); ~AudioDriftCorrection(); /** * A segment of input data (in the source rate) and a number of requested * output frames (in the target rate) are provided, and a segment (in the * target rate) of drift-corrected data is returned. The input is buffered * internally so some latency exists. The returned AudioSegment may not be * long-lived because any point in the internal buffer gets reused every * 100ms. If not enough data is available in the input buffer to produce * the requested number of output frames, the input buffer is drained and * a smaller segment than requested is returned. */ AudioSegment RequestFrames(const AudioSegment& aInput, uint32_t aOutputFrames); uint32_t CurrentBuffering() const; uint32_t BufferSize() const; uint32_t NumCorrectionChanges() const; uint32_t NumUnderruns() const { return mNumUnderruns; } void SetSourceLatency(media::TimeUnit aSourceLatency); const uint32_t mTargetRate; const media::TimeUnit mLatencyReductionTimeLimit = media::TimeUnit(15, 1).ToBase(mTargetRate); private: void SetDesiredBuffering(media::TimeUnit aDesiredBuffering); media::TimeUnit mSourceLatency = media::TimeUnit::Zero(); media::TimeUnit mDesiredBuffering = media::TimeUnit::Zero(); uint32_t mNumUnderruns = 0; bool mIsHandlingUnderrun = false; const UniquePtr mDriftController; const UniquePtr mResampler; }; } // namespace mozilla #endif // DOM_MEDIA_DRIFTCONTROL_AUDIODRIFTCORRECTION_H_