diff options
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/byte_queue.cc | 79 | ||||
-rw-r--r-- | media/base/byte_queue.h | 54 |
2 files changed, 133 insertions, 0 deletions
diff --git a/media/base/byte_queue.cc b/media/base/byte_queue.cc new file mode 100644 index 0000000..8f4fee8 --- /dev/null +++ b/media/base/byte_queue.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/byte_queue.h" + +#include "base/logging.h" + +namespace media { + +// Default starting size for the queue. +enum { kDefaultQueueSize = 1024 }; + +ByteQueue::ByteQueue() + : buffer_(new uint8[kDefaultQueueSize]), + size_(kDefaultQueueSize), + offset_(0), + used_(0) { +} + +ByteQueue::~ByteQueue() {} + +void ByteQueue::Push(const uint8* data, int size) { + DCHECK(data); + DCHECK_GT(size, 0); + + size_t size_needed = used_ + size; + + // Check to see if we need a bigger buffer. + if (size_needed > size_) { + size_t new_size = 2 * size_; + while (size_needed > new_size && new_size > size_) + new_size *= 2; + + // Sanity check to make sure we didn't overflow. + CHECK_GT(new_size, size_); + + scoped_array<uint8> new_buffer(new uint8[new_size]); + + // Copy the data from the old buffer to the start of the new one. + if (used_ > 0) + memcpy(new_buffer.get(), front(), used_); + + buffer_.reset(new_buffer.release()); + size_ = new_size; + offset_ = 0; + } else if ((offset_ + used_ + size) > size_) { + // The buffer is big enough, but we need to move the data in the queue. + memmove(buffer_.get(), front(), used_); + offset_ = 0; + } + + memcpy(front() + used_, data, size); + used_ += size; +} + +void ByteQueue::Peek(const uint8** data, int* size) const { + DCHECK(data); + DCHECK(size); + *data = front(); + *size = used_; +} + +void ByteQueue::Pop(int count) { + DCHECK_LE(count, used_); + + offset_ += count; + used_ -= count; + + // Move the offset back to 0 if we have reached the end of the buffer. + if (offset_ == size_) { + DCHECK_EQ(used_, 0); + offset_ = 0; + } +} + +uint8* ByteQueue::front() const { return buffer_.get() + offset_; } + +} // namespace media diff --git a/media/base/byte_queue.h b/media/base/byte_queue.h new file mode 100644 index 0000000..69f2728 --- /dev/null +++ b/media/base/byte_queue.h @@ -0,0 +1,54 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_BYTE_QUEUE_H_ +#define MEDIA_BASE_BYTE_QUEUE_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" + +namespace media { + +// Represents a queue of bytes. +// Data is added to the end of the queue via an Push() call and removed via +// Pop(). The contents of the queue can be observed via the Peek() method. +// This class manages the underlying storage of the queue and tries to minimize +// the number of buffer copies when data is appended and removed. +class ByteQueue { + public: + ByteQueue(); + ~ByteQueue(); + + // Appends new bytes onto the end of the queue. + void Push(const uint8* data, int size); + + // Get a pointer to the front of the queue and the queue size. + // These values are only valid until the next Push() or + // Pop() call. + void Peek(const uint8** data, int* size) const; + + // Remove |count| bytes from the front of the queue. + void Pop(int count); + + private: + // Returns a pointer to the front of the queue. + uint8* front() const; + + scoped_array<uint8> buffer_; + + // Size of |buffer_|. + size_t size_; + + // Offset from the start of |buffer_| that marks the front of the queue. + size_t offset_; + + // Number of bytes stored in the queue. + int used_; + + DISALLOW_COPY_AND_ASSIGN(ByteQueue); +}; + +} // namespace media + +#endif // MEDIA_BASE_BYTE_QUEUE_H_ |