diff options
author | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-06 00:48:37 +0000 |
---|---|---|
committer | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-06 00:48:37 +0000 |
commit | e4eccfdae7c8b34056e7b61450b0be30825fc5d2 (patch) | |
tree | f5090ba1d0d83f9df413ddf370eb12acbec8e7d2 /media/base | |
parent | 8e248501d06d6536bdc8f37d20d8c600f848485b (diff) | |
download | chromium_src-e4eccfdae7c8b34056e7b61450b0be30825fc5d2.zip chromium_src-e4eccfdae7c8b34056e7b61450b0be30825fc5d2.tar.gz chromium_src-e4eccfdae7c8b34056e7b61450b0be30825fc5d2.tar.bz2 |
Fix muted audio when playback rate != 1.0 or 0.0
Rewrites the logic in AudioRendererAlgorithmBase to be able to output audio
at any point of a sped-up/slowed down window, instead of only outputting audio
in full multiples of windows.
BUG=108239
TEST=media_unittests, manual testing on video test matrix
Review URL: http://codereview.chromium.org/9395057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125052 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/seekable_buffer.cc | 53 | ||||
-rw-r--r-- | media/base/seekable_buffer.h | 9 |
2 files changed, 38 insertions, 24 deletions
diff --git a/media/base/seekable_buffer.cc b/media/base/seekable_buffer.cc index b9ad7a4..49df43f 100644 --- a/media/base/seekable_buffer.cc +++ b/media/base/seekable_buffer.cc @@ -36,12 +36,12 @@ void SeekableBuffer::Clear() { size_t SeekableBuffer::Read(uint8* data, size_t size) { DCHECK(data); - return InternalRead(data, size, true); + return InternalRead(data, size, true, 0); } -size_t SeekableBuffer::Peek(uint8* data, size_t size) { +size_t SeekableBuffer::Peek(uint8* data, size_t size, size_t forward_offset) { DCHECK(data); - return InternalRead(data, size, false); + return InternalRead(data, size, false, forward_offset); } bool SeekableBuffer::GetCurrentChunk(const uint8** data, size_t* size) const { @@ -113,7 +113,7 @@ bool SeekableBuffer::SeekForward(size_t size) { return false; // Do a read of |size| bytes. - size_t taken = InternalRead(NULL, size, true); + size_t taken = InternalRead(NULL, size, true, 0); DCHECK_EQ(taken, size); return true; } @@ -183,13 +183,15 @@ void SeekableBuffer::EvictBackwardBuffers() { } size_t SeekableBuffer::InternalRead(uint8* data, size_t size, - bool advance_position) { + bool advance_position, + size_t forward_offset) { // Counts how many bytes are actually read from the buffer queue. size_t taken = 0; BufferQueue::iterator current_buffer = current_buffer_; size_t current_buffer_offset = current_buffer_offset_; + size_t bytes_to_skip = forward_offset; while (taken < size) { // |current_buffer| is valid since the first time this buffer is appended // with data. @@ -198,22 +200,31 @@ size_t SeekableBuffer::InternalRead(uint8* data, size_t size, scoped_refptr<Buffer> buffer = *current_buffer; - // Find the right amount to copy from the current buffer referenced by - // |buffer|. We shall copy no more than |size| bytes in total and each - // single step copied no more than the current buffer size. - size_t copied = std::min(size - taken, - buffer->GetDataSize() - current_buffer_offset); - - // |data| is NULL if we are seeking forward, so there's no need to copy. - if (data) - memcpy(data + taken, buffer->GetData() + current_buffer_offset, copied); - - // Increase total number of bytes copied, which regulates when to end this - // loop. - taken += copied; - - // We have read |copied| bytes from the current buffer. Advances the offset. - current_buffer_offset += copied; + size_t remaining_bytes_in_buffer = + buffer->GetDataSize() - current_buffer_offset; + + if (bytes_to_skip == 0) { + // Find the right amount to copy from the current buffer referenced by + // |buffer|. We shall copy no more than |size| bytes in total and each + // single step copied no more than the current buffer size. + size_t copied = std::min(size - taken, remaining_bytes_in_buffer); + + // |data| is NULL if we are seeking forward, so there's no need to copy. + if (data) + memcpy(data + taken, buffer->GetData() + current_buffer_offset, copied); + + // Increase total number of bytes copied, which regulates when to end this + // loop. + taken += copied; + + // We have read |copied| bytes from the current buffer. Advances the + // offset. + current_buffer_offset += copied; + } else { + size_t skipped = std::min(remaining_bytes_in_buffer, bytes_to_skip); + current_buffer_offset += skipped; + bytes_to_skip -= skipped; + } // The buffer has been consumed. if (current_buffer_offset == buffer->GetDataSize()) { diff --git a/media/base/seekable_buffer.h b/media/base/seekable_buffer.h index 56a7ceb..eb7ba84 100644 --- a/media/base/seekable_buffer.h +++ b/media/base/seekable_buffer.h @@ -60,8 +60,10 @@ class MEDIA_EXPORT SeekableBuffer { size_t Read(uint8* data, size_t size); // Copies up to |size| bytes from current position to |data|. Returns - // number of bytes copied. Doesn't advance current position. - size_t Peek(uint8* data, size_t size); + // number of bytes copied. Doesn't advance current position. Optionally + // starts at a |forward_offset| from current position. + size_t Peek(uint8* data, size_t size) { return Peek(data, size, 0); } + size_t Peek(uint8* data, size_t size, size_t forward_offset); // Returns pointer to the current chunk of data that is being consumed. // If there is no data left in the buffer false is returned, otherwise @@ -137,7 +139,8 @@ class MEDIA_EXPORT SeekableBuffer { // of bytes read. The current read position will be moved forward by the // number of bytes read. If |data| is NULL, only the current read position // will advance but no data will be copied. - size_t InternalRead(uint8* data, size_t size, bool advance_position); + size_t InternalRead( + uint8* data, size_t size, bool advance_position, size_t forward_offset); // A helper method that moves the current read position forward by |size| // bytes. |