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
9namespace media {
10
11// Default starting size for the queue.
12enum { kDefaultQueueSize = 1024 };
13
14ByteQueue::ByteQueue()
15    : buffer_(new uint8[kDefaultQueueSize]),
16      size_(kDefaultQueueSize),
17      offset_(0),
18      used_(0) {
19}
20
21ByteQueue::~ByteQueue() {}
22
23void ByteQueue::Reset() {
24  offset_ = 0;
25  used_ = 0;
26}
27
28void 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
62void ByteQueue::Peek(const uint8** data, int* size) const {
63  DCHECK(data);
64  DCHECK(size);
65  *data = front();
66  *size = used_;
67}
68
69void 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
82uint8* ByteQueue::front() const { return buffer_.get() + offset_; }
83
84}  // namespace media
85