Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: media/base/audio_buffer.h

Issue 2788483003: Introduce AudioBufferMemoryPool to avoid thrashing on audio buffers. (Closed)
Patch Set: Privatize methods. Remove cruft. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MEDIA_BASE_AUDIO_BUFFER_H_ 5 #ifndef MEDIA_BASE_AUDIO_BUFFER_H_
6 #define MEDIA_BASE_AUDIO_BUFFER_H_ 6 #define MEDIA_BASE_AUDIO_BUFFER_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <list>
11 #include <memory> 12 #include <memory>
13 #include <utility>
12 #include <vector> 14 #include <vector>
13 15
14 #include "base/macros.h" 16 #include "base/macros.h"
15 #include "base/memory/aligned_memory.h" 17 #include "base/memory/aligned_memory.h"
16 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
19 #include "base/synchronization/lock.h"
17 #include "base/time/time.h" 20 #include "base/time/time.h"
18 #include "media/base/channel_layout.h" 21 #include "media/base/channel_layout.h"
19 #include "media/base/media_export.h" 22 #include "media/base/media_export.h"
20 #include "media/base/sample_format.h" 23 #include "media/base/sample_format.h"
21 24
22 namespace mojo { 25 namespace mojo {
23 template <typename T, typename U> 26 template <typename T, typename U>
24 struct TypeConverter; 27 struct TypeConverter;
25 template <typename T> 28 template <typename T>
26 class StructPtr; 29 class StructPtr;
27 }; 30 };
28 31
29 namespace media { 32 namespace media {
30 class AudioBus; 33 class AudioBus;
34 class AudioBufferMemoryPool;
31 35
32 namespace mojom { 36 namespace mojom {
33 class AudioBuffer; 37 class AudioBuffer;
34 } 38 }
35 39
36 // An audio buffer that takes a copy of the data passed to it, holds it, and 40 // An audio buffer that takes a copy of the data passed to it, holds it, and
37 // copies it into an AudioBus when needed. Also supports an end of stream 41 // copies it into an AudioBus when needed. Also supports an end of stream
38 // marker. 42 // marker.
39 class MEDIA_EXPORT AudioBuffer 43 class MEDIA_EXPORT AudioBuffer
40 : public base::RefCountedThreadSafe<AudioBuffer> { 44 : public base::RefCountedThreadSafe<AudioBuffer> {
41 public: 45 public:
42 // Alignment of each channel's data; this must match what ffmpeg expects 46 // Alignment of each channel's data; this must match what ffmpeg expects
43 // (which may be 0, 16, or 32, depending on the processor). Selecting 32 in 47 // (which may be 0, 16, or 32, depending on the processor). Selecting 32 in
44 // order to work on all processors. 48 // order to work on all processors.
45 enum { kChannelAlignment = 32 }; 49 enum { kChannelAlignment = 32 };
46 50
47 // Create an AudioBuffer whose channel data is copied from |data|. For 51 // Create an AudioBuffer whose channel data is copied from |data|. For
48 // interleaved data, only the first buffer is used. For planar data, the 52 // interleaved data, only the first buffer is used. For planar data, the
49 // number of buffers must be equal to |channel_count|. |frame_count| is the 53 // number of buffers must be equal to |channel_count|. |frame_count| is the
50 // number of frames in each buffer. |data| must not be null and |frame_count| 54 // number of frames in each buffer. |data| must not be null and |frame_count|
51 // must be >= 0. 55 // must be >= 0. For optimal efficiency when many buffers are being created, a
52 static scoped_refptr<AudioBuffer> CopyFrom(SampleFormat sample_format, 56 // AudioBufferMemoryPool can be provided to avoid thrashing memory.
53 ChannelLayout channel_layout, 57 static scoped_refptr<AudioBuffer> CopyFrom(
54 int channel_count, 58 SampleFormat sample_format,
55 int sample_rate, 59 ChannelLayout channel_layout,
56 int frame_count, 60 int channel_count,
57 const uint8_t* const* data, 61 int sample_rate,
58 const base::TimeDelta timestamp); 62 int frame_count,
63 const uint8_t* const* data,
64 const base::TimeDelta timestamp,
65 scoped_refptr<AudioBufferMemoryPool> pool = nullptr);
59 66
60 // Create an AudioBuffer with |frame_count| frames. Buffer is allocated, but 67 // Create an AudioBuffer with |frame_count| frames. Buffer is allocated, but
61 // not initialized. Timestamp and duration are set to kNoTimestamp. 68 // not initialized. Timestamp and duration are set to kNoTimestamp. For
62 static scoped_refptr<AudioBuffer> CreateBuffer(SampleFormat sample_format, 69 // optimal efficiency when many buffers are being created, a
63 ChannelLayout channel_layout, 70 // AudioBufferMemoryPool can be provided to avoid thrashing memory.
64 int channel_count, 71 static scoped_refptr<AudioBuffer> CreateBuffer(
65 int sample_rate, 72 SampleFormat sample_format,
66 int frame_count); 73 ChannelLayout channel_layout,
74 int channel_count,
75 int sample_rate,
76 int frame_count,
77 scoped_refptr<AudioBufferMemoryPool> pool = nullptr);
67 78
68 // Create an empty AudioBuffer with |frame_count| frames. 79 // Create an empty AudioBuffer with |frame_count| frames.
69 static scoped_refptr<AudioBuffer> CreateEmptyBuffer( 80 static scoped_refptr<AudioBuffer> CreateEmptyBuffer(
70 ChannelLayout channel_layout, 81 ChannelLayout channel_layout,
71 int channel_count, 82 int channel_count,
72 int sample_rate, 83 int sample_rate,
73 int frame_count, 84 int frame_count,
74 const base::TimeDelta timestamp); 85 const base::TimeDelta timestamp);
75 86
76 // Create a AudioBuffer indicating we've reached end of stream. 87 // Create a AudioBuffer indicating we've reached end of stream.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // [data,data+data_size) to the allocated buffer(s). If |data| is null, no 161 // [data,data+data_size) to the allocated buffer(s). If |data| is null, no
151 // data is copied. If |create_buffer| is false, no data buffer is created (or 162 // data is copied. If |create_buffer| is false, no data buffer is created (or
152 // copied to). 163 // copied to).
153 AudioBuffer(SampleFormat sample_format, 164 AudioBuffer(SampleFormat sample_format,
154 ChannelLayout channel_layout, 165 ChannelLayout channel_layout,
155 int channel_count, 166 int channel_count,
156 int sample_rate, 167 int sample_rate,
157 int frame_count, 168 int frame_count,
158 bool create_buffer, 169 bool create_buffer,
159 const uint8_t* const* data, 170 const uint8_t* const* data,
160 const base::TimeDelta timestamp); 171 const base::TimeDelta timestamp,
172 scoped_refptr<AudioBufferMemoryPool> pool);
161 173
162 virtual ~AudioBuffer(); 174 virtual ~AudioBuffer();
163 175
164 const SampleFormat sample_format_; 176 const SampleFormat sample_format_;
165 const ChannelLayout channel_layout_; 177 const ChannelLayout channel_layout_;
166 const int channel_count_; 178 const int channel_count_;
167 int sample_rate_; 179 int sample_rate_;
168 int adjusted_frame_count_; 180 int adjusted_frame_count_;
169 const bool end_of_stream_; 181 const bool end_of_stream_;
170 base::TimeDelta timestamp_; 182 base::TimeDelta timestamp_;
171 base::TimeDelta duration_; 183 base::TimeDelta duration_;
172 184
173 // Contiguous block of channel data. 185 // Contiguous block of channel data.
174 std::unique_ptr<uint8_t, base::AlignedFreeDeleter> data_; 186 std::unique_ptr<uint8_t, base::AlignedFreeDeleter> data_;
175 size_t data_size_; 187 size_t data_size_;
176 188
177 // For planar data, points to each channels data. 189 // For planar data, points to each channels data.
178 std::vector<uint8_t*> channel_data_; 190 std::vector<uint8_t*> channel_data_;
179 191
192 // Allows recycling of memory data to avoid repeated allocations.
193 scoped_refptr<AudioBufferMemoryPool> pool_;
194
180 DISALLOW_IMPLICIT_CONSTRUCTORS(AudioBuffer); 195 DISALLOW_IMPLICIT_CONSTRUCTORS(AudioBuffer);
181 }; 196 };
182 197
198 // Basic memory pool for reusing AudioBuffer internal memory to avoid thrashing.
xhwang 2017/04/01 00:05:26 Please add a comment that AudioBuffer created usin
DaleCurtis 2017/04/01 01:00:01 Done.
199 class MEDIA_EXPORT AudioBufferMemoryPool
200 : public base::RefCountedThreadSafe<AudioBufferMemoryPool> {
201 public:
202 AudioBufferMemoryPool();
203
204 size_t get_pool_size_for_testing() const { return entries_.size(); }
205
206 private:
207 friend class AudioBuffer;
208 friend class base::RefCountedThreadSafe<AudioBufferMemoryPool>;
209
210 ~AudioBufferMemoryPool();
211
212 using AudioMemory = std::unique_ptr<uint8_t, base::AlignedFreeDeleter>;
213 AudioMemory CreateBuffer(size_t size);
214 void ReturnBuffer(AudioMemory memory, size_t size);
215
216 base::Lock entry_lock_;
217 using MemoryEntry = std::pair<AudioMemory, size_t>;
218 std::list<MemoryEntry> entries_;
219
220 DISALLOW_COPY_AND_ASSIGN(AudioBufferMemoryPool);
221 };
222
183 } // namespace media 223 } // namespace media
184 224
185 #endif // MEDIA_BASE_AUDIO_BUFFER_H_ 225 #endif // MEDIA_BASE_AUDIO_BUFFER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698