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