Home | History | Annotate | Download | only in base
      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