| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef MEDIA_BASE_DATA_BUFFER_H_ |
| #define MEDIA_BASE_DATA_BUFFER_H_ |
| |
| #include <stdint.h> |
| |
| #include "base/check_op.h" |
| #include "base/containers/heap_array.h" |
| #include "base/containers/span.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/time/time.h" |
| #include "base/types/pass_key.h" |
| #include "media/base/media_export.h" |
| |
| namespace media { |
| |
| // A simple buffer that takes ownership of the given data pointer or allocates |
| // as necessary. The capacity of the buffer is constant and set at construction, |
| // and its size may fluctuate as data is written to the buffer. |
| // |
| // Unlike DecoderBuffer, allocations are assumed to be allocated with the |
| // default memory allocator (i.e., new uint8_t[]). |
| // |
| // NOTE: It is illegal to call any method when end_of_stream() is true. |
| class MEDIA_EXPORT DataBuffer : public base::RefCountedThreadSafe<DataBuffer> { |
| public: |
| REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); |
| |
| // Constructs an empty buffer with max `capacity`, uninitialized `data_` and |
| // a size of zero. |
| explicit DataBuffer(size_t capacity); |
| |
| // Constructs a filled buffer by moving `buffer` into the `data_` property, |
| // with a size of `buffer.size()`. |
| explicit DataBuffer(base::HeapArray<uint8_t> buffer); |
| |
| // Allocates a buffer with a copy of `data` in it |
| DataBuffer(base::PassKey<DataBuffer>, base::span<const uint8_t> data); |
| |
| enum class DataBufferType { kNormal, kEndOfStream }; |
| DataBuffer(base::PassKey<DataBuffer>, DataBufferType data_buffer_type); |
| |
| DataBuffer(DataBuffer&&) = delete; |
| DataBuffer(const DataBuffer&) = delete; |
| DataBuffer& operator=(DataBuffer&&) = delete; |
| DataBuffer& operator=(const DataBuffer&) = delete; |
| |
| // Create a DataBuffer whose |data_| is copied from |data|. |
| static scoped_refptr<DataBuffer> CopyFrom(base::span<const uint8_t> data); |
| |
| // Create a DataBuffer indicating we've reached end of stream. |
| // |
| // Calling any method other than end_of_stream() on the resulting buffer |
| // is disallowed. |
| static scoped_refptr<DataBuffer> CreateEOSBuffer(); |
| |
| // Convenience method for initializing `data_` to zero. By default, data_ |
| // is constructed with its value uninitialized. |
| void FillWithZeroes() { |
| CHECK(!end_of_stream()); |
| std::fill(data_.begin(), data_.end(), 0); |
| } |
| |
| base::TimeDelta timestamp() const { |
| CHECK(!end_of_stream()); |
| return timestamp_; |
| } |
| |
| void set_timestamp(const base::TimeDelta& timestamp) { |
| CHECK(!end_of_stream()); |
| timestamp_ = timestamp; |
| } |
| |
| base::TimeDelta duration() const { |
| CHECK(!end_of_stream()); |
| return duration_; |
| } |
| |
| void set_duration(const base::TimeDelta& duration) { |
| CHECK(!end_of_stream()); |
| duration_ = duration; |
| } |
| |
| // The capacity of the buffer, set at construction. |
| size_t capacity() const { |
| CHECK(!end_of_stream()); |
| return data_.size(); |
| } |
| |
| // Adds the elements from data to the beginning of the free space within the |
| // buffer, and updates `size_`. Caller is responsible for ensuring there is |
| // enough space for this method to succeed. |
| void Append(base::span<const uint8_t> data); |
| |
| // Returns a span over `data_` that is truncated by the valid size(). |
| base::span<const uint8_t> data() const { |
| CHECK(!end_of_stream()); |
| return data_.first(size_); |
| } |
| |
| // Returns a span over `data_`, including any initialized portion. Care should |
| // be taken that uninitialized memory is written to before being accessed. |
| base::span<uint8_t> writable_data() { |
| CHECK(!end_of_stream()); |
| return data_; |
| } |
| |
| // The size of valid data in bytes. |
| // |
| // Setting this value beyond the buffer capacity is disallowed. |
| size_t size() const { |
| CHECK(!end_of_stream()); |
| return size_; |
| } |
| |
| void set_size(size_t size) { |
| CHECK(!end_of_stream()); |
| CHECK_LE(size, data_.size()); |
| size_ = size; |
| } |
| |
| bool end_of_stream() const { return is_end_of_stream_; } |
| |
| private: |
| friend class base::RefCountedThreadSafe<DataBuffer>; |
| virtual ~DataBuffer(); |
| |
| base::TimeDelta timestamp_; |
| base::TimeDelta duration_; |
| |
| base::HeapArray<uint8_t> data_; |
| size_t size_ = 0; |
| const bool is_end_of_stream_ = false; |
| }; |
| |
| } // namespace media |
| |
| #endif // MEDIA_BASE_DATA_BUFFER_H_ |