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 SharedMemory;
     23 class SingleThreadTaskRunner;
     24 }
     25 
     26 namespace media {
     27 
     28 class DecoderBuffer;
     29 class GpuVideoAcceleratorFactories;
     30 class MediaLog;
     31 
     32 // GPU-accelerated video decoder implementation.  Relies on
     33 // AcceleratedVideoDecoderMsg_Decode and friends.  Can be created on any thread
     34 // but must be accessed and destroyed on GpuVideoAcceleratorFactories's
     35 // GetMessageLoop().
     36 class MEDIA_EXPORT GpuVideoDecoder
     37     : public VideoDecoder,
     38       public VideoDecodeAccelerator::Client {
     39  public:
     40   explicit GpuVideoDecoder(
     41       const scoped_refptr<GpuVideoAcceleratorFactories>& factories);
     42 
     43   // VideoDecoder implementation.
     44   virtual std::string GetDisplayName() const OVERRIDE;
     45   virtual void Initialize(const VideoDecoderConfig& config,
     46                           bool low_delay,
     47                           const PipelineStatusCB& status_cb,
     48                           const OutputCB& output_cb) OVERRIDE;
     49   virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
     50                       const DecodeCB& decode_cb) OVERRIDE;
     51   virtual void Reset(const base::Closure& closure) OVERRIDE;
     52   virtual bool NeedsBitstreamConversion() const OVERRIDE;
     53   virtual bool CanReadWithoutStalling() const OVERRIDE;
     54   virtual int GetMaxDecodeRequests() const OVERRIDE;
     55 
     56   // VideoDecodeAccelerator::Client implementation.
     57   virtual void ProvidePictureBuffers(uint32 count,
     58                                      const gfx::Size& size,
     59                                      uint32 texture_target) OVERRIDE;
     60   virtual void DismissPictureBuffer(int32 id) OVERRIDE;
     61   virtual void PictureReady(const media::Picture& picture) OVERRIDE;
     62   virtual void NotifyEndOfBitstreamBuffer(int32 id) OVERRIDE;
     63   virtual void NotifyFlushDone() OVERRIDE;
     64   virtual void NotifyResetDone() OVERRIDE;
     65   virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE;
     66 
     67  protected:
     68   virtual ~GpuVideoDecoder();
     69 
     70  private:
     71   enum State {
     72     kNormal,
     73     kDrainingDecoder,
     74     kDecoderDrained,
     75     kError
     76   };
     77 
     78   // A shared memory segment and its allocated size.
     79   struct SHMBuffer {
     80     SHMBuffer(base::SharedMemory* m, size_t s);
     81     ~SHMBuffer();
     82     base::SharedMemory* shm;
     83     size_t size;
     84   };
     85 
     86   // A SHMBuffer and the DecoderBuffer its data came from.
     87   struct PendingDecoderBuffer {
     88     PendingDecoderBuffer(SHMBuffer* s,
     89                         const scoped_refptr<DecoderBuffer>& b,
     90                         const DecodeCB& done_cb);
     91     ~PendingDecoderBuffer();
     92     SHMBuffer* shm_buffer;
     93     scoped_refptr<DecoderBuffer> buffer;
     94     DecodeCB done_cb;
     95   };
     96 
     97   typedef std::map<int32, PictureBuffer> PictureBufferMap;
     98 
     99   void DeliverFrame(const scoped_refptr<VideoFrame>& frame);
    100 
    101   // Static method is to allow it to run even after GVD is deleted.
    102   static void ReleaseMailbox(
    103       base::WeakPtr<GpuVideoDecoder> decoder,
    104       const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories,
    105       int64 picture_buffer_id,
    106       uint32 texture_id,
    107       uint32 release_sync_point);
    108   // Indicate the picture buffer can be reused by the decoder.
    109   void ReusePictureBuffer(int64 picture_buffer_id);
    110 
    111   void RecordBufferData(
    112       const BitstreamBuffer& bitstream_buffer, const DecoderBuffer& buffer);
    113   void GetBufferData(int32 id, base::TimeDelta* timetamp,
    114                      gfx::Rect* visible_rect, gfx::Size* natural_size);
    115 
    116   void DestroyVDA();
    117 
    118   // Request a shared-memory segment of at least |min_size| bytes.  Will
    119   // allocate as necessary.  Caller does not own returned pointer.
    120   SHMBuffer* GetSHM(size_t min_size);
    121 
    122   // Return a shared-memory segment to the available pool.
    123   void PutSHM(SHMBuffer* shm_buffer);
    124 
    125   // Destroy all PictureBuffers in |buffers|, and delete their textures.
    126   void DestroyPictureBuffers(PictureBufferMap* buffers);
    127 
    128   // Assert the contract that this class is operated on the right thread.
    129   void DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() const;
    130 
    131   bool needs_bitstream_conversion_;
    132 
    133   scoped_refptr<GpuVideoAcceleratorFactories> factories_;
    134 
    135   // Populated during Initialize() (on success) and unchanged until an error
    136   // occurs.
    137   scoped_ptr<VideoDecodeAccelerator> vda_;
    138 
    139   OutputCB output_cb_;
    140 
    141   DecodeCB eos_decode_cb_;
    142 
    143   // Not null only during reset.
    144   base::Closure pending_reset_cb_;
    145 
    146   State state_;
    147 
    148   VideoDecoderConfig config_;
    149 
    150   // Shared-memory buffer pool.  Since allocating SHM segments requires a
    151   // round-trip to the browser process, we keep allocation out of the
    152   // steady-state of the decoder.
    153   std::vector<SHMBuffer*> available_shm_segments_;
    154 
    155   std::map<int32, PendingDecoderBuffer> bitstream_buffers_in_decoder_;
    156   PictureBufferMap assigned_picture_buffers_;
    157   // PictureBuffers given to us by VDA via PictureReady, which we sent forward
    158   // as VideoFrames to be rendered via decode_cb_, and which will be returned
    159   // to us via ReusePictureBuffer.
    160   typedef std::map<int32 /* picture_buffer_id */, uint32 /* texture_id */>
    161       PictureBufferTextureMap;
    162   PictureBufferTextureMap picture_buffers_at_display_;
    163 
    164   // The texture target used for decoded pictures.
    165   uint32 decoder_texture_target_;
    166 
    167   struct BufferData {
    168     BufferData(int32 bbid, base::TimeDelta ts, const gfx::Rect& visible_rect,
    169                const gfx::Size& natural_size);
    170     ~BufferData();
    171     int32 bitstream_buffer_id;
    172     base::TimeDelta timestamp;
    173     gfx::Rect visible_rect;
    174     gfx::Size natural_size;
    175   };
    176   std::list<BufferData> input_buffer_data_;
    177 
    178   // picture_buffer_id and the frame wrapping the corresponding Picture, for
    179   // frames that have been decoded but haven't been requested by a Decode() yet.
    180   int32 next_picture_buffer_id_;
    181   int32 next_bitstream_buffer_id_;
    182 
    183   // Set during ProvidePictureBuffers(), used for checking and implementing
    184   // HasAvailableOutputFrames().
    185   int available_pictures_;
    186 
    187   // Bound to factories_->GetMessageLoop().
    188   // NOTE: Weak pointers must be invalidated before all other member variables.
    189   base::WeakPtrFactory<GpuVideoDecoder> weak_factory_;
    190 
    191   DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoder);
    192 };
    193 
    194 }  // namespace media
    195 
    196 #endif  // MEDIA_FILTERS_GPU_VIDEO_DECODER_H_
    197