Home | History | Annotate | Download | only in base
      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