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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
|
// Copyright (c) 2012 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.
#ifndef MEDIA_BASE_DECODER_BUFFER_H_
#define MEDIA_BASE_DECODER_BUFFER_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>
#include "base/check.h"
#include "base/macros.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/decrypt_config.h"
#include "media/base/media_export.h"
#include "media/base/timestamp_constants.h"
#include "media/base/unaligned_shared_memory.h"
namespace media {
// A specialized buffer for interfacing with audio / video decoders.
//
// Also includes decoder specific functionality for decryption.
//
// NOTE: It is illegal to call any method when end_of_stream() is true.
class MEDIA_EXPORT DecoderBuffer
: public base::RefCountedThreadSafe<DecoderBuffer> {
public:
enum {
kPaddingSize = 64,
#if defined(ARCH_CPU_ARM_FAMILY)
kAlignmentSize = 16
#else
kAlignmentSize = 32
#endif
};
// Allocates buffer with |size| >= 0. |is_key_frame_| will default to false.
explicit DecoderBuffer(size_t size);
// Create a DecoderBuffer whose |data_| is copied from |data|. |data| must not
// be NULL and |size| >= 0. The buffer's |is_key_frame_| will default to
// false.
static scoped_refptr<DecoderBuffer> CopyFrom(const uint8_t* data,
size_t size);
// Create a DecoderBuffer whose |data_| is copied from |data| and |side_data_|
// is copied from |side_data|. Data pointers must not be NULL and sizes must
// be >= 0. The buffer's |is_key_frame_| will default to false.
static scoped_refptr<DecoderBuffer> CopyFrom(const uint8_t* data,
size_t size,
const uint8_t* side_data,
size_t side_data_size);
// Create a DecoderBuffer where data() of |size| bytes resides within the heap
// as byte array. The buffer's |is_key_frame_| will default to false.
//
// Ownership of |data| is transferred to the buffer.
static scoped_refptr<DecoderBuffer> FromArray(std::unique_ptr<uint8_t[]> data,
size_t size);
// Create a DecoderBuffer where data() of |size| bytes resides within the
// memory referred to by |region| at non-negative offset |offset|. The
// buffer's |is_key_frame_| will default to false.
//
// The shared memory will be mapped read-only.
//
// If mapping fails, nullptr will be returned.
static scoped_refptr<DecoderBuffer> FromSharedMemoryRegion(
base::subtle::PlatformSharedMemoryRegion region,
off_t offset,
size_t size);
// Create a DecoderBuffer where data() of |size| bytes resides within the
// ReadOnlySharedMemoryRegion referred to by |mapping| at non-negative offset
// |offset|. The buffer's |is_key_frame_| will default to false.
//
// Ownership of |region| is transferred to the buffer.
static scoped_refptr<DecoderBuffer> FromSharedMemoryRegion(
base::ReadOnlySharedMemoryRegion region,
off_t offset,
size_t size);
// Create a DecoderBuffer indicating we've reached end of stream.
//
// Calling any method other than end_of_stream() on the resulting buffer
// is disallowed.
static scoped_refptr<DecoderBuffer> CreateEOSBuffer();
base::TimeDelta timestamp() const {
DCHECK(!end_of_stream());
return timestamp_;
}
// TODO(dalecurtis): This should be renamed at some point, but to avoid a yak
// shave keep as a virtual with hacker_style() for now.
virtual void set_timestamp(base::TimeDelta timestamp);
base::TimeDelta duration() const {
DCHECK(!end_of_stream());
return duration_;
}
void set_duration(base::TimeDelta duration) {
DCHECK(!end_of_stream());
DCHECK(duration == kNoTimestamp ||
(duration >= base::TimeDelta() && duration != kInfiniteDuration))
<< duration.InSecondsF();
duration_ = duration;
}
const uint8_t* data() const {
DCHECK(!end_of_stream());
if (shared_mem_mapping_ && shared_mem_mapping_->IsValid())
return static_cast<const uint8_t*>(shared_mem_mapping_->memory());
if (shm_)
return static_cast<uint8_t*>(shm_->memory());
return data_.get();
}
// TODO(sandersd): Remove writable_data(). https://crbug.com/834088
uint8_t* writable_data() const {
DCHECK(!end_of_stream());
DCHECK(!shm_);
DCHECK(!shared_mem_mapping_);
return data_.get();
}
size_t data_size() const {
DCHECK(!end_of_stream());
return size_;
}
const uint8_t* side_data() const {
DCHECK(!end_of_stream());
return side_data_.get();
}
size_t side_data_size() const {
DCHECK(!end_of_stream());
return side_data_size_;
}
typedef std::pair<base::TimeDelta, base::TimeDelta> DiscardPadding;
const DiscardPadding& discard_padding() const {
DCHECK(!end_of_stream());
return discard_padding_;
}
void set_discard_padding(const DiscardPadding& discard_padding) {
DCHECK(!end_of_stream());
discard_padding_ = discard_padding;
}
// Returns DecryptConfig associated with |this|. Returns null iff |this| is
// not encrypted.
const DecryptConfig* decrypt_config() const {
DCHECK(!end_of_stream());
return decrypt_config_.get();
}
void set_decrypt_config(std::unique_ptr<DecryptConfig> decrypt_config) {
DCHECK(!end_of_stream());
decrypt_config_ = std::move(decrypt_config);
}
// If there's no data in this buffer, it represents end of stream.
bool end_of_stream() const { return !shared_mem_mapping_ && !shm_ && !data_; }
bool is_key_frame() const {
DCHECK(!end_of_stream());
return is_key_frame_;
}
void set_is_key_frame(bool is_key_frame) {
DCHECK(!end_of_stream());
is_key_frame_ = is_key_frame;
}
// Returns true if all fields in |buffer| matches this buffer
// including |data_| and |side_data_|.
bool MatchesForTesting(const DecoderBuffer& buffer) const;
// Returns a human-readable string describing |*this|.
std::string AsHumanReadableString(bool verbose = false) const;
// Replaces any existing side data with data copied from |side_data|.
void CopySideDataFrom(const uint8_t* side_data, size_t side_data_size);
protected:
friend class base::RefCountedThreadSafe<DecoderBuffer>;
// Allocates a buffer of size |size| >= 0 and copies |data| into it. If |data|
// is NULL then |data_| is set to NULL and |buffer_size_| to 0.
// |is_key_frame_| will default to false.
DecoderBuffer(const uint8_t* data,
size_t size,
const uint8_t* side_data,
size_t side_data_size);
DecoderBuffer(std::unique_ptr<uint8_t[]> data, size_t size);
DecoderBuffer(std::unique_ptr<UnalignedSharedMemory> shm, size_t size);
DecoderBuffer(std::unique_ptr<ReadOnlyUnalignedMapping> shared_mem_mapping,
size_t size);
virtual ~DecoderBuffer();
// Encoded data, if it is stored on the heap.
std::unique_ptr<uint8_t[]> data_;
private:
// Presentation time of the frame.
base::TimeDelta timestamp_;
// Presentation duration of the frame.
base::TimeDelta duration_;
// Size of the encoded data.
size_t size_;
// Side data. Used for alpha channel in VPx, and for text cues.
size_t side_data_size_;
std::unique_ptr<uint8_t[]> side_data_;
// Encoded data, if it is stored in a shared memory mapping.
std::unique_ptr<ReadOnlyUnalignedMapping> shared_mem_mapping_;
// Encoded data, if it is stored in SHM.
std::unique_ptr<UnalignedSharedMemory> shm_;
// Encryption parameters for the encoded data.
std::unique_ptr<DecryptConfig> decrypt_config_;
// Duration of (audio) samples from the beginning and end of this frame which
// should be discarded after decoding. A value of kInfiniteDuration for the
// first value indicates the entire frame should be discarded; the second
// value must be base::TimeDelta() in this case.
DiscardPadding discard_padding_;
// Whether the frame was marked as a keyframe in the container.
bool is_key_frame_;
// Constructor helper method for memory allocations.
void Initialize();
DISALLOW_COPY_AND_ASSIGN(DecoderBuffer);
};
} // namespace media
#endif // MEDIA_BASE_DECODER_BUFFER_H_
|