• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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