OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // This file contains an implementation of VideoDecoderAccelerator | 5 // This file contains an implementation of VideoDecoderAccelerator |
6 // that utilizes hardware video decoder present on Intel CPUs. | 6 // that utilizes hardware video decoder present on Intel CPUs. |
7 | 7 |
8 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ | 8 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ |
9 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ | 9 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ |
10 | 10 |
11 #include <list> | |
11 #include <map> | 12 #include <map> |
12 #include <queue> | 13 #include <queue> |
13 #include <utility> | 14 #include <utility> |
14 #include <vector> | 15 #include <vector> |
15 | 16 |
16 #include "base/logging.h" | 17 #include "base/logging.h" |
17 #include "base/memory/linked_ptr.h" | 18 #include "base/memory/linked_ptr.h" |
18 #include "base/memory/shared_memory.h" | 19 #include "base/memory/shared_memory.h" |
19 #include "base/memory/weak_ptr.h" | 20 #include "base/memory/weak_ptr.h" |
20 #include "base/message_loop/message_loop.h" | 21 #include "base/message_loop/message_loop.h" |
21 #include "base/synchronization/condition_variable.h" | 22 #include "base/synchronization/condition_variable.h" |
22 #include "base/synchronization/lock.h" | 23 #include "base/synchronization/lock.h" |
23 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
24 #include "content/common/content_export.h" | 25 #include "content/common/content_export.h" |
25 #include "content/common/gpu/media/vaapi_h264_decoder.h" | |
26 #include "content/common/gpu/media/vaapi_wrapper.h" | 26 #include "content/common/gpu/media/vaapi_wrapper.h" |
27 #include "media/base/bitstream_buffer.h" | 27 #include "media/base/bitstream_buffer.h" |
28 #include "media/video/picture.h" | 28 #include "media/video/picture.h" |
29 #include "media/video/video_decode_accelerator.h" | 29 #include "media/video/video_decode_accelerator.h" |
30 | 30 |
31 namespace gfx { | 31 namespace gfx { |
32 class GLImage; | 32 class GLImage; |
33 } | 33 } |
34 | 34 |
35 namespace content { | 35 namespace content { |
36 | 36 |
37 class AcceleratedVideoDecoder; | |
37 class VaapiPicture; | 38 class VaapiPicture; |
38 | 39 |
39 // Class to provide video decode acceleration for Intel systems with hardware | 40 // Class to provide video decode acceleration for Intel systems with hardware |
40 // support for it, and on which libva is available. | 41 // support for it, and on which libva is available. |
41 // Decoding tasks are performed in a separate decoding thread. | 42 // Decoding tasks are performed in a separate decoding thread. |
42 // | 43 // |
43 // Threading/life-cycle: this object is created & destroyed on the GPU | 44 // Threading/life-cycle: this object is created & destroyed on the GPU |
44 // ChildThread. A few methods on it are called on the decoder thread which is | 45 // ChildThread. A few methods on it are called on the decoder thread which is |
45 // stopped during |this->Destroy()|, so any tasks posted to the decoder thread | 46 // stopped during |this->Destroy()|, so any tasks posted to the decoder thread |
46 // can assume |*this| is still alive. See |weak_this_| below for more details. | 47 // can assume |*this| is still alive. See |weak_this_| below for more details. |
47 class CONTENT_EXPORT VaapiVideoDecodeAccelerator | 48 class CONTENT_EXPORT VaapiVideoDecodeAccelerator |
48 : public media::VideoDecodeAccelerator { | 49 : public media::VideoDecodeAccelerator { |
49 public: | 50 public: |
51 class VaapiDecodeSurface; | |
52 | |
50 VaapiVideoDecodeAccelerator( | 53 VaapiVideoDecodeAccelerator( |
51 const base::Callback<bool(void)>& make_context_current, | 54 const base::Callback<bool(void)>& make_context_current, |
52 const base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)>& | 55 const base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)>& |
53 bind_image); | 56 bind_image); |
54 ~VaapiVideoDecodeAccelerator() override; | 57 ~VaapiVideoDecodeAccelerator() override; |
55 | 58 |
56 // media::VideoDecodeAccelerator implementation. | 59 // media::VideoDecodeAccelerator implementation. |
57 bool Initialize(media::VideoCodecProfile profile, | 60 bool Initialize(media::VideoCodecProfile profile, Client* client) override; |
58 Client* client) override; | |
59 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; | 61 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; |
60 void AssignPictureBuffers( | 62 void AssignPictureBuffers( |
61 const std::vector<media::PictureBuffer>& buffers) override; | 63 const std::vector<media::PictureBuffer>& buffers) override; |
62 void ReusePictureBuffer(int32 picture_buffer_id) override; | 64 void ReusePictureBuffer(int32 picture_buffer_id) override; |
63 void Flush() override; | 65 void Flush() override; |
64 void Reset() override; | 66 void Reset() override; |
65 void Destroy() override; | 67 void Destroy() override; |
66 bool CanDecodeOnIOThread() override; | 68 bool CanDecodeOnIOThread() override; |
67 | 69 |
68 private: | 70 private: |
71 class VaapiH264Accelerator; | |
72 | |
69 // Notify the client that an error has occurred and decoding cannot continue. | 73 // Notify the client that an error has occurred and decoding cannot continue. |
70 void NotifyError(Error error); | 74 void NotifyError(Error error); |
71 | 75 |
72 // Map the received input buffer into this process' address space and | 76 // Map the received input buffer into this process' address space and |
73 // queue it for decode. | 77 // queue it for decode. |
74 void MapAndQueueNewInputBuffer( | 78 void MapAndQueueNewInputBuffer( |
75 const media::BitstreamBuffer& bitstream_buffer); | 79 const media::BitstreamBuffer& bitstream_buffer); |
76 | 80 |
77 // Get a new input buffer from the queue and set it up in decoder. This will | 81 // Get a new input buffer from the queue and set it up in decoder. This will |
78 // sleep if no input buffers are available. Return true if a new buffer has | 82 // sleep if no input buffers are available. Return true if a new buffer has |
79 // been set up, false if an early exit has been requested (due to initiated | 83 // been set up, false if an early exit has been requested (due to initiated |
80 // reset/flush/destroy). | 84 // reset/flush/destroy). |
81 bool GetInputBuffer_Locked(); | 85 bool GetInputBuffer_Locked(); |
82 | 86 |
83 // Signal the client that the current buffer has been read and can be | 87 // Signal the client that the current buffer has been read and can be |
84 // returned. Will also release the mapping. | 88 // returned. Will also release the mapping. |
85 void ReturnCurrInputBuffer_Locked(); | 89 void ReturnCurrInputBuffer_Locked(); |
86 | 90 |
87 // Pass one or more output buffers to the decoder. This will sleep | 91 // Wait for more surfaces to become available. Return true once they do or |
88 // if no buffers are available. Return true if buffers have been set up or | 92 // false if an early exit has been requested (due to an initiated |
89 // false if an early exit has been requested (due to initiated | |
90 // reset/flush/destroy). | 93 // reset/flush/destroy). |
91 bool FeedDecoderWithOutputSurfaces_Locked(); | 94 // TODO(posciak): refactor the whole class to remove sleeping in wait for |
95 // surfaces, and reschedule DecodeTask instead. | |
96 bool WaitForSurfaces_Locked(); | |
92 | 97 |
93 // Continue decoding given input buffers and sleep waiting for input/output | 98 // Continue decoding given input buffers and sleep waiting for input/output |
94 // as needed. Will exit if a new set of surfaces or reset/flush/destroy | 99 // as needed. Will exit if a new set of surfaces or reset/flush/destroy |
95 // is requested. | 100 // is requested. |
96 void DecodeTask(); | 101 void DecodeTask(); |
97 | 102 |
98 // Scheduled after receiving a flush request and executed after the current | 103 // Scheduled after receiving a flush request and executed after the current |
99 // decoding task finishes decoding pending inputs. Makes the decoder return | 104 // decoding task finishes decoding pending inputs. Makes the decoder return |
100 // all remaining output pictures and puts it in an idle state, ready | 105 // all remaining output pictures and puts it in an idle state, ready |
101 // to resume if needed and schedules a FinishFlush. | 106 // to resume if needed and schedules a FinishFlush. |
(...skipping 15 matching lines...) Expand all Loading... | |
117 // finished. | 122 // finished. |
118 void FinishReset(); | 123 void FinishReset(); |
119 | 124 |
120 // Helper for Destroy(), doing all the actual work except for deleting self. | 125 // Helper for Destroy(), doing all the actual work except for deleting self. |
121 void Cleanup(); | 126 void Cleanup(); |
122 | 127 |
123 // Get a usable framebuffer configuration for use in binding textures | 128 // Get a usable framebuffer configuration for use in binding textures |
124 // or return false on failure. | 129 // or return false on failure. |
125 bool InitializeFBConfig(); | 130 bool InitializeFBConfig(); |
126 | 131 |
127 // Callback for the decoder to execute when it wants us to output given | |
128 // |va_surface|. | |
129 void SurfaceReady(int32 input_id, const scoped_refptr<VASurface>& va_surface); | |
130 | |
131 // Callback to be executed once we have a |va_surface| to be output and | 132 // Callback to be executed once we have a |va_surface| to be output and |
132 // an available |picture| to use for output. | 133 // an available |picture| to use for output. |
133 // Puts contents of |va_surface| into given |picture|, releases the | 134 // Puts contents of |va_surface| into given |picture|, releases the |
134 // surface and passes the resulting picture to client for output. | 135 // surface and passes the resulting picture to client for output. |
135 void OutputPicture(const scoped_refptr<VASurface>& va_surface, | 136 void OutputPicture(const scoped_refptr<VASurface>& va_surface, |
136 int32 input_id, | 137 int32 input_id, |
137 VaapiPicture* picture); | 138 VaapiPicture* picture); |
138 | 139 |
139 // Try to OutputPicture() if we have both a ready surface and picture. | 140 // Try to OutputPicture() if we have both a ready surface and picture. |
140 void TryOutputSurface(); | 141 void TryOutputSurface(); |
141 | 142 |
142 // Called when a VASurface is no longer in use by the decoder or is not being | 143 // Called when a VASurface is no longer in use by the decoder or is not being |
143 // synced/waiting to be synced to a picture. Returns it to available surfaces | 144 // synced/waiting to be synced to a picture. Returns it to available surfaces |
144 // pool. | 145 // pool. |
145 void RecycleVASurfaceID(VASurfaceID va_surface_id); | 146 void RecycleVASurfaceID(VASurfaceID va_surface_id); |
146 | 147 |
147 // Initiate wait cycle for surfaces to be released before we release them | 148 // Initiate wait cycle for surfaces to be released before we release them |
148 // and allocate new ones, as requested by the decoder. | 149 // and allocate new ones, as requested by the decoder. |
149 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); | 150 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); |
151 | |
150 // Check if the surfaces have been released or post ourselves for later. | 152 // Check if the surfaces have been released or post ourselves for later. |
151 void TryFinishSurfaceSetChange(); | 153 void TryFinishSurfaceSetChange(); |
152 | 154 |
155 // | |
156 // Below methods are used by accelerator implementations. | |
157 // | |
158 // Decode of |dec_surface| is ready to be submitted and all codec-specific | |
159 // settings are set in hardware. | |
160 bool DecodeSurface(const scoped_refptr<VaapiDecodeSurface>& dec_surface); | |
161 | |
162 // |dec_surface| is ready to be outputted once decode is finished. | |
163 // This can be called before decode is actually done in hardware, and this | |
164 // method is responsible for maintaining the ordering, i.e. the surfaces have | |
165 // to be outputted in the same order as SurfaceReady is called. | |
166 // On Intel, we don't have to explicitly maintain the ordering however, as the | |
167 // driver will maintain ordering, as well as dependencies, and will process | |
168 // each submitted command in order, and run each command only if its | |
169 // dependencies are ready. | |
170 void SurfaceReady(const scoped_refptr<VaapiDecodeSurface>& dec_surface); | |
171 | |
172 // Return a new VaapiDecodeSurface for decoding into, or nullptr if not | |
173 // available. | |
174 scoped_refptr<VaapiDecodeSurface> CreateSurface(); | |
175 | |
176 | |
kcwu
2015/03/31 15:20:09
two blank line
Pawel Osciak
2015/04/03 07:06:00
This was intentional to make a clear delineation b
| |
153 // Client-provided GL state. | 177 // Client-provided GL state. |
154 base::Callback<bool(void)> make_context_current_; | 178 base::Callback<bool(void)> make_context_current_; |
155 | 179 |
156 // VAVDA state. | 180 // VAVDA state. |
157 enum State { | 181 enum State { |
158 // Initialize() not called yet or failed. | 182 // Initialize() not called yet or failed. |
159 kUninitialized, | 183 kUninitialized, |
160 // DecodeTask running. | 184 // DecodeTask running. |
161 kDecoding, | 185 kDecoding, |
162 // Resetting, waiting for decoder to finish current task and cleanup. | 186 // Resetting, waiting for decoder to finish current task and cleanup. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 // Callback used when creating VASurface objects. | 265 // Callback used when creating VASurface objects. |
242 VASurface::ReleaseCB va_surface_release_cb_; | 266 VASurface::ReleaseCB va_surface_release_cb_; |
243 | 267 |
244 // To expose client callbacks from VideoDecodeAccelerator. | 268 // To expose client callbacks from VideoDecodeAccelerator. |
245 // NOTE: all calls to these objects *MUST* be executed on message_loop_. | 269 // NOTE: all calls to these objects *MUST* be executed on message_loop_. |
246 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; | 270 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; |
247 base::WeakPtr<Client> client_; | 271 base::WeakPtr<Client> client_; |
248 | 272 |
249 // Comes after vaapi_wrapper_ to ensure its destructor is executed before | 273 // Comes after vaapi_wrapper_ to ensure its destructor is executed before |
250 // vaapi_wrapper_ is destroyed. | 274 // vaapi_wrapper_ is destroyed. |
251 scoped_ptr<VaapiH264Decoder> decoder_; | 275 scoped_ptr<VaapiH264Accelerator> h264_accelerator_; |
276 // After h264_accelerator_ to ensure correct destruction order. | |
277 scoped_ptr<AcceleratedVideoDecoder> decoder_; | |
278 | |
252 base::Thread decoder_thread_; | 279 base::Thread decoder_thread_; |
253 // Use this to post tasks to |decoder_thread_| instead of | 280 // Use this to post tasks to |decoder_thread_| instead of |
254 // |decoder_thread_.message_loop()| because the latter will be NULL once | 281 // |decoder_thread_.message_loop()| because the latter will be NULL once |
255 // |decoder_thread_.Stop()| returns. | 282 // |decoder_thread_.Stop()| returns. |
256 scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_; | 283 scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_; |
257 | 284 |
258 int num_frames_at_client_; | 285 int num_frames_at_client_; |
259 int num_stream_bufs_at_decoder_; | 286 int num_stream_bufs_at_decoder_; |
260 | 287 |
261 // Whether we are waiting for any pending_output_cbs_ to be run before | 288 // Whether we are waiting for any pending_output_cbs_ to be run before |
(...skipping 14 matching lines...) Expand all Loading... | |
276 | 303 |
277 // The WeakPtrFactory for |weak_this_|. | 304 // The WeakPtrFactory for |weak_this_|. |
278 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; | 305 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; |
279 | 306 |
280 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator); | 307 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator); |
281 }; | 308 }; |
282 | 309 |
283 } // namespace content | 310 } // namespace content |
284 | 311 |
285 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ | 312 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ |
OLD | NEW |