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

Side by Side Diff: media/base/seekable_buffer.cc

Issue 9395057: Fix muted audio when playback rate != 1.0 or 0.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 #include "media/base/seekable_buffer.h" 5 #include "media/base/seekable_buffer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/data_buffer.h" 10 #include "media/base/data_buffer.h"
(...skipping 18 matching lines...) Expand all
29 buffers_.clear(); 29 buffers_.clear();
30 current_buffer_ = buffers_.begin(); 30 current_buffer_ = buffers_.begin();
31 current_buffer_offset_ = 0; 31 current_buffer_offset_ = 0;
32 backward_bytes_ = 0; 32 backward_bytes_ = 0;
33 forward_bytes_ = 0; 33 forward_bytes_ = 0;
34 current_time_ = kNoTimestamp(); 34 current_time_ = kNoTimestamp();
35 } 35 }
36 36
37 size_t SeekableBuffer::Read(uint8* data, size_t size) { 37 size_t SeekableBuffer::Read(uint8* data, size_t size) {
38 DCHECK(data); 38 DCHECK(data);
39 return InternalRead(data, size, true); 39 return InternalRead(data, size, true, 0);
40 } 40 }
41 41
42 size_t SeekableBuffer::Peek(uint8* data, size_t size) { 42 size_t SeekableBuffer::Peek(uint8* data, size_t size) {
43 DCHECK(data); 43 DCHECK(data);
44 return InternalRead(data, size, false); 44 return InternalRead(data, size, false, 0);
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 nit:How about removing DCHECK & just calling Peek(
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 D'oh! Yes, that would make sense, thanks :)
45 }
46
47 size_t SeekableBuffer::Peek(uint8* data, size_t size, size_t forward_offset) {
48 DCHECK(data);
49 return InternalRead(data, size, false, forward_offset);
45 } 50 }
46 51
47 bool SeekableBuffer::GetCurrentChunk(const uint8** data, size_t* size) const { 52 bool SeekableBuffer::GetCurrentChunk(const uint8** data, size_t* size) const {
48 BufferQueue::iterator current_buffer = current_buffer_; 53 BufferQueue::iterator current_buffer = current_buffer_;
49 size_t current_buffer_offset = current_buffer_offset_; 54 size_t current_buffer_offset = current_buffer_offset_;
50 // Advance position if we are in the end of the current buffer. 55 // Advance position if we are in the end of the current buffer.
51 while (current_buffer != buffers_.end() && 56 while (current_buffer != buffers_.end() &&
52 current_buffer_offset >= (*current_buffer)->GetDataSize()) { 57 current_buffer_offset >= (*current_buffer)->GetDataSize()) {
53 ++current_buffer; 58 ++current_buffer;
54 current_buffer_offset = 0; 59 current_buffer_offset = 0;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 return SeekBackward(-offset); 111 return SeekBackward(-offset);
107 return true; 112 return true;
108 } 113 }
109 114
110 bool SeekableBuffer::SeekForward(size_t size) { 115 bool SeekableBuffer::SeekForward(size_t size) {
111 // Perform seeking forward only if we have enough bytes in the queue. 116 // Perform seeking forward only if we have enough bytes in the queue.
112 if (size > forward_bytes_) 117 if (size > forward_bytes_)
113 return false; 118 return false;
114 119
115 // Do a read of |size| bytes. 120 // Do a read of |size| bytes.
116 size_t taken = InternalRead(NULL, size, true); 121 size_t taken = InternalRead(NULL, size, true, 0);
117 DCHECK_EQ(taken, size); 122 DCHECK_EQ(taken, size);
118 return true; 123 return true;
119 } 124 }
120 125
121 bool SeekableBuffer::SeekBackward(size_t size) { 126 bool SeekableBuffer::SeekBackward(size_t size) {
122 if (size > backward_bytes_) 127 if (size > backward_bytes_)
123 return false; 128 return false;
124 // Record the number of bytes taken. 129 // Record the number of bytes taken.
125 size_t taken = 0; 130 size_t taken = 0;
126 // Loop until we taken enough bytes and rewind by the desired |size|. 131 // Loop until we taken enough bytes and rewind by the desired |size|.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 break; 181 break;
177 scoped_refptr<Buffer> buffer = *i; 182 scoped_refptr<Buffer> buffer = *i;
178 backward_bytes_ -= buffer->GetDataSize(); 183 backward_bytes_ -= buffer->GetDataSize();
179 DCHECK_GE(backward_bytes_, 0u); 184 DCHECK_GE(backward_bytes_, 0u);
180 185
181 buffers_.erase(i); 186 buffers_.erase(i);
182 } 187 }
183 } 188 }
184 189
185 size_t SeekableBuffer::InternalRead(uint8* data, size_t size, 190 size_t SeekableBuffer::InternalRead(uint8* data, size_t size,
186 bool advance_position) { 191 bool advance_position,
192 size_t forward_offset) {
187 // Counts how many bytes are actually read from the buffer queue. 193 // Counts how many bytes are actually read from the buffer queue.
188 size_t taken = 0; 194 size_t taken = 0;
189 195
190 BufferQueue::iterator current_buffer = current_buffer_; 196 BufferQueue::iterator current_buffer = current_buffer_;
191 size_t current_buffer_offset = current_buffer_offset_; 197 size_t current_buffer_offset = current_buffer_offset_;
192 198
199 size_t bytes_to_skip = forward_offset;
193 while (taken < size) { 200 while (taken < size) {
194 // |current_buffer| is valid since the first time this buffer is appended 201 // |current_buffer| is valid since the first time this buffer is appended
195 // with data. 202 // with data.
196 if (current_buffer == buffers_.end()) 203 if (current_buffer == buffers_.end())
197 break; 204 break;
198 205
199 scoped_refptr<Buffer> buffer = *current_buffer; 206 scoped_refptr<Buffer> buffer = *current_buffer;
200 207
201 // Find the right amount to copy from the current buffer referenced by 208 size_t remaining_bytes_in_buffer =
202 // |buffer|. We shall copy no more than |size| bytes in total and each 209 buffer->GetDataSize() - current_buffer_offset;
203 // single step copied no more than the current buffer size.
204 size_t copied = std::min(size - taken,
205 buffer->GetDataSize() - current_buffer_offset);
206 210
207 // |data| is NULL if we are seeking forward, so there's no need to copy. 211 if (bytes_to_skip == 0) {
208 if (data) 212 // Find the right amount to copy from the current buffer referenced by
209 memcpy(data + taken, buffer->GetData() + current_buffer_offset, copied); 213 // |buffer|. We shall copy no more than |size| bytes in total and each
214 // single step copied no more than the current buffer size.
215 size_t copied = std::min(size - taken, remaining_bytes_in_buffer);
210 216
211 // Increase total number of bytes copied, which regulates when to end this 217 // |data| is NULL if we are seeking forward, so there's no need to copy.
212 // loop. 218 if (data)
213 taken += copied; 219 memcpy(data + taken, buffer->GetData() + current_buffer_offset, copied);
214 220
215 // We have read |copied| bytes from the current buffer. Advances the offset. 221 // Increase total number of bytes copied, which regulates when to end this
216 current_buffer_offset += copied; 222 // loop.
223 taken += copied;
224
225 // We have read |copied| bytes from the current buffer. Advances the
226 // offset.
227 current_buffer_offset += copied;
228 } else {
229 size_t skipped = std::min(remaining_bytes_in_buffer, bytes_to_skip);
230 current_buffer_offset += skipped;
231 bytes_to_skip -= skipped;
232 }
217 233
218 // The buffer has been consumed. 234 // The buffer has been consumed.
219 if (current_buffer_offset == buffer->GetDataSize()) { 235 if (current_buffer_offset == buffer->GetDataSize()) {
220 if (advance_position) { 236 if (advance_position) {
221 // Next buffer may not have timestamp, so we need to update current 237 // Next buffer may not have timestamp, so we need to update current
222 // timestamp before switching to the next buffer. 238 // timestamp before switching to the next buffer.
223 UpdateCurrentTime(current_buffer, current_buffer_offset); 239 UpdateCurrentTime(current_buffer, current_buffer_offset);
224 } 240 }
225 241
226 BufferQueue::iterator next = current_buffer; 242 BufferQueue::iterator next = current_buffer;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 (*buffer)->GetTimestamp().InMicroseconds() > 0) { 276 (*buffer)->GetTimestamp().InMicroseconds() > 0) {
261 int64 time_offset = ((*buffer)->GetDuration().InMicroseconds() * 277 int64 time_offset = ((*buffer)->GetDuration().InMicroseconds() *
262 offset) / (*buffer)->GetDataSize(); 278 offset) / (*buffer)->GetDataSize();
263 279
264 current_time_ = (*buffer)->GetTimestamp() + 280 current_time_ = (*buffer)->GetTimestamp() +
265 base::TimeDelta::FromMicroseconds(time_offset); 281 base::TimeDelta::FromMicroseconds(time_offset);
266 } 282 }
267 } 283 }
268 284
269 } // namespace media 285 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698