• 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 
5 #ifndef MEDIA_BASE_VIDEO_FRAME_H_
6 #define MEDIA_BASE_VIDEO_FRAME_H_
7 
8 #include <vector>
9 
10 #include "base/callback.h"
11 #include "base/md5.h"
12 #include "base/memory/shared_memory.h"
13 #include "base/synchronization/lock.h"
14 #include "media/base/buffers.h"
15 #include "ui/gfx/rect.h"
16 #include "ui/gfx/size.h"
17 
18 class SkBitmap;
19 
20 namespace gpu {
21 struct MailboxHolder;
22 }  // namespace gpu
23 
24 namespace media {
25 
26 class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
27  public:
28   enum {
29     kFrameSizeAlignment = 16,
30     kFrameSizePadding = 16,
31     kFrameAddressAlignment = 32
32   };
33 
34   enum {
35     kMaxPlanes = 4,
36 
37     kYPlane = 0,
38     kUPlane = 1,
39     kUVPlane = kUPlane,
40     kVPlane = 2,
41     kAPlane = 3,
42   };
43 
44   // Surface formats roughly based on FOURCC labels, see:
45   // http://www.fourcc.org/rgb.php
46   // http://www.fourcc.org/yuv.php
47   // Logged to UMA, so never reuse values.
48   enum Format {
49     UNKNOWN = 0,  // Unknown format value.
50     YV12 = 1,  // 12bpp YVU planar 1x1 Y, 2x2 VU samples
51     YV16 = 2,  // 16bpp YVU planar 1x1 Y, 2x1 VU samples
52     I420 = 3,  // 12bpp YVU planar 1x1 Y, 2x2 UV samples.
53     YV12A = 4,  // 20bpp YUVA planar 1x1 Y, 2x2 VU, 1x1 A samples.
54 #if defined(VIDEO_HOLE)
55     HOLE = 5,  // Hole frame.
56 #endif  // defined(VIDEO_HOLE)
57     NATIVE_TEXTURE = 6,  // Native texture.  Pixel-format agnostic.
58     YV12J = 7,  // JPEG color range version of YV12
59     NV12 = 8,  // 12bpp 1x1 Y plane followed by an interleaved 2x2 UV plane.
60     YV24 = 9,  // 24bpp YUV planar, no subsampling.
61     FORMAT_MAX = YV24,  // Must always be equal to largest entry logged.
62   };
63 
64   // Returns the name of a Format as a string.
65   static std::string FormatToString(Format format);
66 
67   // Creates a new frame in system memory with given parameters. Buffers for
68   // the frame are allocated but not initialized.
69   static scoped_refptr<VideoFrame> CreateFrame(
70       Format format,
71       const gfx::Size& coded_size,
72       const gfx::Rect& visible_rect,
73       const gfx::Size& natural_size,
74       base::TimeDelta timestamp);
75 
76   // Call prior to CreateFrame to ensure validity of frame configuration. Called
77   // automatically by VideoDecoderConfig::IsValidConfig().
78   // TODO(scherkus): VideoDecoderConfig shouldn't call this method
79   static bool IsValidConfig(Format format, const gfx::Size& coded_size,
80                             const gfx::Rect& visible_rect,
81                             const gfx::Size& natural_size);
82 
83   // CB to write pixels from the texture backing this frame into the
84   // |const SkBitmap&| parameter.
85   typedef base::Callback<void(const SkBitmap&)> ReadPixelsCB;
86 
87   // CB to be called on the mailbox backing this frame when the frame is
88   // destroyed.
89   typedef base::Callback<void(const std::vector<uint32>&)> ReleaseMailboxCB;
90 
91   // Wraps a native texture of the given parameters with a VideoFrame.  The
92   // backing of the VideoFrame is held in the mailbox held by |mailbox_holder|,
93   // and |mailbox_holder_release_cb| will be called with |mailbox_holder| as the
94   // argument when the VideoFrame is to be destroyed.
95   // |read_pixels_cb| may be used to do (slow!) readbacks from the
96   // texture to main memory.
97   static scoped_refptr<VideoFrame> WrapNativeTexture(
98       scoped_ptr<gpu::MailboxHolder> mailbox_holder,
99       const ReleaseMailboxCB& mailbox_holder_release_cb,
100       const gfx::Size& coded_size,
101       const gfx::Rect& visible_rect,
102       const gfx::Size& natural_size,
103       base::TimeDelta timestamp,
104       const ReadPixelsCB& read_pixels_cb);
105 
106   // Read pixels from the native texture backing |*this| and write
107   // them to |pixels| as BGRA.  |pixels| must point to a buffer at
108   // least as large as 4 * visible_rect().size().GetArea().
109   void ReadPixelsFromNativeTexture(const SkBitmap& pixels);
110 
111   // Wraps packed image data residing in a memory buffer with a VideoFrame.
112   // The image data resides in |data| and is assumed to be packed tightly in a
113   // buffer of logical dimensions |coded_size| with the appropriate bit depth
114   // and plane count as given by |format|.  The shared memory handle of the
115   // backing allocation, if present, can be passed in with |handle|.  When the
116   // frame is destroyed, |no_longer_needed_cb.Run()| will be called.
117   static scoped_refptr<VideoFrame> WrapExternalPackedMemory(
118       Format format,
119       const gfx::Size& coded_size,
120       const gfx::Rect& visible_rect,
121       const gfx::Size& natural_size,
122       uint8* data,
123       size_t data_size,
124       base::SharedMemoryHandle handle,
125       base::TimeDelta timestamp,
126       const base::Closure& no_longer_needed_cb);
127 
128 #if defined(OS_POSIX)
129   // Wraps provided dmabufs
130   // (https://www.kernel.org/doc/Documentation/dma-buf-sharing.txt) with a
131   // VideoFrame. The dmabuf fds are dup()ed on creation, so that the VideoFrame
132   // retains a reference to them, and are automatically close()d on destruction,
133   // dropping the reference. The caller may safely close() its reference after
134   // calling WrapExternalDmabufs().
135   // The image data is only accessible via dmabuf fds, which are usually passed
136   // directly to a hardware device and/or to another process, or can also be
137   // mapped via mmap() for CPU access.
138   // When the frame is destroyed, |no_longer_needed_cb.Run()| will be called.
139   static scoped_refptr<VideoFrame> WrapExternalDmabufs(
140       Format format,
141       const gfx::Size& coded_size,
142       const gfx::Rect& visible_rect,
143       const gfx::Size& natural_size,
144       const std::vector<int> dmabuf_fds,
145       base::TimeDelta timestamp,
146       const base::Closure& no_longer_needed_cb);
147 #endif
148 
149   // Wraps external YUV data of the given parameters with a VideoFrame.
150   // The returned VideoFrame does not own the data passed in. When the frame
151   // is destroyed |no_longer_needed_cb.Run()| will be called.
152   // TODO(sheu): merge this into WrapExternalSharedMemory().
153   // http://crbug.com/270217
154   static scoped_refptr<VideoFrame> WrapExternalYuvData(
155       Format format,
156       const gfx::Size& coded_size,
157       const gfx::Rect& visible_rect,
158       const gfx::Size& natural_size,
159       int32 y_stride,
160       int32 u_stride,
161       int32 v_stride,
162       uint8* y_data,
163       uint8* u_data,
164       uint8* v_data,
165       base::TimeDelta timestamp,
166       const base::Closure& no_longer_needed_cb);
167 
168   // Wraps |frame| and calls |no_longer_needed_cb| when the wrapper VideoFrame
169   // gets destroyed. |visible_rect| must be a sub rect within
170   // frame->visible_rect().
171   static scoped_refptr<VideoFrame> WrapVideoFrame(
172       const scoped_refptr<VideoFrame>& frame,
173       const gfx::Rect& visible_rect,
174       const gfx::Size& natural_size,
175       const base::Closure& no_longer_needed_cb);
176 
177   // Creates a frame which indicates end-of-stream.
178   static scoped_refptr<VideoFrame> CreateEOSFrame();
179 
180   // Allocates YV12 frame based on |size|, and sets its data to the YUV(y,u,v).
181   static scoped_refptr<VideoFrame> CreateColorFrame(
182       const gfx::Size& size,
183       uint8 y, uint8 u, uint8 v,
184       base::TimeDelta timestamp);
185 
186   // Allocates YV12 frame based on |size|, and sets its data to the YUV
187   // equivalent of RGB(0,0,0).
188   static scoped_refptr<VideoFrame> CreateBlackFrame(const gfx::Size& size);
189 
190 #if defined(VIDEO_HOLE)
191   // Allocates a hole frame.
192   static scoped_refptr<VideoFrame> CreateHoleFrame(const gfx::Size& size);
193 #endif  // defined(VIDEO_HOLE)
194 
195   static size_t NumPlanes(Format format);
196 
197   // Returns the required allocation size for a (tightly packed) frame of the
198   // given coded size and format.
199   static size_t AllocationSize(Format format, const gfx::Size& coded_size);
200 
201   // Returns the plane size for a plane of the given coded size and format.
202   static gfx::Size PlaneSize(Format format,
203                              size_t plane,
204                              const gfx::Size& coded_size);
205 
206   // Returns the required allocation size for a (tightly packed) plane of the
207   // given coded size and format.
208   static size_t PlaneAllocationSize(Format format,
209                                     size_t plane,
210                                     const gfx::Size& coded_size);
211 
212   // Returns horizontal bits per pixel for given |plane| and |format|.
213   static int PlaneHorizontalBitsPerPixel(Format format, size_t plane);
214 
format()215   Format format() const { return format_; }
216 
coded_size()217   const gfx::Size& coded_size() const { return coded_size_; }
visible_rect()218   const gfx::Rect& visible_rect() const { return visible_rect_; }
natural_size()219   const gfx::Size& natural_size() const { return natural_size_; }
220 
221   int stride(size_t plane) const;
222 
223   // Returns the number of bytes per row and number of rows for a given plane.
224   //
225   // As opposed to stride(), row_bytes() refers to the bytes representing
226   // frame data scanlines (coded_size.width() pixels, without stride padding).
227   int row_bytes(size_t plane) const;
228   int rows(size_t plane) const;
229 
230   // Returns pointer to the buffer for a given plane. The memory is owned by
231   // VideoFrame object and must not be freed by the caller.
232   uint8* data(size_t plane) const;
233 
234   // Returns the mailbox holder of the native texture wrapped by this frame.
235   // Only valid to call if this is a NATIVE_TEXTURE frame. Before using the
236   // mailbox, the caller must wait for the included sync point.
237   const gpu::MailboxHolder* mailbox_holder() const;
238 
239   // Returns the shared-memory handle, if present
240   base::SharedMemoryHandle shared_memory_handle() const;
241 
242 #if defined(OS_POSIX)
243   // Returns backing dmabuf file descriptor for given |plane|, if present.
244   int dmabuf_fd(size_t plane) const;
245 #endif
246 
247   // Returns true if this VideoFrame represents the end of the stream.
end_of_stream()248   bool end_of_stream() const { return end_of_stream_; }
249 
timestamp()250   base::TimeDelta timestamp() const {
251     return timestamp_;
252   }
set_timestamp(const base::TimeDelta & timestamp)253   void set_timestamp(const base::TimeDelta& timestamp) {
254     timestamp_ = timestamp;
255   }
256 
257   // Append |sync_point| into |release_sync_points_| which will be passed to
258   // the video decoder when |mailbox_holder_release_cb_| is called so that
259   // the video decoder waits for the sync points before reusing the mailbox.
260   // Multiple clients can append multiple sync points on one frame.
261   // This method is thread safe. Both blink and compositor threads can call it.
262   void AppendReleaseSyncPoint(uint32 sync_point);
263 
264   // Used to keep a running hash of seen frames.  Expects an initialized MD5
265   // context.  Calls MD5Update with the context and the contents of the frame.
266   void HashFrameForTesting(base::MD5Context* context);
267 
268  private:
269   friend class base::RefCountedThreadSafe<VideoFrame>;
270   // Clients must use the static CreateFrame() method to create a new frame.
271   VideoFrame(Format format,
272              const gfx::Size& coded_size,
273              const gfx::Rect& visible_rect,
274              const gfx::Size& natural_size,
275              scoped_ptr<gpu::MailboxHolder> mailbox_holder,
276              base::TimeDelta timestamp,
277              bool end_of_stream);
278   virtual ~VideoFrame();
279 
280   void AllocateYUV();
281 
282   // Used to DCHECK() plane parameters.
283   bool IsValidPlane(size_t plane) const;
284 
285   // Frame format.
286   const Format format_;
287 
288   // Width and height of the video frame, in pixels. This must include pixel
289   // data for the whole image; i.e. for YUV formats with subsampled chroma
290   // planes, in the case that the visible portion of the image does not line up
291   // on a sample boundary, |coded_size_| must be rounded up appropriately and
292   // the pixel data provided for the odd pixels.
293   const gfx::Size coded_size_;
294 
295   // Width, height, and offsets of the visible portion of the video frame. Must
296   // be a subrect of |coded_size_|. Can be odd with respect to the sample
297   // boundaries, e.g. for formats with subsampled chroma.
298   const gfx::Rect visible_rect_;
299 
300   // Width and height of the visible portion of the video frame
301   // (|visible_rect_.size()|) with aspect ratio taken into account.
302   const gfx::Size natural_size_;
303 
304   // Array of strides for each plane, typically greater or equal to the width
305   // of the surface divided by the horizontal sampling period.  Note that
306   // strides can be negative.
307   int32 strides_[kMaxPlanes];
308 
309   // Array of data pointers to each plane.
310   uint8* data_[kMaxPlanes];
311 
312   // Native texture mailbox, if this is a NATIVE_TEXTURE frame.
313   const scoped_ptr<gpu::MailboxHolder> mailbox_holder_;
314   ReleaseMailboxCB mailbox_holder_release_cb_;
315   ReadPixelsCB read_pixels_cb_;
316 
317   // Shared memory handle, if this frame was allocated from shared memory.
318   base::SharedMemoryHandle shared_memory_handle_;
319 
320 #if defined(OS_POSIX)
321   // Dmabufs for each plane, if this frame is wrapping memory
322   // acquired via dmabuf.
323   base::ScopedFD dmabuf_fds_[kMaxPlanes];
324 #endif
325 
326   base::Closure no_longer_needed_cb_;
327 
328   base::TimeDelta timestamp_;
329 
330   base::Lock release_sync_point_lock_;
331   std::vector<uint32> release_sync_points_;
332 
333   const bool end_of_stream_;
334 
335   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame);
336 };
337 
338 }  // namespace media
339 
340 #endif  // MEDIA_BASE_VIDEO_FRAME_H_
341