1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137

media / base / data_buffer.h [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 "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:
  // 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);

  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);

  base::span<const uint8_t> data() const {
    CHECK(!end_of_stream());
    return data_;
  }

  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_; }

 protected:
  friend class base::RefCountedThreadSafe<DataBuffer>;
  enum class DataBufferType { kNormal, kEndOfStream };

  // Allocates a buffer with a copy of |data| in it
  explicit DataBuffer(base::span<const uint8_t> data);

  explicit DataBuffer(DataBufferType data_buffer_type);

  virtual ~DataBuffer();

 private:
  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_