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.
5 #ifndef MEDIA_BASE_VIDEO_FRAME_H_
6 #define MEDIA_BASE_VIDEO_FRAME_H_
10 #include "base/callback.h"
12 #include "base/memory/shared_memory.h"
13 #include "base/synchronization/lock.h"
14 #include "gpu/command_buffer/common/mailbox_holder.h"
15 #include "media/base/buffers.h"
16 #include "media/base/video_frame_metadata.h"
17 #include "ui/gfx/geometry/rect.h"
18 #include "ui/gfx/geometry/size.h"
20 #if defined(OS_MACOSX)
21 #include <CoreVideo/CVPixelBuffer.h>
22 #include "base/mac/scoped_cftyperef.h"
27 class MEDIA_EXPORT VideoFrame
: public base::RefCountedThreadSafe
<VideoFrame
> {
30 kFrameSizeAlignment
= 16,
31 kFrameSizePadding
= 16,
32 kFrameAddressAlignment
= 32
46 // Pixel formats roughly based on FOURCC labels, see:
47 // http://www.fourcc.org/rgb.php and http://www.fourcc.org/yuv.php
48 // Logged to UMA, so never reuse values. Leave gaps if necessary.
50 UNKNOWN
= 0, // Unknown or unspecified format value.
51 YV12
= 1, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
52 I420
= 2, // 12bpp YUV planar 1x1 Y, 2x2 UV samples, a.k.a. YU12.
53 YV16
= 3, // 16bpp YVU planar 1x1 Y, 2x1 VU samples.
54 YV12A
= 4, // 20bpp YUVA planar 1x1 Y, 2x2 VU, 1x1 A samples.
55 YV24
= 5, // 24bpp YUV planar, no subsampling.
56 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
57 NV12
= 6, // 12bpp with Y plane followed by a 2x2 interleaved UV plane.
59 ARGB
= 7, // 32bpp ARGB, 1 plane.
60 XRGB
= 8, // 24bpp XRGB, 1 plane.
61 // Please update UMA histogram enumeration when adding new formats here.
62 FORMAT_MAX
= XRGB
, // Must always be equal to largest entry logged.
65 // Color space or color range used for the pixels, in general this is left
66 // unspecified, meaning Rec601 (SD) is assumed.
67 // Logged to UMA, so never reuse values. Leave gaps if necessary.
69 COLOR_SPACE_UNSPECIFIED
= 0, // In general this is Rec601.
70 COLOR_SPACE_JPEG
= 1, // JPEG color range.
71 COLOR_SPACE_HD_REC709
= 2, // Rec709 "HD" color space.
72 COLOR_SPACE_MAX
= COLOR_SPACE_HD_REC709
,
75 // Defines the pixel storage type. Differentiates between directly accessible
76 // |data_| and pixels that are only indirectly accessible and not via mappable
78 // Note that VideoFrames of any StorageType can also have Texture backing,
79 // with "classical" GPU Driver-only textures identified as STORAGE_OPAQUE.
82 STORAGE_OPAQUE
= 1, // We don't know how VideoFrame's pixels are stored.
83 STORAGE_UNOWNED_MEMORY
= 2, // External, non owned data pointers.
84 STORAGE_OWNED_MEMORY
= 3, // VideoFrame has allocated its own data buffer.
85 STORAGE_SHMEM
= 4, // Pixels are backed by Shared Memory.
87 STORAGE_DMABUFS
= 5, // Each plane is stored into a DmaBuf.
89 #if defined(VIDEO_HOLE)
90 STORAGE_HOLE
= 6, // Opaque storage.
94 // CB to be called on the mailbox backing this frame when the frame is
96 typedef base::Callback
<void(uint32
)> ReleaseMailboxCB
;
98 // Returns the name of a Format as a string.
99 static std::string
FormatToString(Format format
);
101 // Returns true if |format| is a YUV format. This includes (multi)planar
102 // and/or (partially) interleaved formats.
103 static bool IsYuvPlanar(Format format
);
105 // Call prior to CreateFrame to ensure validity of frame configuration. Called
106 // automatically by VideoDecoderConfig::IsValidConfig().
107 // TODO(scherkus): VideoDecoderConfig shouldn't call this method
108 static bool IsValidConfig(Format format
,
109 StorageType storage_type
,
110 const gfx::Size
& coded_size
,
111 const gfx::Rect
& visible_rect
,
112 const gfx::Size
& natural_size
);
114 // Creates a new YUV frame in system memory with given parameters (|format|
115 // must be YUV). Buffers for the frame are allocated but not initialized. The
116 // caller most not make assumptions about the actual underlying size(s), but
117 // check the returned VideoFrame instead.
118 // TODO(mcasas): implement the RGB version of this factory method.
119 static scoped_refptr
<VideoFrame
> CreateFrame(
121 const gfx::Size
& coded_size
,
122 const gfx::Rect
& visible_rect
,
123 const gfx::Size
& natural_size
,
124 base::TimeDelta timestamp
);
126 // Wraps a native texture of the given parameters with a VideoFrame.
127 // The backing of the VideoFrame is held in the mailbox held by
128 // |mailbox_holder|, and |mailbox_holder_release_cb| will be called with
129 // a syncpoint as the argument when the VideoFrame is to be destroyed.
130 static scoped_refptr
<VideoFrame
> WrapNativeTexture(
132 const gpu::MailboxHolder
& mailbox_holder
,
133 const ReleaseMailboxCB
& mailbox_holder_release_cb
,
134 const gfx::Size
& coded_size
,
135 const gfx::Rect
& visible_rect
,
136 const gfx::Size
& natural_size
,
137 base::TimeDelta timestamp
);
139 // Wraps a set of native textures representing YUV data with a VideoFrame.
140 // |mailbox_holders_release_cb| will be called with a syncpoint as the
141 // argument when the VideoFrame is to be destroyed.
142 static scoped_refptr
<VideoFrame
> WrapYUV420NativeTextures(
143 const gpu::MailboxHolder
& y_mailbox_holder
,
144 const gpu::MailboxHolder
& u_mailbox_holder
,
145 const gpu::MailboxHolder
& v_mailbox_holder
,
146 const ReleaseMailboxCB
& mailbox_holders_release_cb
,
147 const gfx::Size
& coded_size
,
148 const gfx::Rect
& visible_rect
,
149 const gfx::Size
& natural_size
,
150 base::TimeDelta timestamp
);
152 // Wraps packed image data residing in a memory buffer with a VideoFrame.
153 // The image data resides in |data| and is assumed to be packed tightly in a
154 // buffer of logical dimensions |coded_size| with the appropriate bit depth
155 // and plane count as given by |format|. Returns NULL on failure.
156 static scoped_refptr
<VideoFrame
> WrapExternalData(
158 const gfx::Size
& coded_size
,
159 const gfx::Rect
& visible_rect
,
160 const gfx::Size
& natural_size
,
163 base::TimeDelta timestamp
);
165 // Same as WrapExternalData() with SharedMemoryHandle and its offset.
166 static scoped_refptr
<VideoFrame
> WrapExternalSharedMemory(
168 const gfx::Size
& coded_size
,
169 const gfx::Rect
& visible_rect
,
170 const gfx::Size
& natural_size
,
173 base::SharedMemoryHandle handle
,
174 size_t shared_memory_offset
,
175 base::TimeDelta timestamp
);
177 // Wraps external YUV data of the given parameters with a VideoFrame.
178 // The returned VideoFrame does not own the data passed in.
179 static scoped_refptr
<VideoFrame
> WrapExternalYuvData(
181 const gfx::Size
& coded_size
,
182 const gfx::Rect
& visible_rect
,
183 const gfx::Size
& natural_size
,
190 base::TimeDelta timestamp
);
192 #if defined(OS_LINUX)
193 // Wraps provided dmabufs
194 // (https://www.kernel.org/doc/Documentation/dma-buf-sharing.txt) with a
195 // VideoFrame. The dmabuf fds are dup()ed on creation, so that the VideoFrame
196 // retains a reference to them, and are automatically close()d on destruction,
197 // dropping the reference. The caller may safely close() its reference after
198 // calling WrapExternalDmabufs().
199 // The image data is only accessible via dmabuf fds, which are usually passed
200 // directly to a hardware device and/or to another process, or can also be
201 // mapped via mmap() for CPU access.
202 // Returns NULL on failure.
203 static scoped_refptr
<VideoFrame
> WrapExternalDmabufs(
205 const gfx::Size
& coded_size
,
206 const gfx::Rect
& visible_rect
,
207 const gfx::Size
& natural_size
,
208 const std::vector
<int>& dmabuf_fds
,
209 base::TimeDelta timestamp
);
212 #if defined(OS_MACOSX)
213 // Wraps a provided CVPixelBuffer with a VideoFrame. The pixel buffer is
214 // retained for the lifetime of the VideoFrame and released upon destruction.
215 // The image data is only accessible via the pixel buffer, which could be
216 // backed by an IOSurface from another process. All the attributes of the
217 // VideoFrame are derived from the pixel buffer, with the exception of the
218 // timestamp. If information is missing or is incompatible (for example, a
219 // pixel format that has no VideoFrame match), NULL is returned.
220 // http://crbug.com/401308
221 static scoped_refptr
<VideoFrame
> WrapCVPixelBuffer(
222 CVPixelBufferRef cv_pixel_buffer
,
223 base::TimeDelta timestamp
);
226 // Wraps |frame|. |visible_rect| must be a sub rect within
227 // frame->visible_rect().
228 static scoped_refptr
<VideoFrame
> WrapVideoFrame(
229 const scoped_refptr
<VideoFrame
>& frame
,
230 const gfx::Rect
& visible_rect
,
231 const gfx::Size
& natural_size
);
233 // Creates a frame which indicates end-of-stream.
234 static scoped_refptr
<VideoFrame
> CreateEOSFrame();
236 // Allocates YV12 frame based on |size|, and sets its data to the YUV(y,u,v).
237 static scoped_refptr
<VideoFrame
> CreateColorFrame(
238 const gfx::Size
& size
,
239 uint8 y
, uint8 u
, uint8 v
,
240 base::TimeDelta timestamp
);
242 // Allocates YV12 frame based on |size|, and sets its data to the YUV
243 // equivalent of RGB(0,0,0).
244 static scoped_refptr
<VideoFrame
> CreateBlackFrame(const gfx::Size
& size
);
246 // Allocates YV12A frame based on |size|, and sets its data to the YUVA
247 // equivalent of RGBA(0,0,0,0).
248 static scoped_refptr
<VideoFrame
> CreateTransparentFrame(
249 const gfx::Size
& size
);
251 #if defined(VIDEO_HOLE)
252 // Allocates a hole frame.
253 static scoped_refptr
<VideoFrame
> CreateHoleFrame(const gfx::Size
& size
);
254 #endif // defined(VIDEO_HOLE)
256 static size_t NumPlanes(Format format
);
258 // Returns the required allocation size for a (tightly packed) frame of the
259 // given coded size and format.
260 static size_t AllocationSize(Format format
, const gfx::Size
& coded_size
);
262 // Returns the plane size (in bytes) for a plane of the given coded size and
264 static gfx::Size
PlaneSize(Format format
,
266 const gfx::Size
& coded_size
);
268 // Returns the required allocation size for a (tightly packed) plane of the
269 // given coded size and format.
270 static size_t PlaneAllocationSize(Format format
,
272 const gfx::Size
& coded_size
);
274 // Returns horizontal bits per pixel for given |plane| and |format|.
275 static int PlaneHorizontalBitsPerPixel(Format format
, size_t plane
);
277 // Returns bits per pixel for given |plane| and |format|.
278 static int PlaneBitsPerPixel(Format format
, size_t plane
);
280 // Returns the number of bytes per row for the given plane, format, and width.
281 // The width may be aligned to format requirements.
282 static size_t RowBytes(size_t plane
, Format format
, int width
);
284 // Returns the number of rows for the given plane, format, and height.
285 // The height may be aligned to format requirements.
286 static size_t Rows(size_t plane
, Format format
, int height
);
288 // Returns the number of columns for the given plane, format, and width.
289 // The width may be aligned to format requirements.
290 static size_t Columns(size_t plane
, Format format
, int width
);
292 // Returns true if |frame| is accessible and mapped in the VideoFrame memory
293 // space. If false, clients should refrain from accessing data(),
294 // visible_data() etc.
295 bool IsMappable() const;
297 // Returns true if |frame| has textures with any StorageType and should not be
298 // accessed via data(), visible_data() etc.
299 bool HasTextures() const;
301 Format
format() const { return format_
; }
302 StorageType
storage_type() const { return storage_type_
; }
304 const gfx::Size
& coded_size() const { return coded_size_
; }
305 const gfx::Rect
& visible_rect() const { return visible_rect_
; }
306 const gfx::Size
& natural_size() const { return natural_size_
; }
308 int stride(size_t plane
) const;
310 // Returns the number of bytes per row and number of rows for a given plane.
312 // As opposed to stride(), row_bytes() refers to the bytes representing
313 // frame data scanlines (coded_size.width() pixels, without stride padding).
314 int row_bytes(size_t plane
) const;
315 int rows(size_t plane
) const;
317 // Returns pointer to the buffer for a given plane, if this is an
318 // IsMappable() frame type. The memory is owned by VideoFrame object and must
319 // not be freed by the caller.
320 const uint8
* data(size_t plane
) const;
321 uint8
* data(size_t plane
);
323 // Returns pointer to the data in the visible region of the frame, for
324 // IsMappable() storage types. The returned pointer is offsetted into the
325 // plane buffer specified by visible_rect().origin(). Memory is owned by
326 // VideoFrame object and must not be freed by the caller.
327 const uint8
* visible_data(size_t plane
) const;
328 uint8
* visible_data(size_t plane
);
330 // Returns a mailbox holder for a given texture.
331 // Only valid to call if this is a NATIVE_TEXTURE frame. Before using the
332 // mailbox, the caller must wait for the included sync point.
333 const gpu::MailboxHolder
& mailbox_holder(size_t texture_index
) const;
335 // Returns the shared-memory handle, if present
336 base::SharedMemoryHandle
shared_memory_handle() const;
338 // Returns the offset into the shared memory where the frame data begins.
339 size_t shared_memory_offset() const;
341 #if defined(OS_LINUX)
342 // Returns backing DmaBuf file descriptor for given |plane|, if present, or
344 // TODO(mcasas): Rename to DmabufFd() to comply with Style Guide.
345 int dmabuf_fd(size_t plane
) const;
347 // Duplicates internally the |fds_in|, overwriting the current ones. Returns
348 // false if something goes wrong, and leaves all internal fds closed.
349 bool DuplicateFileDescriptors(const std::vector
<int>& fds_in
);
352 void AddSharedMemoryHandle(base::SharedMemoryHandle handle
,
353 size_t shared_memory_offset
);
355 #if defined(OS_MACOSX)
356 // Returns the backing CVPixelBuffer, if present.
357 // TODO(mcasas): Rename to CvPixelBuffer() to comply with Style Guide.
358 CVPixelBufferRef
cv_pixel_buffer() const;
361 // Adds a callback to be run when the VideoFrame is about to be destroyed.
362 // The callback may be run from ANY THREAD, and so it is up to the client to
363 // ensure thread safety. Although read-only access to the members of this
364 // VideoFrame is permitted while the callback executes (including
365 // VideoFrameMetadata), clients should not assume the data pointers are
367 void AddDestructionObserver(const base::Closure
& callback
);
369 // Returns a dictionary of optional metadata. This contains information
370 // associated with the frame that downstream clients might use for frame-level
371 // logging, quality/performance optimizations, signaling, etc.
373 // TODO(miu): Move some of the "extra" members of VideoFrame (below) into
374 // here as a later clean-up step.
375 const VideoFrameMetadata
* metadata() const { return &metadata_
; }
376 VideoFrameMetadata
* metadata() { return &metadata_
; }
378 base::TimeDelta
timestamp() const { return timestamp_
; }
379 void set_timestamp(base::TimeDelta timestamp
) {
380 timestamp_
= timestamp
;
383 class SyncPointClient
{
386 virtual uint32
InsertSyncPoint() = 0;
387 virtual void WaitSyncPoint(uint32 sync_point
) = 0;
390 virtual ~SyncPointClient() {}
392 DISALLOW_COPY_AND_ASSIGN(SyncPointClient
);
394 // It uses |client| to insert a new sync point and potentially waits on a
395 // older sync point. The final sync point will be used to release this
397 // This method is thread safe. Both blink and compositor threads can call it.
398 void UpdateReleaseSyncPoint(SyncPointClient
* client
);
400 // Used to keep a running hash of seen frames. Expects an initialized MD5
401 // context. Calls MD5Update with the context and the contents of the frame.
402 void HashFrameForTesting(base::MD5Context
* context
);
405 friend class base::RefCountedThreadSafe
<VideoFrame
>;
407 // Clients must use the static factory/wrapping methods to create a new frame.
408 VideoFrame(Format format
,
409 StorageType storage_type
,
410 const gfx::Size
& coded_size
,
411 const gfx::Rect
& visible_rect
,
412 const gfx::Size
& natural_size
,
413 base::TimeDelta timestamp
);
414 VideoFrame(Format format
,
415 StorageType storage_type
,
416 const gfx::Size
& coded_size
,
417 const gfx::Rect
& visible_rect
,
418 const gfx::Size
& natural_size
,
419 base::TimeDelta timestamp
,
420 base::SharedMemoryHandle handle
,
421 size_t shared_memory_offset
);
422 VideoFrame(Format format
,
423 StorageType storage_type
,
424 const gfx::Size
& coded_size
,
425 const gfx::Rect
& visible_rect
,
426 const gfx::Size
& natural_size
,
427 const gpu::MailboxHolder(&mailbox_holders
)[kMaxPlanes
],
428 const ReleaseMailboxCB
& mailbox_holder_release_cb
,
429 base::TimeDelta timestamp
);
430 virtual ~VideoFrame();
432 static scoped_refptr
<VideoFrame
> WrapExternalStorage(
434 StorageType storage_type
,
435 const gfx::Size
& coded_size
,
436 const gfx::Rect
& visible_rect
,
437 const gfx::Size
& natural_size
,
440 base::TimeDelta timestamp
,
441 base::SharedMemoryHandle handle
,
447 const Format format_
;
449 // Storage type for the different planes.
450 StorageType storage_type_
; // TODO(mcasas): make const
452 // Width and height of the video frame, in pixels. This must include pixel
453 // data for the whole image; i.e. for YUV formats with subsampled chroma
454 // planes, in the case that the visible portion of the image does not line up
455 // on a sample boundary, |coded_size_| must be rounded up appropriately and
456 // the pixel data provided for the odd pixels.
457 const gfx::Size coded_size_
;
459 // Width, height, and offsets of the visible portion of the video frame. Must
460 // be a subrect of |coded_size_|. Can be odd with respect to the sample
461 // boundaries, e.g. for formats with subsampled chroma.
462 const gfx::Rect visible_rect_
;
464 // Width and height of the visible portion of the video frame
465 // (|visible_rect_.size()|) with aspect ratio taken into account.
466 const gfx::Size natural_size_
;
468 // Array of strides for each plane, typically greater or equal to the width
469 // of the surface divided by the horizontal sampling period. Note that
470 // strides can be negative.
471 int32 strides_
[kMaxPlanes
];
473 // Array of data pointers to each plane.
474 // TODO(mcasas): we don't know on ctor if we own |data_| or not. After
475 // refactoring VideoFrame, change to scoped_ptr<uint8, AlignedFreeDeleter>.
476 uint8
* data_
[kMaxPlanes
];
478 // Native texture mailboxes, if this is a IsTexture() frame.
479 gpu::MailboxHolder mailbox_holders_
[kMaxPlanes
];
480 ReleaseMailboxCB mailbox_holders_release_cb_
;
482 // Shared memory handle and associated offset inside it, if this frame is
483 // a STORAGE_SHMEM one.
484 base::SharedMemoryHandle shared_memory_handle_
;
485 size_t shared_memory_offset_
;
487 #if defined(OS_LINUX)
488 // Dmabufs for each plane. If set, this frame has DmaBuf backing in some way.
489 base::ScopedFD dmabuf_fds_
[kMaxPlanes
];
492 #if defined(OS_MACOSX)
493 // CVPixelBuffer, if this frame is wrapping one.
494 base::ScopedCFTypeRef
<CVPixelBufferRef
> cv_pixel_buffer_
;
497 std::vector
<base::Closure
> done_callbacks_
;
499 base::TimeDelta timestamp_
;
501 base::Lock release_sync_point_lock_
;
502 uint32 release_sync_point_
;
504 VideoFrameMetadata metadata_
;
506 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame
);
511 #endif // MEDIA_BASE_VIDEO_FRAME_H_