diff options
author | Torne (Richard Coles) <torne@google.com> | 2014-03-18 10:20:56 +0000 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2014-03-18 10:20:56 +0000 |
commit | a1401311d1ab56c4ed0a474bd38c108f75cb0cd9 (patch) | |
tree | 3437151d9ae1ce20a1e53a0d98c19ca01c786394 /media/base/audio_splicer.h | |
parent | af5066f1e36c6579e74752647e6c584438f80f94 (diff) | |
download | chromium_org-a1401311d1ab56c4ed0a474bd38c108f75cb0cd9.tar.gz |
Merge from Chromium at DEPS revision 257591
This commit was generated by merge_to_master.py.
Change-Id: I0010df2ec3fbb5d4947cd026de2feb150ce7a6b5
Diffstat (limited to 'media/base/audio_splicer.h')
-rw-r--r-- | media/base/audio_splicer.h | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/media/base/audio_splicer.h b/media/base/audio_splicer.h index 50445b2d54..c20ecc09a7 100644 --- a/media/base/audio_splicer.h +++ b/media/base/audio_splicer.h @@ -5,52 +5,85 @@ #ifndef MEDIA_BASE_AUDIO_SPLICER_H_ #define MEDIA_BASE_AUDIO_SPLICER_H_ -#include <deque> - #include "base/memory/ref_counted.h" -#include "media/base/audio_timestamp_helper.h" +#include "base/memory/scoped_ptr.h" +#include "base/time/time.h" #include "media/base/media_export.h" namespace media { class AudioBuffer; -class AudioDecoderConfig; +class AudioBus; +class AudioStreamSanitizer; // Helper class that handles filling gaps and resolving overlaps. class MEDIA_EXPORT AudioSplicer { public: - AudioSplicer(int samples_per_second); + explicit AudioSplicer(int samples_per_second); ~AudioSplicer(); - // Resets the splicer state by clearing the output buffers queue, - // and resetting the timestamp helper. + // Resets the splicer state by clearing the output buffers queue and resetting + // the timestamp helper. void Reset(); // Adds a new buffer full of samples or end of stream buffer to the splicer. - // Returns true if the buffer was accepted. False is returned if an error + // Returns true if the buffer was accepted. False is returned if an error // occurred. bool AddInput(const scoped_refptr<AudioBuffer>& input); // Returns true if the splicer has a buffer to return. bool HasNextBuffer() const; - // Removes the next buffer from the output buffer queue and returns it. - // This should only be called if HasNextBuffer() returns true. + // Removes the next buffer from the output buffer queue and returns it; this + // should only be called if HasNextBuffer() returns true. scoped_refptr<AudioBuffer> GetNextBuffer(); - private: - void AddOutputBuffer(const scoped_refptr<AudioBuffer>& buffer); - - AudioTimestampHelper output_timestamp_helper_; + // Indicates that overlapping buffers are coming up and should be crossfaded. + // Once set, all buffers encountered after |splice_timestamp| will be queued + // internally until at least 5ms of overlapping buffers are received (or end + // of stream, whichever comes first). + void SetSpliceTimestamp(base::TimeDelta splice_timestamp); - // Minimum gap size needed before the splicer will take action to - // fill a gap. This avoids periodically inserting and then dropping samples - // when the buffer timestamps are slightly off because of timestamp rounding - // in the source content. Unit is frames. - int min_gap_size_; - - std::deque<scoped_refptr<AudioBuffer> > output_buffers_; - bool received_end_of_stream_; + private: + friend class AudioSplicerTest; + + // Extracts frames to be crossfaded from |pre_splice_sanitizer_|. Transfers + // all frames before |splice_timestamp_| into |output_sanitizer_| and drops + // frames outside of the crossfade duration. + // + // The size of the returned AudioBus is the crossfade duration in frames. + // Crossfade duration is calculated based on the number of frames available + // after |splice_timestamp_| in each sanitizer and capped by + // |max_crossfade_duration_|. + // + // |pre_splice_sanitizer_| will be empty after this operation. + scoped_ptr<AudioBus> ExtractCrossfadeFromPreSplice(); + + // Crossfades |pre_splice_bus->frames()| frames from |post_splice_sanitizer_| + // with those from |pre_splice_bus|. Adds the crossfaded buffer to + // |output_sanitizer_| along with all buffers in |post_splice_sanitizer_|. + // + // |post_splice_sanitizer_| will be empty after this operation. + void CrossfadePostSplice(scoped_ptr<AudioBus> pre_splice_bus); + + const base::TimeDelta max_crossfade_duration_; + base::TimeDelta splice_timestamp_; + + // The various sanitizers for each stage of the crossfade process. Buffers in + // |output_sanitizer_| are immediately available for consumption by external + // callers. + // + // Overlapped buffers go into the |pre_splice_sanitizer_| while overlapping + // buffers go into the |post_splice_sanitizer_|. Once enough buffers for + // crossfading are received the pre and post sanitizers are drained into + // |output_sanitizer_| by the two ExtractCrossfadeFromXXX methods above. + // + // |pre_splice_sanitizer_| is not constructed until the first splice frame is + // encountered. At which point it is constructed based on the timestamp state + // of |output_sanitizer_|. It is destructed once the splice is finished. + scoped_ptr<AudioStreamSanitizer> output_sanitizer_; + scoped_ptr<AudioStreamSanitizer> pre_splice_sanitizer_; + scoped_ptr<AudioStreamSanitizer> post_splice_sanitizer_; DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSplicer); }; |