| Index: media/base/seekable_buffer.h
|
| ===================================================================
|
| --- media/base/seekable_buffer.h (revision 0)
|
| +++ media/base/seekable_buffer.h (revision 0)
|
| @@ -0,0 +1,132 @@
|
| +// Copyright (c) 2009 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.
|
| +
|
| +// SeekableBuffer to support backward and forward seeking in a buffer for
|
| +// reading a media data source.
|
| +//
|
| +// In order to support backward and forward seeking, this class buffers data in
|
| +// both backward and forward directions, the current read position can be reset
|
| +// to anywhere in the buffered data.
|
| +//
|
| +// The amount of data buffered is regulated by two variables at construction,
|
| +// |backward_capacity| and |forward_capacity|.
|
| +//
|
| +// In the case of reading and seeking forward, the current read position
|
| +// advances and there will be more data in the backward direction. If backward
|
| +// bytes exceeds |backward_capacity|, the exceeding bytes are evicted and thus
|
| +// backward_bytes() will always be less than or equal to |backward_capacity|.
|
| +// The eviction will be caused by Read() and Seek() in the forward direction and
|
| +// is done internally when the mentioned criteria is fulfilled.
|
| +//
|
| +// In the case of appending data to the buffer, there is an advisory limit of
|
| +// how many bytes can be kept in the forward direction, regulated by
|
| +// |forward_capacity|. The append operation (by calling Append()) that caused
|
| +// forward bytes to exceed |forward_capacity| will have a return value that
|
| +// advises a halt of append operation, further append operations are allowed but
|
| +// are not advised. Since this class is used as a backend buffer for caching
|
| +// media files downloaded from network we cannot afford losing data, we can
|
| +// only advise a halt of further writing to this buffer.
|
| +// This class is not inherently thread-safe. Concurrent access must be
|
| +// externally serialized.
|
| +
|
| +#ifndef MEDIA_BASE_SEEKABLE_BUFFER_H_
|
| +#define MEDIA_BASE_SEEKABLE_BUFFER_H_
|
| +
|
| +#include <list>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/lock.h"
|
| +#include "base/scoped_ptr.h"
|
| +
|
| +namespace media {
|
| +
|
| +class SeekableBuffer {
|
| + public:
|
| + // Construct an instance with forward capacity of |forward_capacity|
|
| + // and backward capacity of |backward_capacity|. The values are in bytes.
|
| + SeekableBuffer(size_t backward_capacity, size_t forward_capacity);
|
| +
|
| + ~SeekableBuffer();
|
| +
|
| + // Read a maximum of |size| bytes into |buffer| from the current read
|
| + // position. Return the number of bytes read.
|
| + // The current read position will advances by the amount of bytes read. If
|
| + // reading caused backward bytes to exceed backward_capacity(), an eviction
|
| + // of backward buffer will be done internally.
|
| + size_t Read(size_t size, uint8* buffer);
|
| +
|
| + // Append |data| with |size| bytes to this buffer. If this buffer becomes full
|
| + // or is already full then return false, otherwise true.
|
| + // Append operations are always successful, a return value of false only means
|
| + // that there's more forward bytes than the capacity, data is still in this
|
| + // buffer, but user is advised not to write any more.
|
| + bool Append(size_t size, const uint8* data);
|
| +
|
| + // Move the read position by an offset of |offset| bytes. If |offset| is
|
| + // positive, the current read position is moved forward. If negative, the
|
| + // current read position is moved backward. A zero |offset| value will keep
|
| + // the current read position stationary.
|
| + // If |offset| exceeds bytes buffered in either direction, reported by
|
| + // forward_bytes() when seeking forward and backward_bytes() when seeking
|
| + // backward, the seek operation will fail and return value will be false.
|
| + // If the seek operation fails, the current read position will not be updated.
|
| + // If a forward seeking caused backward bytes to exceed backward_capacity(),
|
| + // this method call will cause an eviction of backward buffer.
|
| + bool Seek(int32 offset);
|
| +
|
| + // Returns the number of bytes buffered beyond the current read position.
|
| + size_t forward_bytes() const { return forward_bytes_; }
|
| +
|
| + // Returns the number of bytes buffered that precedes the current read
|
| + // position.
|
| + size_t backward_bytes() const { return backward_bytes_; }
|
| +
|
| + // Returns the maximum number of bytes that should be kept in the forward
|
| + // direction.
|
| + size_t forward_capacity() const { return forward_capacity_; }
|
| +
|
| + // Returns the maximum number of bytes that should be kept in the backward
|
| + // direction.
|
| + size_t backward_capacity() const { return backward_capacity_; }
|
| +
|
| + private:
|
| + // A helper method to evict buffers in the backward direction until backward
|
| + // bytes is within the backward capacity.
|
| + void EvictBackwardBuffers();
|
| +
|
| + // An internal method shared by Read() and SeekForward() that actually does
|
| + // reading. It reads a maximum of |size| bytes into |data|. Returns the number
|
| + // of bytes read. The current read position will be moved forward by the
|
| + // number of bytes read. If |data| is NULL, only the current read position
|
| + // will advance but no data will be copied.
|
| + size_t InternalRead(size_t size, uint8* data);
|
| +
|
| + bool SeekForward(size_t size);
|
| +
|
| + bool SeekBackward(size_t size);
|
| +
|
| + // A structure that contains a block of data.
|
| + struct Buffer {
|
| + explicit Buffer(size_t len) : data(new uint8[len]), size(len) {}
|
| + // Pointer to data.
|
| + scoped_array<uint8> data;
|
| + // Size of this block.
|
| + size_t size;
|
| + };
|
| +
|
| + typedef std::list<Buffer*> BufferQueue;
|
| + BufferQueue::iterator current_buffer_;
|
| + BufferQueue buffers_;
|
| + size_t current_buffer_offset_;
|
| +
|
| + size_t backward_capacity_;
|
| + size_t backward_bytes_;
|
| +
|
| + size_t forward_capacity_;
|
| + size_t forward_bytes_;
|
| +};
|
| +
|
| +} // namespace media
|
| +
|
| +#endif // MEDIA_BASE_SEEKABLE_BUFFER_H_
|
|
|