| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef MEDIA_BASE_AUDIO_SPLICER_H_ | |
| 6 #define MEDIA_BASE_AUDIO_SPLICER_H_ | |
| 7 | |
| 8 #include <memory> | |
| 9 | |
| 10 #include "base/macros.h" | |
| 11 #include "base/memory/ref_counted.h" | |
| 12 #include "base/time/time.h" | |
| 13 #include "media/base/audio_parameters.h" | |
| 14 #include "media/base/media_export.h" | |
| 15 #include "media/base/timestamp_constants.h" | |
| 16 | |
| 17 namespace media { | |
| 18 | |
| 19 class AudioBuffer; | |
| 20 class AudioBus; | |
| 21 class AudioStreamSanitizer; | |
| 22 class MediaLog; | |
| 23 | |
| 24 // Helper class that handles filling gaps and resolving overlaps. | |
| 25 class MEDIA_EXPORT AudioSplicer { | |
| 26 public: | |
| 27 AudioSplicer(int samples_per_second, | |
| 28 const scoped_refptr<MediaLog>& media_log); | |
| 29 ~AudioSplicer(); | |
| 30 | |
| 31 enum { | |
| 32 // The number of ms to crossfade before trimming when buffers overlap. | |
| 33 kCrossfadeDurationInMilliseconds = 5, | |
| 34 | |
| 35 // Largest gap or overlap allowed between buffers. Anything larger than | |
| 36 // this will trigger an error. This is an arbitrary value, but the initial | |
| 37 // selection of 50ms roughly represents the duration of 2 compressed AAC or | |
| 38 // MP3 frames. | |
| 39 kMaxTimeDeltaInMilliseconds = 50, | |
| 40 }; | |
| 41 | |
| 42 // Resets the splicer state by clearing the output buffers queue and resetting | |
| 43 // the timestamp helper. | |
| 44 void Reset(); | |
| 45 | |
| 46 // Adds a new buffer full of samples or end of stream buffer to the splicer. | |
| 47 // Returns true if the buffer was accepted. False is returned if an error | |
| 48 // occurred. | |
| 49 bool AddInput(const scoped_refptr<AudioBuffer>& input); | |
| 50 | |
| 51 // Returns true if the splicer has a buffer to return. | |
| 52 bool HasNextBuffer() const; | |
| 53 | |
| 54 // Removes the next buffer from the output buffer queue and returns it; this | |
| 55 // should only be called if HasNextBuffer() returns true. | |
| 56 scoped_refptr<AudioBuffer> GetNextBuffer(); | |
| 57 | |
| 58 // Indicates an upcoming splice point. All buffers overlapping or after the | |
| 59 // |splice_timestamp| will be considered as "before the splice." Clients must | |
| 60 // then call SetSpliceTimestamp(kNoTimestamp) to signal that future buffers | |
| 61 // should be considered as "after the splice." | |
| 62 // | |
| 63 // Once |kCrossfadeDurationInMilliseconds| of buffers "after the splice" or | |
| 64 // end of stream has been received, the "after" buffers will be crossfaded | |
| 65 // with all "before" buffers which overlap them. "before" buffers outside | |
| 66 // of the overlap range will be discarded. | |
| 67 void SetSpliceTimestamp(base::TimeDelta splice_timestamp); | |
| 68 | |
| 69 private: | |
| 70 friend class AudioSplicerTest; | |
| 71 | |
| 72 // Extracts frames to be crossfaded from |pre_splice_sanitizer_|. Transfers | |
| 73 // all frames before |splice_timestamp_| into |output_sanitizer_| and drops | |
| 74 // frames outside of the crossfade duration. | |
| 75 // | |
| 76 // The size of the returned AudioBus is the crossfade duration in frames. | |
| 77 // Crossfade duration is calculated based on the number of frames available | |
| 78 // after |splice_timestamp_| in each sanitizer and capped by | |
| 79 // |max_crossfade_duration_|. | |
| 80 // | |
| 81 // |pre_splice_sanitizer_| will be empty after this operation. | |
| 82 std::unique_ptr<AudioBus> ExtractCrossfadeFromPreSplice( | |
| 83 scoped_refptr<AudioBuffer>* crossfade_buffer); | |
| 84 | |
| 85 // Crossfades |pre_splice_bus->frames()| frames from | |
| 86 // |post_splice_sanitizer_| | |
| 87 // with those from |pre_splice_bus|. Adds the crossfaded buffer to | |
| 88 // |output_sanitizer_| along with all buffers in |post_splice_sanitizer_|. | |
| 89 // | |
| 90 // |post_splice_sanitizer_| will be empty after this operation. | |
| 91 void CrossfadePostSplice(std::unique_ptr<AudioBus> pre_splice_bus, | |
| 92 const scoped_refptr<AudioBuffer>& crossfade_buffer); | |
| 93 | |
| 94 // Reset the splice and splice end timestamps. | |
| 95 void reset_splice_timestamps() { | |
| 96 splice_timestamp_ = max_splice_end_timestamp_ = kNoTimestamp; | |
| 97 } | |
| 98 | |
| 99 const base::TimeDelta max_crossfade_duration_; | |
| 100 base::TimeDelta splice_timestamp_; | |
| 101 base::TimeDelta max_splice_end_timestamp_; | |
| 102 | |
| 103 // The various sanitizers for each stage of the crossfade process. Buffers in | |
| 104 // |output_sanitizer_| are immediately available for consumption by external | |
| 105 // callers. | |
| 106 // | |
| 107 // Overlapped buffers go into the |pre_splice_sanitizer_| while overlapping | |
| 108 // buffers go into the |post_splice_sanitizer_|. Once enough buffers for | |
| 109 // crossfading are received the pre and post sanitizers are drained into | |
| 110 // |output_sanitizer_| by the two ExtractCrossfadeFromXXX methods above. | |
| 111 // | |
| 112 // |pre_splice_sanitizer_| is not constructed until the first splice frame is | |
| 113 // encountered. At which point it is constructed based on the timestamp state | |
| 114 // of |output_sanitizer_|. It is destructed once the splice is finished. | |
| 115 std::unique_ptr<AudioStreamSanitizer> output_sanitizer_; | |
| 116 std::unique_ptr<AudioStreamSanitizer> pre_splice_sanitizer_; | |
| 117 std::unique_ptr<AudioStreamSanitizer> post_splice_sanitizer_; | |
| 118 | |
| 119 // Whether all buffers which should go into |pre_splice_sanitizer_| have been | |
| 120 // received. If true, buffers should now be put in |post_splice_sanitizer_|. | |
| 121 bool have_all_pre_splice_buffers_; | |
| 122 | |
| 123 DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSplicer); | |
| 124 }; | |
| 125 | |
| 126 } // namespace media | |
| 127 | |
| 128 #endif // MEDIA_BASE_AUDIO_SPLICER_H_ | |
| OLD | NEW |