OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |