OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 // SeekableBuffer to support backward and forward seeking in a buffer for |
| 6 // reading a media data source. |
| 7 // |
| 8 // In order to support backward and forward seeking, this class buffers data in |
| 9 // both backward and forward directions, the current read position can be reset |
| 10 // to anywhere in the buffered data. |
| 11 // |
| 12 // The amount of data buffered is regulated by two variables at construction, |
| 13 // |backward_capacity| and |forward_capacity|. |
| 14 // |
| 15 // In the case of reading and seeking forward, the current read position |
| 16 // advances and there will be more data in the backward direction. If backward |
| 17 // bytes exceeds |backward_capacity|, the exceeding bytes are evicted and thus |
| 18 // backward_bytes() will always be less than or equal to |backward_capacity|. |
| 19 // The eviction will be caused by Read() and Seek() in the forward direction and |
| 20 // is done internally when the mentioned criteria is fulfilled. |
| 21 // |
| 22 // In the case of appending data to the buffer, there is an advisory limit of |
| 23 // how many bytes can be kept in the forward direction, regulated by |
| 24 // |forward_capacity|. The append operation (by calling Append()) that caused |
| 25 // forward bytes to exceed |forward_capacity| will have a return value that |
| 26 // advises a halt of append operation, further append operations are allowed but |
| 27 // are not advised. Since this class is used as a backend buffer for caching |
| 28 // media files downloaded from network we cannot afford losing data, we can |
| 29 // only advise a halt of further writing to this buffer. |
| 30 // This class is not inherently thread-safe. Concurrent access must be |
| 31 // externally serialized. |
| 32 |
| 33 #ifndef MEDIA_BASE_SEEKABLE_BUFFER_H_ |
| 34 #define MEDIA_BASE_SEEKABLE_BUFFER_H_ |
| 35 |
| 36 #include <list> |
| 37 |
| 38 #include "base/basictypes.h" |
| 39 #include "base/lock.h" |
| 40 #include "base/scoped_ptr.h" |
| 41 |
| 42 namespace media { |
| 43 |
| 44 class SeekableBuffer { |
| 45 public: |
| 46 // Construct an instance with forward capacity of |forward_capacity| |
| 47 // and backward capacity of |backward_capacity|. The values are in bytes. |
| 48 SeekableBuffer(size_t backward_capacity, size_t forward_capacity); |
| 49 |
| 50 ~SeekableBuffer(); |
| 51 |
| 52 // Read a maximum of |size| bytes into |buffer| from the current read |
| 53 // position. Return the number of bytes read. |
| 54 // The current read position will advances by the amount of bytes read. If |
| 55 // reading caused backward bytes to exceed backward_capacity(), an eviction |
| 56 // of backward buffer will be done internally. |
| 57 size_t Read(size_t size, uint8* buffer); |
| 58 |
| 59 // Append |data| with |size| bytes to this buffer. If this buffer becomes full |
| 60 // or is already full then return false, otherwise true. |
| 61 // Append operations are always successful, a return value of false only means |
| 62 // that there's more forward bytes than the capacity, data is still in this |
| 63 // buffer, but user is advised not to write any more. |
| 64 bool Append(size_t size, const uint8* data); |
| 65 |
| 66 // Move the read position by an offset of |offset| bytes. If |offset| is |
| 67 // positive, the current read position is moved forward. If negative, the |
| 68 // current read position is moved backward. A zero |offset| value will keep |
| 69 // the current read position stationary. |
| 70 // If |offset| exceeds bytes buffered in either direction, reported by |
| 71 // forward_bytes() when seeking forward and backward_bytes() when seeking |
| 72 // backward, the seek operation will fail and return value will be false. |
| 73 // If the seek operation fails, the current read position will not be updated. |
| 74 // If a forward seeking caused backward bytes to exceed backward_capacity(), |
| 75 // this method call will cause an eviction of backward buffer. |
| 76 bool Seek(int32 offset); |
| 77 |
| 78 // Returns the number of bytes buffered beyond the current read position. |
| 79 size_t forward_bytes() const { return forward_bytes_; } |
| 80 |
| 81 // Returns the number of bytes buffered that precedes the current read |
| 82 // position. |
| 83 size_t backward_bytes() const { return backward_bytes_; } |
| 84 |
| 85 // Returns the maximum number of bytes that should be kept in the forward |
| 86 // direction. |
| 87 size_t forward_capacity() const { return forward_capacity_; } |
| 88 |
| 89 // Returns the maximum number of bytes that should be kept in the backward |
| 90 // direction. |
| 91 size_t backward_capacity() const { return backward_capacity_; } |
| 92 |
| 93 private: |
| 94 // A helper method to evict buffers in the backward direction until backward |
| 95 // bytes is within the backward capacity. |
| 96 void EvictBackwardBuffers(); |
| 97 |
| 98 // An internal method shared by Read() and SeekForward() that actually does |
| 99 // reading. It reads a maximum of |size| bytes into |data|. Returns the number |
| 100 // of bytes read. The current read position will be moved forward by the |
| 101 // number of bytes read. If |data| is NULL, only the current read position |
| 102 // will advance but no data will be copied. |
| 103 size_t InternalRead(size_t size, uint8* data); |
| 104 |
| 105 bool SeekForward(size_t size); |
| 106 |
| 107 bool SeekBackward(size_t size); |
| 108 |
| 109 // A structure that contains a block of data. |
| 110 struct Buffer { |
| 111 explicit Buffer(size_t len) : data(new uint8[len]), size(len) {} |
| 112 // Pointer to data. |
| 113 scoped_array<uint8> data; |
| 114 // Size of this block. |
| 115 size_t size; |
| 116 }; |
| 117 |
| 118 typedef std::list<Buffer*> BufferQueue; |
| 119 BufferQueue::iterator current_buffer_; |
| 120 BufferQueue buffers_; |
| 121 size_t current_buffer_offset_; |
| 122 |
| 123 size_t backward_capacity_; |
| 124 size_t backward_bytes_; |
| 125 |
| 126 size_t forward_capacity_; |
| 127 size_t forward_bytes_; |
| 128 }; |
| 129 |
| 130 } // namespace media |
| 131 |
| 132 #endif // MEDIA_BASE_SEEKABLE_BUFFER_H_ |
OLD | NEW |