AudioDriftCorrection.h (3189B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef DOM_MEDIA_DRIFTCONTROL_AUDIODRIFTCORRECTION_H_ 7 #define DOM_MEDIA_DRIFTCONTROL_AUDIODRIFTCORRECTION_H_ 8 9 #include "AudioSegment.h" 10 #include "TimeUnits.h" 11 12 namespace mozilla { 13 14 class AudioResampler; 15 class DriftController; 16 17 /** 18 * Correct the drift between two independent clocks, the source, and the target 19 * clock. The target clock is the master clock so the correction syncs the drift 20 * of the source clock to the target. The nominal sampling rates of source and 21 * target must be provided. 22 * 23 * It works with AudioSegment in order to be able to be used from the 24 * MediaTrackGraph/MediaTrack. The audio buffers are pre-allocated so the only 25 * new allocation taking place during operation happens if the input buffer 26 * outgrows the memory allocated. The preallocation capacity is 100ms for input 27 * and 100ms for output. The class consists of DriftController and 28 * AudioResampler check there for more details. 29 * 30 * The class is not thread-safe. The construction can happen in any thread but 31 * the member method must be used in a single thread that can be different than 32 * the construction thread. Appropriate for being used in the high priority 33 * audio thread. 34 */ 35 class AudioDriftCorrection final { 36 public: 37 AudioDriftCorrection(uint32_t aSourceRate, uint32_t aTargetRate, 38 const PrincipalHandle& aPrincipalHandle); 39 40 ~AudioDriftCorrection(); 41 42 /** 43 * A segment of input data (in the source rate) and a number of requested 44 * output frames (in the target rate) are provided, and a segment (in the 45 * target rate) of drift-corrected data is returned. The input is buffered 46 * internally so some latency exists. The returned AudioSegment may not be 47 * long-lived because any point in the internal buffer gets reused every 48 * 100ms. If not enough data is available in the input buffer to produce 49 * the requested number of output frames, the input buffer is drained and 50 * a smaller segment than requested is returned. 51 */ 52 AudioSegment RequestFrames(const AudioSegment& aInput, 53 uint32_t aOutputFrames); 54 55 uint32_t CurrentBuffering() const; 56 57 uint32_t BufferSize() const; 58 59 uint32_t NumCorrectionChanges() const; 60 61 uint32_t NumUnderruns() const { return mNumUnderruns; } 62 63 void SetSourceLatency(media::TimeUnit aSourceLatency); 64 65 const uint32_t mTargetRate; 66 const media::TimeUnit mLatencyReductionTimeLimit = 67 media::TimeUnit(15, 1).ToBase(mTargetRate); 68 69 private: 70 void SetDesiredBuffering(media::TimeUnit aDesiredBuffering); 71 72 media::TimeUnit mSourceLatency = media::TimeUnit::Zero(); 73 media::TimeUnit mDesiredBuffering = media::TimeUnit::Zero(); 74 uint32_t mNumUnderruns = 0; 75 bool mIsHandlingUnderrun = false; 76 const UniquePtr<DriftController> mDriftController; 77 const UniquePtr<AudioResampler> mResampler; 78 }; 79 } // namespace mozilla 80 #endif // DOM_MEDIA_DRIFTCONTROL_AUDIODRIFTCORRECTION_H_