• 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 "base/callback.h"
9 #include "base/md5.h"
10 #include "base/memory/shared_memory.h"
11 #include "gpu/command_buffer/common/mailbox.h"
12 #include "media/base/buffers.h"
13 #include "ui/gfx/rect.h"
14 #include "ui/gfx/size.h"
15 
16 class SkBitmap;
17 
18 namespace media {
19 
20 class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
21  public:
22   enum {
23     kFrameSizeAlignment = 16,
24     kFrameSizePadding = 16,
25     kFrameAddressAlignment = 32
26   };
27 
28   enum {
29     kMaxPlanes = 4,
30 
31     kYPlane = 0,
32     kUPlane = 1,
33     kVPlane = 2,
34     kAPlane = 3,
35   };
36 
37   // Surface formats roughly based on FOURCC labels, see:
38   // http://www.fourcc.org/rgb.php
39   // http://www.fourcc.org/yuv.php
40   // Logged to UMA, so never reuse values.
41   enum Format {
42     UNKNOWN = 0,  // Unknown format value.
43     YV12 = 1,  // 12bpp YVU planar 1x1 Y, 2x2 VU samples
44     YV16 = 2,  // 16bpp YVU planar 1x1 Y, 2x1 VU samples
45     I420 = 3,  // 12bpp YVU planar 1x1 Y, 2x2 UV samples.
46     YV12A = 4,  // 20bpp YUVA planar 1x1 Y, 2x2 VU, 1x1 A samples.
47 #if defined(VIDEO_HOLE)
48     HOLE = 5,  // Hole frame.
49 #endif  // defined(VIDEO_HOLE)
50     NATIVE_TEXTURE = 6,  // Native texture.  Pixel-format agnostic.
51     YV12J = 7,  // JPEG color range version of YV12
52     HISTOGRAM_MAX,  // Must always be greatest.
53   };
54 
55   // Returns the name of a Format as a string.
56   static std::string FormatToString(Format format);
57 
58   // This class calls the TextureNoLongerNeededCallback when this class is
59   // destroyed.  Users can query the current sync point associated with this
60   // mailbox with sync_point(), and should call Resync() with a new sync point
61   // to ensure the mailbox remains valid for the issued commands.
62   // valid for the issued commands.
63   class MEDIA_EXPORT MailboxHolder {
64    public:
65     typedef base::Callback<void(uint32 sync_point)>
66         TextureNoLongerNeededCallback;
67 
68     MailboxHolder(const gpu::Mailbox& mailbox,
69                   unsigned sync_point,
70                   const TextureNoLongerNeededCallback& release_callback);
71     ~MailboxHolder();
72 
mailbox()73     const gpu::Mailbox& mailbox() const { return mailbox_; }
sync_point()74     unsigned sync_point() const { return sync_point_; }
75 
Resync(unsigned sync_point)76     void Resync(unsigned sync_point) { sync_point_ = sync_point; }
77 
78    private:
79 
80     gpu::Mailbox mailbox_;
81     unsigned sync_point_;
82     TextureNoLongerNeededCallback release_callback_;
83   };
84 
85 
86   // Creates a new frame in system memory with given parameters. Buffers for
87   // the frame are allocated but not initialized.
88   // |coded_size| is the width and height of the frame data in pixels.
89   // |visible_rect| is the visible portion of |coded_size|, after cropping (if
90   // any) is applied.
91   // |natural_size| is the width and height of the frame when the frame's aspect
92   // ratio is applied to |visible_rect|.
93   static scoped_refptr<VideoFrame> CreateFrame(
94       Format format,
95       const gfx::Size& coded_size,
96       const gfx::Rect& visible_rect,
97       const gfx::Size& natural_size,
98       base::TimeDelta timestamp);
99 
100   // Call prior to CreateFrame to ensure validity of frame configuration. Called
101   // automatically by VideoDecoderConfig::IsValidConfig().
102   // TODO(scherkus): VideoDecoderConfig shouldn't call this method
103   static bool IsValidConfig(Format format, const gfx::Size& coded_size,
104                             const gfx::Rect& visible_rect,
105                             const gfx::Size& natural_size);
106 
107   // CB to write pixels from the texture backing this frame into the
108   // |const SkBitmap&| parameter.
109   typedef base::Callback<void(const SkBitmap&)> ReadPixelsCB;
110 
111   // Wraps a native texture of the given parameters with a VideoFrame.  When the
112   // frame is destroyed |no_longer_needed_cb.Run()| will be called.
113   // |coded_size| is the width and height of the frame data in pixels.
114   // |visible_rect| is the visible portion of |coded_size|, after cropping (if
115   // any) is applied.
116   // |natural_size| is the width and height of the frame when the frame's aspect
117   // ratio is applied to |visible_rect|.
118 
119   // |read_pixels_cb| may be used to do (slow!) readbacks from the
120   // texture to main memory.
121   static scoped_refptr<VideoFrame> WrapNativeTexture(
122       scoped_ptr<MailboxHolder> mailbox_holder,
123       uint32 texture_target,
124       const gfx::Size& coded_size,
125       const gfx::Rect& visible_rect,
126       const gfx::Size& natural_size,
127       base::TimeDelta timestamp,
128       const ReadPixelsCB& read_pixels_cb,
129       const base::Closure& no_longer_needed_cb);
130 
131   // Read pixels from the native texture backing |*this| and write
132   // them to |pixels| as BGRA.  |pixels| must point to a buffer at
133   // least as large as 4*visible_rect().width()*visible_rect().height().
134   void ReadPixelsFromNativeTexture(const SkBitmap& pixels);
135 
136   // Wraps packed image data residing in a memory buffer with a VideoFrame.
137   // The image data resides in |data| and is assumed to be packed tightly in a
138   // buffer of logical dimensions |coded_size| with the appropriate bit depth
139   // and plane count as given by |format|.  The shared memory handle of the
140   // backing allocation, if present, can be passed in with |handle|.  When the
141   // frame is destroyed, |no_longer_needed_cb.Run()| will be called.
142   static scoped_refptr<VideoFrame> WrapExternalPackedMemory(
143       Format format,
144       const gfx::Size& coded_size,
145       const gfx::Rect& visible_rect,
146       const gfx::Size& natural_size,
147       uint8* data,
148       size_t data_size,
149       base::SharedMemoryHandle handle,
150       base::TimeDelta timestamp,
151       const base::Closure& no_longer_needed_cb);
152 
153   // Wraps external YUV data of the given parameters with a VideoFrame.
154   // The returned VideoFrame does not own the data passed in. When the frame
155   // is destroyed |no_longer_needed_cb.Run()| will be called.
156   // TODO(sheu): merge this into WrapExternalSharedMemory().
157   // http://crbug.com/270217
158   static scoped_refptr<VideoFrame> WrapExternalYuvData(
159       Format format,
160       const gfx::Size& coded_size,
161       const gfx::Rect& visible_rect,
162       const gfx::Size& natural_size,
163       int32 y_stride,
164       int32 u_stride,
165       int32 v_stride,
166       uint8* y_data,
167       uint8* u_data,
168       uint8* v_data,
169       base::TimeDelta timestamp,
170       const base::Closure& no_longer_needed_cb);
171 
172   // Wraps |frame| and calls |no_longer_needed_cb| when the wrapper VideoFrame
173   // gets destroyed.
174   static scoped_refptr<VideoFrame> WrapVideoFrame(
175       const scoped_refptr<VideoFrame>& frame,
176       const base::Closure& no_longer_needed_cb);
177 
178   // Creates a frame which indicates end-of-stream.
179   static scoped_refptr<VideoFrame> CreateEOSFrame();
180 
181   // Allocates YV12 frame based on |size|, and sets its data to the YUV(y,u,v).
182   static scoped_refptr<VideoFrame> CreateColorFrame(
183       const gfx::Size& size,
184       uint8 y, uint8 u, uint8 v,
185       base::TimeDelta timestamp);
186 
187   // Allocates YV12 frame based on |size|, and sets its data to the YUV
188   // equivalent of RGB(0,0,0).
189   static scoped_refptr<VideoFrame> CreateBlackFrame(const gfx::Size& size);
190 
191 #if defined(VIDEO_HOLE)
192   // Allocates a hole frame.
193   static scoped_refptr<VideoFrame> CreateHoleFrame(const gfx::Size& size);
194 #endif  // defined(VIDEO_HOLE)
195 
196   static size_t NumPlanes(Format format);
197 
198   // Returns the required allocation size for a (tightly packed) frame of the
199   // given coded size and format.
200   static size_t AllocationSize(Format format, const gfx::Size& coded_size);
201 
202   // Returns the required allocation size for a (tightly packed) plane of the
203   // given coded size and format.
204   static size_t PlaneAllocationSize(Format format,
205                                     size_t plane,
206                                     const gfx::Size& coded_size);
207 
format()208   Format format() const { return format_; }
209 
coded_size()210   const gfx::Size& coded_size() const { return coded_size_; }
visible_rect()211   const gfx::Rect& visible_rect() const { return visible_rect_; }
natural_size()212   const gfx::Size& natural_size() const { return natural_size_; }
213 
214   int stride(size_t plane) const;
215 
216   // Returns the number of bytes per row and number of rows for a given plane.
217   //
218   // As opposed to stride(), row_bytes() refers to the bytes representing
219   // frame data scanlines (coded_size.width() pixels, without stride padding).
220   int row_bytes(size_t plane) const;
221   int rows(size_t plane) const;
222 
223   // Returns pointer to the buffer for a given plane. The memory is owned by
224   // VideoFrame object and must not be freed by the caller.
225   uint8* data(size_t plane) const;
226 
227   // Returns the mailbox of the native texture wrapped by this frame. Only
228   // valid to call if this is a NATIVE_TEXTURE frame. Before using the
229   // mailbox, the caller must wait for the included sync point.
230   MailboxHolder* texture_mailbox() const;
231 
232   // Returns the texture target. Only valid for NATIVE_TEXTURE frames.
233   uint32 texture_target() const;
234 
235   // Returns the shared-memory handle, if present
236   base::SharedMemoryHandle shared_memory_handle() const;
237 
238   // Returns true if this VideoFrame represents the end of the stream.
end_of_stream()239   bool end_of_stream() const { return end_of_stream_; }
240 
GetTimestamp()241   base::TimeDelta GetTimestamp() const {
242     return timestamp_;
243   }
SetTimestamp(const base::TimeDelta & timestamp)244   void SetTimestamp(const base::TimeDelta& timestamp) {
245     timestamp_ = timestamp;
246   }
247 
248   // Used to keep a running hash of seen frames.  Expects an initialized MD5
249   // context.  Calls MD5Update with the context and the contents of the frame.
250   void HashFrameForTesting(base::MD5Context* context);
251 
252  private:
253   friend class base::RefCountedThreadSafe<VideoFrame>;
254   // Clients must use the static CreateFrame() method to create a new frame.
255   VideoFrame(Format format,
256              const gfx::Size& coded_size,
257              const gfx::Rect& visible_rect,
258              const gfx::Size& natural_size,
259              base::TimeDelta timestamp,
260              bool end_of_stream);
261   virtual ~VideoFrame();
262 
263   void AllocateYUV();
264 
265   // Used to DCHECK() plane parameters.
266   bool IsValidPlane(size_t plane) const;
267 
268   // Frame format.
269   Format format_;
270 
271   // Width and height of the video frame.
272   gfx::Size coded_size_;
273 
274   // Width, height, and offsets of the visible portion of the video frame.
275   gfx::Rect visible_rect_;
276 
277   // Width and height of the visible portion of the video frame with aspect
278   // ratio taken into account.
279   gfx::Size natural_size_;
280 
281   // Array of strides for each plane, typically greater or equal to the width
282   // of the surface divided by the horizontal sampling period.  Note that
283   // strides can be negative.
284   int32 strides_[kMaxPlanes];
285 
286   // Array of data pointers to each plane.
287   uint8* data_[kMaxPlanes];
288 
289   // Native texture mailbox, if this is a NATIVE_TEXTURE frame.
290   scoped_ptr<MailboxHolder> texture_mailbox_holder_;
291   uint32 texture_target_;
292   ReadPixelsCB read_pixels_cb_;
293 
294   // Shared memory handle, if this frame was allocated from shared memory.
295   base::SharedMemoryHandle shared_memory_handle_;
296 
297   base::Closure no_longer_needed_cb_;
298 
299   base::TimeDelta timestamp_;
300 
301   const bool end_of_stream_;
302 
303   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame);
304 };
305 
306 }  // namespace media
307 
308 #endif  // MEDIA_BASE_VIDEO_FRAME_H_
309