| 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 // Audio rendering unit utilizing AudioDevice. | |
| 6 // | |
| 7 // This class lives inside three threads during it's lifetime, namely: | |
| 8 // 1. Render thread. | |
| 9 // This object is created on the render thread. | |
| 10 // 2. Pipeline thread | |
| 11 // OnInitialize() is called here with the audio format. | |
| 12 // Play/Pause/Seek also happens here. | |
| 13 // 3. Audio thread created by the AudioDevice. | |
| 14 // Render() is called here where audio data is decoded into raw PCM data. | |
| 15 | |
| 16 #ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ | |
| 17 #define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ | |
| 18 #pragma once | |
| 19 | |
| 20 #include <vector> | |
| 21 | |
| 22 #include "base/gtest_prod_util.h" | |
| 23 #include "base/memory/scoped_ptr.h" | |
| 24 #include "base/synchronization/lock.h" | |
| 25 #include "content/renderer/media/audio_device.h" | |
| 26 #include "media/audio/audio_io.h" | |
| 27 #include "media/audio/audio_parameters.h" | |
| 28 #include "media/base/audio_renderer_sink.h" | |
| 29 #include "media/filters/audio_renderer_base.h" | |
| 30 | |
| 31 class AudioMessageFilter; | |
| 32 | |
| 33 class CONTENT_EXPORT AudioRendererImpl | |
| 34 : public media::AudioRendererBase, | |
| 35 NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback) { | |
| 36 public: | |
| 37 // Methods called on Render thread ------------------------------------------ | |
| 38 // An AudioRendererSink is used as the destination for the rendered audio. | |
| 39 explicit AudioRendererImpl(media::AudioRendererSink* sink); | |
| 40 virtual ~AudioRendererImpl(); | |
| 41 | |
| 42 // Methods called on pipeline thread ---------------------------------------- | |
| 43 // media::Filter implementation. | |
| 44 virtual void SetPlaybackRate(float rate) OVERRIDE; | |
| 45 virtual void Pause(const base::Closure& callback) OVERRIDE; | |
| 46 virtual void Seek(base::TimeDelta time, | |
| 47 const media::PipelineStatusCB& cb) OVERRIDE; | |
| 48 virtual void Play(const base::Closure& callback) OVERRIDE; | |
| 49 | |
| 50 // media::AudioRenderer implementation. | |
| 51 virtual void SetVolume(float volume) OVERRIDE; | |
| 52 | |
| 53 protected: | |
| 54 // Methods called on pipeline thread ---------------------------------------- | |
| 55 // These methods are called from AudioRendererBase. | |
| 56 virtual bool OnInitialize(int bits_per_channel, | |
| 57 ChannelLayout channel_layout, | |
| 58 int sample_rate) OVERRIDE; | |
| 59 virtual void OnStop() OVERRIDE; | |
| 60 virtual void OnRenderEndOfStream() OVERRIDE; | |
| 61 | |
| 62 private: | |
| 63 // For access to constructor and IO thread methods. | |
| 64 friend class AudioRendererImplTest; | |
| 65 friend class DelegateCaller; | |
| 66 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop); | |
| 67 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, | |
| 68 DestroyedMessageLoop_ConsumeAudioSamples); | |
| 69 FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime); | |
| 70 // Helper methods. | |
| 71 // Convert number of bytes to duration of time using information about the | |
| 72 // number of channels, sample rate and sample bits. | |
| 73 base::TimeDelta ConvertToDuration(int bytes); | |
| 74 | |
| 75 // Methods called on pipeline thread ---------------------------------------- | |
| 76 void DoPlay(); | |
| 77 void DoPause(); | |
| 78 void DoSeek(); | |
| 79 | |
| 80 // media::AudioRendererSink::RenderCallback implementation. | |
| 81 virtual size_t Render(const std::vector<float*>& audio_data, | |
| 82 size_t number_of_frames, | |
| 83 size_t audio_delay_milliseconds) OVERRIDE; | |
| 84 virtual void OnRenderError() OVERRIDE; | |
| 85 | |
| 86 // Accessors used by tests. | |
| 87 base::Time earliest_end_time() const { | |
| 88 return earliest_end_time_; | |
| 89 } | |
| 90 | |
| 91 void set_earliest_end_time(const base::Time& earliest_end_time) { | |
| 92 earliest_end_time_ = earliest_end_time; | |
| 93 } | |
| 94 | |
| 95 uint32 bytes_per_second() const { | |
| 96 return bytes_per_second_; | |
| 97 } | |
| 98 | |
| 99 // Estimate earliest time when current buffer can stop playing. | |
| 100 void UpdateEarliestEndTime(int bytes_filled, | |
| 101 base::TimeDelta request_delay, | |
| 102 base::Time time_now); | |
| 103 | |
| 104 // Used to calculate audio delay given bytes. | |
| 105 uint32 bytes_per_second_; | |
| 106 | |
| 107 // A flag that indicates this filter is called to stop. | |
| 108 bool stopped_; | |
| 109 | |
| 110 // The sink (destination) for rendered audio. | |
| 111 scoped_refptr<media::AudioRendererSink> sink_; | |
| 112 | |
| 113 // Set to true when OnInitialize() is called. | |
| 114 bool is_initialized_; | |
| 115 | |
| 116 // We're supposed to know amount of audio data OS or hardware buffered, but | |
| 117 // that is not always so -- on my Linux box | |
| 118 // AudioBuffersState::hardware_delay_bytes never reaches 0. | |
| 119 // | |
| 120 // As a result we cannot use it to find when stream ends. If we just ignore | |
| 121 // buffered data we will notify host that stream ended before it is actually | |
| 122 // did so, I've seen it done ~140ms too early when playing ~150ms file. | |
| 123 // | |
| 124 // Instead of trying to invent OS-specific solution for each and every OS we | |
| 125 // are supporting, use simple workaround: every time we fill the buffer we | |
| 126 // remember when it should stop playing, and do not assume that buffer is | |
| 127 // empty till that time. Workaround is not bulletproof, as we don't exactly | |
| 128 // know when that particular data would start playing, but it is much better | |
| 129 // than nothing. | |
| 130 base::Time earliest_end_time_; | |
| 131 | |
| 132 media::AudioParameters audio_parameters_; | |
| 133 | |
| 134 DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); | |
| 135 }; | |
| 136 | |
| 137 #endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_ | |
| OLD | NEW |