1 // Copyright (c) 2012 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 // Note: ported from Chromium commit head: 602bc8fa60fa 5 // Note: only necessary functions are ported. 6 // Note: some OS-specific defines have been removed 7 // Note: WrapExternalSharedMemory() has been removed in Chromium, but is still 8 // present here. Porting the code to a newer version of VideoFrame is not 9 // useful, as this is only a temporary step and all usage of VideoFrame will 10 // be removed. 11 12 #ifndef VIDEO_FRAME_H_ 13 #define VIDEO_FRAME_H_ 14 15 #include <stddef.h> 16 #include <stdint.h> 17 18 #include <memory> 19 #include <string> 20 #include <utility> 21 #include <vector> 22 23 #include "base/callback.h" 24 #include "base/logging.h" 25 #include "base/macros.h" 26 #include "base/memory/aligned_memory.h" 27 #include "base/memory/read_only_shared_memory_region.h" 28 #include "base/memory/ref_counted.h" 29 #include "base/memory/shared_memory.h" 30 #include "base/memory/shared_memory_handle.h" 31 #include "base/memory/unsafe_shared_memory_region.h" 32 #include "base/optional.h" 33 #include "base/synchronization/lock.h" 34 #include "base/thread_annotations.h" 35 #include "base/unguessable_token.h" 36 #include "rect.h" 37 #include "size.h" 38 #include "video_frame_layout.h" 39 #include "video_frame_metadata.h" 40 #include "video_pixel_format.h" 41 42 #include "base/files/scoped_file.h" 43 44 namespace media { 45 46 class VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { 47 public: 48 enum { 49 kFrameSizeAlignment = 16, 50 kFrameSizePadding = 16, 51 52 kFrameAddressAlignment = VideoFrameLayout::kBufferAddressAlignment 53 }; 54 55 enum { 56 kMaxPlanes = 4, 57 58 kYPlane = 0, 59 kARGBPlane = kYPlane, 60 kUPlane = 1, 61 kUVPlane = kUPlane, 62 kVPlane = 2, 63 kAPlane = 3, 64 }; 65 66 // Defines the pixel storage type. Differentiates between directly accessible 67 // |data_| and pixels that are only indirectly accessible and not via mappable 68 // memory. 69 // Note that VideoFrames of any StorageType can also have Texture backing, 70 // with "classical" GPU Driver-only textures identified as STORAGE_OPAQUE. 71 enum StorageType { 72 STORAGE_UNKNOWN = 0, 73 STORAGE_OPAQUE = 1, // We don't know how VideoFrame's pixels are stored. 74 STORAGE_UNOWNED_MEMORY = 2, // External, non owned data pointers. 75 STORAGE_OWNED_MEMORY = 3, // VideoFrame has allocated its own data buffer. 76 STORAGE_SHMEM = 4, // Pixels are backed by Shared Memory. 77 // TODO(mcasas): Consider turning this type into STORAGE_NATIVE 78 // based on the idea of using this same enum value for both DMA 79 // buffers on Linux and CVPixelBuffers on Mac (which currently use 80 // STORAGE_UNOWNED_MEMORY) and handle it appropriately in all cases. 81 STORAGE_DMABUFS = 5, // Each plane is stored into a DmaBuf. 82 STORAGE_MOJO_SHARED_BUFFER = 6, 83 STORAGE_LAST = STORAGE_MOJO_SHARED_BUFFER, 84 }; 85 86 // Call prior to CreateFrame to ensure validity of frame configuration. Called 87 // automatically by VideoDecoderConfig::IsValidConfig(). 88 static bool IsValidConfig(VideoPixelFormat format, 89 StorageType storage_type, 90 const Size& coded_size, 91 const Rect& visible_rect, 92 const Size& natural_size); 93 94 // Creates a new frame in system memory with given parameters. Buffers for the 95 // frame are allocated but not initialized. The caller must not make 96 // assumptions about the actual underlying size(s), but check the returned 97 // VideoFrame instead. 98 static scoped_refptr<VideoFrame> CreateFrame(VideoPixelFormat format, 99 const Size& coded_size, 100 const Rect& visible_rect, 101 const Size& natural_size, 102 base::TimeDelta timestamp); 103 104 // Creates a new frame in system memory with given parameters. Buffers for the 105 // frame are allocated but not initialized. The caller should specify the 106 // physical buffer size and strides if needed in |layout| parameter. 107 static scoped_refptr<VideoFrame> CreateFrameWithLayout( 108 const VideoFrameLayout& layout, 109 const Rect& visible_rect, 110 const Size& natural_size, 111 base::TimeDelta timestamp, 112 bool zero_initialize_memory); 113 114 // Legacy wrapping of old SharedMemoryHandle objects. Deprecated, use one of 115 // the shared memory region wrappers above instead. 116 static scoped_refptr<VideoFrame> WrapExternalSharedMemory( 117 VideoPixelFormat format, 118 const Size& coded_size, 119 const Rect& visible_rect, 120 const Size& natural_size, 121 uint8_t* data, 122 size_t data_size, 123 base::SharedMemoryHandle handle, 124 size_t shared_memory_offset, 125 base::TimeDelta timestamp); 126 127 // Creates a frame which indicates end-of-stream. 128 static scoped_refptr<VideoFrame> CreateEOSFrame(); 129 130 static size_t NumPlanes(VideoPixelFormat format); 131 132 // Returns the required allocation size for a (tightly packed) frame of the 133 // given coded size and format. 134 static size_t AllocationSize(VideoPixelFormat format, const Size& coded_size); 135 136 // Returns the plane Size (in bytes) for a plane of the given coded size 137 // and format. 138 static Size PlaneSize(VideoPixelFormat format, 139 size_t plane, 140 const Size& coded_size); 141 142 // Returns horizontal bits per pixel for given |plane| and |format|. 143 static int PlaneHorizontalBitsPerPixel(VideoPixelFormat format, size_t plane); 144 145 // Returns bits per pixel for given |plane| and |format|. 146 static int PlaneBitsPerPixel(VideoPixelFormat format, size_t plane); 147 148 // Returns the number of bytes per row for the given plane, format, and width. 149 // The width may be aligned to format requirements. 150 static size_t RowBytes(size_t plane, VideoPixelFormat format, int width); 151 152 // Returns the number of bytes per element for given |plane| and |format|. 153 static int BytesPerElement(VideoPixelFormat format, size_t plane); 154 155 // Calculates strides for each plane based on |format| and |coded_size|. 156 static std::vector<int32_t> ComputeStrides(VideoPixelFormat format, 157 const Size& coded_size); 158 159 // Returns the number of rows for the given plane, format, and height. 160 // The height may be aligned to format requirements. 161 static size_t Rows(size_t plane, VideoPixelFormat format, int height); 162 163 // Returns the number of columns for the given plane, format, and width. 164 // The width may be aligned to format requirements. 165 static size_t Columns(size_t plane, VideoPixelFormat format, int width); 166 167 // Returns true if |frame| is accesible mapped in the VideoFrame memory space. 168 // static 169 static bool IsStorageTypeMappable(VideoFrame::StorageType storage_type); 170 171 // Returns true if |frame| is accessible and mapped in the VideoFrame memory 172 // space. If false, clients should refrain from accessing data(), 173 // visible_data() etc. 174 bool IsMappable() const; 175 layout()176 const VideoFrameLayout& layout() const { return layout_; } 177 format()178 VideoPixelFormat format() const { return layout_.format(); } storage_type()179 StorageType storage_type() const { return storage_type_; } 180 181 // The full dimensions of the video frame data. coded_size()182 const Size& coded_size() const { return layout_.coded_size(); } 183 // A subsection of [0, 0, coded_size().width(), coded_size.height()]. This 184 // can be set to "soft-apply" a cropping. It determines the pointers into 185 // the data returned by visible_data(). visible_rect()186 const Rect& visible_rect() const { return visible_rect_; } 187 // Specifies that the |visible_rect| section of the frame is supposed to be 188 // scaled to this size when being presented. This can be used to represent 189 // anamorphic frames, or to "soft-apply" any custom scaling. natural_size()190 const Size& natural_size() const { return natural_size_; } 191 stride(size_t plane)192 int stride(size_t plane) const { 193 DCHECK(IsValidPlane(plane, format())); 194 DCHECK_LT(plane, layout_.num_planes()); 195 return layout_.planes()[plane].stride; 196 } 197 198 // Returns the number of bytes per row and number of rows for a given plane. 199 // 200 // As opposed to stride(), row_bytes() refers to the bytes representing 201 // frame data scanlines (coded_size.width() pixels, without stride padding). 202 int row_bytes(size_t plane) const; 203 int rows(size_t plane) const; 204 205 // Returns pointer to the buffer for a given plane, if this is an 206 // IsMappable() frame type. The memory is owned by VideoFrame object and must 207 // not be freed by the caller. data(size_t plane)208 const uint8_t* data(size_t plane) const { 209 DCHECK(IsValidPlane(plane, format())); 210 DCHECK(IsMappable()); 211 return data_[plane]; 212 } data(size_t plane)213 uint8_t* data(size_t plane) { 214 DCHECK(IsValidPlane(plane, format())); 215 DCHECK(IsMappable()); 216 return data_[plane]; 217 } 218 219 // Returns pointer to the data in the visible region of the frame, for 220 // IsMappable() storage types. The returned pointer is offsetted into the 221 // plane buffer specified by visible_rect().origin(). Memory is owned by 222 // VideoFrame object and must not be freed by the caller. 223 const uint8_t* visible_data(size_t plane) const; 224 uint8_t* visible_data(size_t plane); 225 226 // Returns a pointer to the read-only shared-memory region, if present. 227 base::ReadOnlySharedMemoryRegion* read_only_shared_memory_region() const; 228 229 // Returns a pointer to the unsafe shared memory handle, if present. 230 base::UnsafeSharedMemoryRegion* unsafe_shared_memory_region() const; 231 232 // Returns the legacy SharedMemoryHandle, if present. 233 base::SharedMemoryHandle shared_memory_handle() const; 234 235 // Returns the offset into the shared memory where the frame data begins. 236 size_t shared_memory_offset() const; 237 238 // Returns a vector containing the backing DmaBufs for this frame. The number 239 // of returned DmaBufs will be equal or less than the number of planes of 240 // the frame. If there are less, this means that the last FD contains the 241 // remaining planes. 242 // Note that the returned FDs are still owned by the VideoFrame. This means 243 // that the caller shall not close them, or use them after the VideoFrame is 244 // destroyed. For such use cases, use media::DuplicateFDs() to obtain your 245 // own copy of the FDs. 246 const std::vector<base::ScopedFD>& DmabufFds() const; 247 248 // Returns true if |frame| has DmaBufs. 249 bool HasDmaBufs() const; 250 251 void AddReadOnlySharedMemoryRegion(base::ReadOnlySharedMemoryRegion* region); 252 void AddUnsafeSharedMemoryRegion(base::UnsafeSharedMemoryRegion* region); 253 254 // Legacy, use one of the Add*SharedMemoryRegion methods above instead. 255 void AddSharedMemoryHandle(base::SharedMemoryHandle handle); 256 257 // Adds a callback to be run when the VideoFrame is about to be destroyed. 258 // The callback may be run from ANY THREAD, and so it is up to the client to 259 // ensure thread safety. Although read-only access to the members of this 260 // VideoFrame is permitted while the callback executes (including 261 // VideoFrameMetadata), clients should not assume the data pointers are 262 // valid. 263 void AddDestructionObserver(base::OnceClosure callback); 264 265 // Returns a dictionary of optional metadata. This contains information 266 // associated with the frame that downstream clients might use for frame-level 267 // logging, quality/performance optimizations, signaling, etc. 268 // 269 // TODO(miu): Move some of the "extra" members of VideoFrame (below) into 270 // here as a later clean-up step. metadata()271 const VideoFrameMetadata* metadata() const { return &metadata_; } metadata()272 VideoFrameMetadata* metadata() { return &metadata_; } 273 274 // The time span between the current frame and the first frame of the stream. 275 // This is the media timestamp, and not the reference time. 276 // See VideoFrameMetadata::REFERENCE_TIME for details. timestamp()277 base::TimeDelta timestamp() const { return timestamp_; } set_timestamp(base::TimeDelta timestamp)278 void set_timestamp(base::TimeDelta timestamp) { timestamp_ = timestamp; } 279 280 // Returns a human-readable string describing |*this|. 281 std::string AsHumanReadableString(); 282 283 // Unique identifier for this video frame; generated at construction time and 284 // guaranteed to be unique within a single process. unique_id()285 int unique_id() const { return unique_id_; } 286 287 // Returns the number of bits per channel. 288 size_t BitDepth() const; 289 290 protected: 291 friend class base::RefCountedThreadSafe<VideoFrame>; 292 293 // Clients must use the static factory/wrapping methods to create a new frame. 294 // Derived classes should create their own factory/wrapping methods, and use 295 // this constructor to do basic initialization. 296 VideoFrame(const VideoFrameLayout& layout, 297 StorageType storage_type, 298 const Rect& visible_rect, 299 const Size& natural_size, 300 base::TimeDelta timestamp); 301 302 virtual ~VideoFrame(); 303 304 // Creates a summary of the configuration settings provided as parameters. 305 static std::string ConfigToString(const VideoPixelFormat format, 306 const VideoFrame::StorageType storage_type, 307 const Size& coded_size, 308 const Rect& visible_rect, 309 const Size& natural_size); 310 311 // Returns true if |plane| is a valid plane index for the given |format|. 312 static bool IsValidPlane(size_t plane, VideoPixelFormat format); 313 314 // Returns |dimensions| adjusted to appropriate boundaries based on |format|. 315 static Size DetermineAlignedSize(VideoPixelFormat format, 316 const Size& dimensions); 317 set_data(size_t plane,uint8_t * ptr)318 void set_data(size_t plane, uint8_t* ptr) { 319 DCHECK(IsValidPlane(plane, format())); 320 DCHECK(ptr); 321 data_[plane] = ptr; 322 } 323 324 private: 325 static scoped_refptr<VideoFrame> WrapExternalStorage( 326 StorageType storage_type, 327 const VideoFrameLayout& layout, 328 const Rect& visible_rect, 329 const Size& natural_size, 330 uint8_t* data, 331 size_t data_size, 332 base::TimeDelta timestamp, 333 base::ReadOnlySharedMemoryRegion* read_only_region, 334 base::UnsafeSharedMemoryRegion* unsafe_region, 335 base::SharedMemoryHandle handle, 336 size_t data_offset); 337 338 static scoped_refptr<VideoFrame> CreateFrameInternal( 339 VideoPixelFormat format, 340 const Size& coded_size, 341 const Rect& visible_rect, 342 const Size& natural_size, 343 base::TimeDelta timestamp, 344 bool zero_initialize_memory); 345 346 bool SharedMemoryUninitialized(); 347 348 // Returns true if |plane| is a valid plane index for the given |format|. 349 static bool IsValidPlane(VideoPixelFormat format, size_t plane); 350 351 // Returns the pixel size of each subsample for a given |plane| and |format|. 352 // E.g. 2x2 for the U-plane in PIXEL_FORMAT_I420. 353 static Size SampleSize(VideoPixelFormat format, size_t plane); 354 355 // Return the alignment for the whole frame, calculated as the max of the 356 // alignment for each individual plane. 357 static Size CommonAlignment(VideoPixelFormat format); 358 359 void AllocateMemory(bool zero_initialize_memory); 360 361 // Calculates plane size. 362 // It first considers buffer size layout_ object provides. If layout's 363 // number of buffers equals to number of planes, and buffer size is assigned 364 // (non-zero), it returns buffers' size. 365 // Otherwise, it uses the first (num_buffers - 1) assigned buffers' size as 366 // plane size. Then for the rest unassigned planes, calculates their size 367 // based on format, coded size and stride for the plane. 368 std::vector<size_t> CalculatePlaneSize() const; 369 370 // VideFrameLayout (includes format, coded_size, and strides). 371 const VideoFrameLayout layout_; 372 373 // Storage type for the different planes. 374 StorageType storage_type_; // TODO(mcasas): make const 375 376 // Width, height, and offsets of the visible portion of the video frame. Must 377 // be a subrect of |coded_size_|. Can be odd with respect to the sample 378 // boundaries, e.g. for formats with subsampled chroma. 379 const Rect visible_rect_; 380 381 // Width and height of the visible portion of the video frame 382 // (|visible_rect_.size()|) with aspect ratio taken into account. 383 const Size natural_size_; 384 385 // Array of data pointers to each plane. 386 // TODO(mcasas): we don't know on ctor if we own |data_| or not. Change 387 // to std::unique_ptr<uint8_t, AlignedFreeDeleter> after refactoring 388 // VideoFrame. 389 uint8_t* data_[kMaxPlanes]; 390 391 // Shared memory handle and associated offset inside it, if this frame is a 392 // STORAGE_SHMEM one. Pointers to unowned shared memory regions. At most one 393 // of the memory regions will be set. 394 base::ReadOnlySharedMemoryRegion* read_only_shared_memory_region_ = nullptr; 395 base::UnsafeSharedMemoryRegion* unsafe_shared_memory_region_ = nullptr; 396 397 // Legacy handle. 398 base::SharedMemoryHandle shared_memory_handle_; 399 400 // If this is a STORAGE_SHMEM frame, the offset of the data within the shared 401 // memory. 402 size_t shared_memory_offset_; 403 404 class DmabufHolder; 405 406 // Dmabufs for the frame, used when storage is STORAGE_DMABUFS. Size is either 407 // equal or less than the number of planes of the frame. If it is less, then 408 // the memory area represented by the last FD contains the remaining planes. 409 std::vector<base::ScopedFD> dmabuf_fds_; 410 411 std::vector<base::OnceClosure> done_callbacks_; 412 413 base::TimeDelta timestamp_; 414 415 VideoFrameMetadata metadata_; 416 417 // Generated at construction time. 418 const int unique_id_; 419 420 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame); 421 }; 422 423 } // namespace media 424 425 #endif // VIDEO_FRAME_H_ 426