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