1 // Copyright (c) 2011 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 #include "media/base/byte_queue.h" 6 7 #include "base/logging.h" 8 9 namespace media { 10 11 // Default starting size for the queue. 12 enum { kDefaultQueueSize = 1024 }; 13 14 ByteQueue::ByteQueue() 15 : buffer_(new uint8[kDefaultQueueSize]), 16 size_(kDefaultQueueSize), 17 offset_(0), 18 used_(0) { 19 } 20 21 ByteQueue::~ByteQueue() {} 22 23 void ByteQueue::Reset() { 24 offset_ = 0; 25 used_ = 0; 26 } 27 28 void ByteQueue::Push(const uint8* data, int size) { 29 DCHECK(data); 30 DCHECK_GT(size, 0); 31 32 size_t size_needed = used_ + size; 33 34 // Check to see if we need a bigger buffer. 35 if (size_needed > size_) { 36 size_t new_size = 2 * size_; 37 while (size_needed > new_size && new_size > size_) 38 new_size *= 2; 39 40 // Sanity check to make sure we didn't overflow. 41 CHECK_GT(new_size, size_); 42 43 scoped_ptr<uint8[]> new_buffer(new uint8[new_size]); 44 45 // Copy the data from the old buffer to the start of the new one. 46 if (used_ > 0) 47 memcpy(new_buffer.get(), front(), used_); 48 49 buffer_.reset(new_buffer.release()); 50 size_ = new_size; 51 offset_ = 0; 52 } else if ((offset_ + used_ + size) > size_) { 53 // The buffer is big enough, but we need to move the data in the queue. 54 memmove(buffer_.get(), front(), used_); 55 offset_ = 0; 56 } 57 58 memcpy(front() + used_, data, size); 59 used_ += size; 60 } 61 62 void ByteQueue::Peek(const uint8** data, int* size) const { 63 DCHECK(data); 64 DCHECK(size); 65 *data = front(); 66 *size = used_; 67 } 68 69 void ByteQueue::Pop(int count) { 70 DCHECK_LE(count, used_); 71 72 offset_ += count; 73 used_ -= count; 74 75 // Move the offset back to 0 if we have reached the end of the buffer. 76 if (offset_ == size_) { 77 DCHECK_EQ(used_, 0); 78 offset_ = 0; 79 } 80 } 81 82 uint8* ByteQueue::front() const { return buffer_.get() + offset_; } 83 84 } // namespace media 85