• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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