15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/byte_queue.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default starting size for the queue.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { kDefaultQueueSize = 1024 };
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteQueue::ByteQueue()
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : buffer_(new uint8[kDefaultQueueSize]),
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_(kDefaultQueueSize),
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offset_(0),
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      used_(0) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteQueue::~ByteQueue() {}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ByteQueue::Reset() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  offset_ = 0;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  used_ = 0;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ByteQueue::Push(const uint8* data, int size) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(data);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(size, 0);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t size_needed = used_ + size;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see if we need a bigger buffer.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_needed > size_) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t new_size = 2 * size_;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (size_needed > new_size && new_size > size_)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_size *= 2;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sanity check to make sure we didn't overflow.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(new_size, size_);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> new_buffer(new uint8[new_size]);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Copy the data from the old buffer to the start of the new one.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (used_ > 0)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memcpy(new_buffer.get(), front(), used_);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer_.reset(new_buffer.release());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_ = new_size;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    offset_ = 0;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if ((offset_ + used_ + size) > size_) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The buffer is big enough, but we need to move the data in the queue.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memmove(buffer_.get(), front(), used_);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    offset_ = 0;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(front() + used_, data, size);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  used_ += size;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ByteQueue::Peek(const uint8** data, int* size) const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(data);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(size);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *data = front();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *size = used_;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ByteQueue::Pop(int count) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LE(count, used_);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  offset_ += count;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  used_ -= count;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the offset back to 0 if we have reached the end of the buffer.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (offset_ == size_) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(used_, 0);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    offset_ = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8* ByteQueue::front() const { return buffer_.get() + offset_; }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
85