Home | History | Annotate | Download | only in filters
      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_FILTERS_GPU_VIDEO_DECODER_H_
      6 #define MEDIA_FILTERS_GPU_VIDEO_DECODER_H_
      7 
      8 #include <list>
      9 #include <map>
     10 #include <set>
     11 #include <utility>
     12 #include <vector>
     13 
     14 #include "base/memory/weak_ptr.h"
     15 #include "media/base/pipeline_status.h"
     16 #include "media/base/video_decoder.h"
     17 #include "media/video/video_decode_accelerator.h"
     18 
     19 template <class T> class scoped_refptr;
     20 
     21 namespace base {
     22 class MessageLoopProxy;
     23 class SharedMemory;
     24 }
     25 
     26 namespace media {
     27 
     28 class DecoderBuffer;
     29 class GpuVideoDecoderFactories;
     30 
     31 // GPU-accelerated video decoder implementation.  Relies on
     32 // AcceleratedVideoDecoderMsg_Decode and friends.
     33 class MEDIA_EXPORT GpuVideoDecoder
     34     : public VideoDecoder,
     35       public VideoDecodeAccelerator::Client {
     36  public:
     37   // The message loop of |factories| will be saved to |gvd_loop_proxy_|.
     38   explicit GpuVideoDecoder(
     39       const scoped_refptr<GpuVideoDecoderFactories>& factories);
     40 
     41   // VideoDecoder implementation.
     42   virtual void Initialize(const VideoDecoderConfig& config,
     43                           const PipelineStatusCB& status_cb) OVERRIDE;
     44   virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
     45                       const DecodeCB& decode_cb) OVERRIDE;
     46   virtual void Reset(const base::Closure& closure) OVERRIDE;
     47   virtual void Stop(const base::Closure& closure) OVERRIDE;
     48   virtual bool HasAlpha() const OVERRIDE;
     49   virtual bool NeedsBitstreamConversion() const OVERRIDE;
     50   virtual bool CanReadWithoutStalling() const OVERRIDE;
     51 
     52   // VideoDecodeAccelerator::Client implementation.
     53   virtual void NotifyInitializeDone() OVERRIDE;
     54   virtual void ProvidePictureBuffers(uint32 count,
     55                                      const gfx::Size& size,
     56                                      uint32 texture_target) OVERRIDE;
     57   virtual void DismissPictureBuffer(int32 id) OVERRIDE;
     58   virtual void PictureReady(const media::Picture& picture) OVERRIDE;
     59   virtual void NotifyEndOfBitstreamBuffer(int32 id) OVERRIDE;
     60   virtual void NotifyFlushDone() OVERRIDE;
     61   virtual void NotifyResetDone() OVERRIDE;
     62   virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE;
     63 
     64  protected:
     65   virtual ~GpuVideoDecoder();
     66 
     67  private:
     68   enum State {
     69     kNormal,
     70     kDrainingDecoder,
     71     kDecoderDrained,
     72     kError
     73   };
     74 
     75   // Return true if more decode work can be piled on to the VDA.
     76   bool CanMoreDecodeWorkBeDone();
     77 
     78   // Enqueue a frame for later delivery (or drop it on the floor if a
     79   // vda->Reset() is in progress) and trigger out-of-line delivery of the oldest
     80   // ready frame to the client if there is a pending read.  A NULL |frame|
     81   // merely triggers delivery, and requires the ready_video_frames_ queue not be
     82   // empty.
     83   void EnqueueFrameAndTriggerFrameDelivery(
     84       const scoped_refptr<VideoFrame>& frame);
     85 
     86   // Indicate the picture buffer can be reused by the decoder.
     87   void ReusePictureBuffer(int64 picture_buffer_id, uint32 sync_point);
     88 
     89   void RecordBufferData(
     90       const BitstreamBuffer& bitstream_buffer, const DecoderBuffer& buffer);
     91   void GetBufferData(int32 id, base::TimeDelta* timetamp,
     92                      gfx::Rect* visible_rect, gfx::Size* natural_size);
     93 
     94   void DestroyVDA();
     95 
     96   // A shared memory segment and its allocated size.
     97   struct SHMBuffer {
     98     SHMBuffer(base::SharedMemory* m, size_t s);
     99     ~SHMBuffer();
    100     base::SharedMemory* shm;
    101     size_t size;
    102   };
    103 
    104   // Request a shared-memory segment of at least |min_size| bytes.  Will
    105   // allocate as necessary.  Caller does not own returned pointer.
    106   SHMBuffer* GetSHM(size_t min_size);
    107 
    108   // Return a shared-memory segment to the available pool.
    109   void PutSHM(SHMBuffer* shm_buffer);
    110 
    111   void DestroyTextures();
    112 
    113   bool needs_bitstream_conversion_;
    114 
    115   // Message loop which this class and |factories_| run on.
    116   scoped_refptr<base::MessageLoopProxy> gvd_loop_proxy_;
    117   base::WeakPtrFactory<GpuVideoDecoder> weak_factory_;
    118   base::WeakPtr<GpuVideoDecoder> weak_this_;
    119 
    120   scoped_refptr<GpuVideoDecoderFactories> factories_;
    121 
    122   // Populated during Initialize() (on success) and unchanged until an error
    123   // occurs.
    124   scoped_ptr<VideoDecodeAccelerator> vda_;
    125 
    126   // Callbacks that are !is_null() only during their respective operation being
    127   // asynchronously executed.
    128   DecodeCB pending_decode_cb_;
    129   base::Closure pending_reset_cb_;
    130 
    131   State state_;
    132 
    133   VideoDecoderConfig config_;
    134 
    135   // Shared-memory buffer pool.  Since allocating SHM segments requires a
    136   // round-trip to the browser process, we keep allocation out of the
    137   // steady-state of the decoder.
    138   std::vector<SHMBuffer*> available_shm_segments_;
    139 
    140   // Book-keeping variables.
    141   struct BufferPair {
    142     BufferPair(SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b);
    143     ~BufferPair();
    144     SHMBuffer* shm_buffer;
    145     scoped_refptr<DecoderBuffer> buffer;
    146   };
    147   std::map<int32, BufferPair> bitstream_buffers_in_decoder_;
    148   std::map<int32, PictureBuffer> assigned_picture_buffers_;
    149   std::map<int32, PictureBuffer> dismissed_picture_buffers_;
    150   // PictureBuffers given to us by VDA via PictureReady, which we sent forward
    151   // as VideoFrames to be rendered via decode_cb_, and which will be returned
    152   // to us via ReusePictureBuffer.
    153   std::set<int32> picture_buffers_at_display_;
    154 
    155   // The texture target used for decoded pictures.
    156   uint32 decoder_texture_target_;
    157 
    158   struct BufferData {
    159     BufferData(int32 bbid, base::TimeDelta ts, const gfx::Rect& visible_rect,
    160                const gfx::Size& natural_size);
    161     ~BufferData();
    162     int32 bitstream_buffer_id;
    163     base::TimeDelta timestamp;
    164     gfx::Rect visible_rect;
    165     gfx::Size natural_size;
    166   };
    167   std::list<BufferData> input_buffer_data_;
    168 
    169   // picture_buffer_id and the frame wrapping the corresponding Picture, for
    170   // frames that have been decoded but haven't been requested by a Decode() yet.
    171   std::list<scoped_refptr<VideoFrame> > ready_video_frames_;
    172   int32 next_picture_buffer_id_;
    173   int32 next_bitstream_buffer_id_;
    174 
    175   // Set during ProvidePictureBuffers(), used for checking and implementing
    176   // HasAvailableOutputFrames().
    177   int available_pictures_;
    178 
    179   DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoder);
    180 };
    181 
    182 }  // namespace media
    183 
    184 #endif  // MEDIA_FILTERS_GPU_VIDEO_DECODER_H_
    185