blob: 5ed4f6b7268c73f1c798bbf6d5ab8e04f4073773 [file] [log] [blame]
// 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_