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 |