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