Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: content/common/gpu/media/vaapi_video_decode_accelerator.h

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 // This file contains an implementation of VideoDecoderAccelerator
6 // that utilizes hardware video decoder present on Intel CPUs.
7
8 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_
9 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_
10
11 #include <stddef.h>
12 #include <stdint.h>
13
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <queue>
18 #include <utility>
19 #include <vector>
20
21 #include "base/logging.h"
22 #include "base/macros.h"
23 #include "base/memory/linked_ptr.h"
24 #include "base/memory/weak_ptr.h"
25 #include "base/message_loop/message_loop.h"
26 #include "base/synchronization/condition_variable.h"
27 #include "base/synchronization/lock.h"
28 #include "base/threading/thread.h"
29 #include "content/common/content_export.h"
30 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
31 #include "content/common/gpu/media/shared_memory_region.h"
32 #include "content/common/gpu/media/vaapi_wrapper.h"
33 #include "media/base/bitstream_buffer.h"
34 #include "media/video/picture.h"
35 #include "media/video/video_decode_accelerator.h"
36
37 namespace gl {
38 class GLImage;
39 }
40
41 namespace content {
42
43 class AcceleratedVideoDecoder;
44 class VaapiPicture;
45
46 // Class to provide video decode acceleration for Intel systems with hardware
47 // support for it, and on which libva is available.
48 // Decoding tasks are performed in a separate decoding thread.
49 //
50 // Threading/life-cycle: this object is created & destroyed on the GPU
51 // ChildThread. A few methods on it are called on the decoder thread which is
52 // stopped during |this->Destroy()|, so any tasks posted to the decoder thread
53 // can assume |*this| is still alive. See |weak_this_| below for more details.
54 class CONTENT_EXPORT VaapiVideoDecodeAccelerator
55 : public media::VideoDecodeAccelerator {
56 public:
57 class VaapiDecodeSurface;
58
59 VaapiVideoDecodeAccelerator(
60 const MakeGLContextCurrentCallback& make_context_current_cb,
61 const BindGLImageCallback& bind_image_cb);
62
63 ~VaapiVideoDecodeAccelerator() override;
64
65 // media::VideoDecodeAccelerator implementation.
66 bool Initialize(const Config& config, Client* client) override;
67 void Decode(const media::BitstreamBuffer& bitstream_buffer) override;
68 void AssignPictureBuffers(
69 const std::vector<media::PictureBuffer>& buffers) override;
70 void ReusePictureBuffer(int32_t picture_buffer_id) override;
71 void Flush() override;
72 void Reset() override;
73 void Destroy() override;
74 bool TryToSetupDecodeOnSeparateThread(
75 const base::WeakPtr<Client>& decode_client,
76 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
77 override;
78
79 static media::VideoDecodeAccelerator::SupportedProfiles
80 GetSupportedProfiles();
81
82 private:
83 class VaapiH264Accelerator;
84 class VaapiVP8Accelerator;
85 class VaapiVP9Accelerator;
86
87 // Notify the client that an error has occurred and decoding cannot continue.
88 void NotifyError(Error error);
89
90 // Map the received input buffer into this process' address space and
91 // queue it for decode.
92 void MapAndQueueNewInputBuffer(
93 const media::BitstreamBuffer& bitstream_buffer);
94
95 // Get a new input buffer from the queue and set it up in decoder. This will
96 // sleep if no input buffers are available. Return true if a new buffer has
97 // been set up, false if an early exit has been requested (due to initiated
98 // reset/flush/destroy).
99 bool GetInputBuffer_Locked();
100
101 // Signal the client that the current buffer has been read and can be
102 // returned. Will also release the mapping.
103 void ReturnCurrInputBuffer_Locked();
104
105 // Wait for more surfaces to become available. Return true once they do or
106 // false if an early exit has been requested (due to an initiated
107 // reset/flush/destroy).
108 bool WaitForSurfaces_Locked();
109
110 // Continue decoding given input buffers and sleep waiting for input/output
111 // as needed. Will exit if a new set of surfaces or reset/flush/destroy
112 // is requested.
113 void DecodeTask();
114
115 // Scheduled after receiving a flush request and executed after the current
116 // decoding task finishes decoding pending inputs. Makes the decoder return
117 // all remaining output pictures and puts it in an idle state, ready
118 // to resume if needed and schedules a FinishFlush.
119 void FlushTask();
120
121 // Scheduled by the FlushTask after decoder is flushed to put VAVDA into idle
122 // state and notify the client that flushing has been finished.
123 void FinishFlush();
124
125 // Scheduled after receiving a reset request and executed after the current
126 // decoding task finishes decoding the current frame. Puts the decoder into
127 // an idle state, ready to resume if needed, discarding decoded but not yet
128 // outputted pictures (decoder keeps ownership of their associated picture
129 // buffers). Schedules a FinishReset afterwards.
130 void ResetTask();
131
132 // Scheduled by ResetTask after it's done putting VAVDA into an idle state.
133 // Drops remaining input buffers and notifies the client that reset has been
134 // finished.
135 void FinishReset();
136
137 // Helper for Destroy(), doing all the actual work except for deleting self.
138 void Cleanup();
139
140 // Get a usable framebuffer configuration for use in binding textures
141 // or return false on failure.
142 bool InitializeFBConfig();
143
144 // Callback to be executed once we have a |va_surface| to be output and
145 // an available |picture| to use for output.
146 // Puts contents of |va_surface| into given |picture|, releases the
147 // surface and passes the resulting picture to client for output.
148 void OutputPicture(const scoped_refptr<VASurface>& va_surface,
149 int32_t input_id,
150 VaapiPicture* picture);
151
152 // Try to OutputPicture() if we have both a ready surface and picture.
153 void TryOutputSurface();
154
155 // Called when a VASurface is no longer in use by the decoder or is not being
156 // synced/waiting to be synced to a picture. Returns it to available surfaces
157 // pool.
158 void RecycleVASurfaceID(VASurfaceID va_surface_id);
159
160 // Initiate wait cycle for surfaces to be released before we release them
161 // and allocate new ones, as requested by the decoder.
162 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size);
163
164 // Check if the surfaces have been released or post ourselves for later.
165 void TryFinishSurfaceSetChange();
166
167 //
168 // Below methods are used by accelerator implementations.
169 //
170 // Decode of |dec_surface| is ready to be submitted and all codec-specific
171 // settings are set in hardware.
172 bool DecodeSurface(const scoped_refptr<VaapiDecodeSurface>& dec_surface);
173
174 // |dec_surface| is ready to be outputted once decode is finished.
175 // This can be called before decode is actually done in hardware, and this
176 // method is responsible for maintaining the ordering, i.e. the surfaces have
177 // to be outputted in the same order as SurfaceReady is called.
178 // On Intel, we don't have to explicitly maintain the ordering however, as the
179 // driver will maintain ordering, as well as dependencies, and will process
180 // each submitted command in order, and run each command only if its
181 // dependencies are ready.
182 void SurfaceReady(const scoped_refptr<VaapiDecodeSurface>& dec_surface);
183
184 // Return a new VaapiDecodeSurface for decoding into, or nullptr if not
185 // available.
186 scoped_refptr<VaapiDecodeSurface> CreateSurface();
187
188 // VAVDA state.
189 enum State {
190 // Initialize() not called yet or failed.
191 kUninitialized,
192 // DecodeTask running.
193 kDecoding,
194 // Resetting, waiting for decoder to finish current task and cleanup.
195 kResetting,
196 // Flushing, waiting for decoder to finish current task and cleanup.
197 kFlushing,
198 // Idle, decoder in state ready to start/resume decoding.
199 kIdle,
200 // Destroying, waiting for the decoder to finish current task.
201 kDestroying,
202 };
203
204 // Protects input buffer and surface queues and state_.
205 base::Lock lock_;
206 State state_;
207
208 // An input buffer awaiting consumption, provided by the client.
209 struct InputBuffer {
210 InputBuffer();
211 ~InputBuffer();
212
213 int32_t id;
214 std::unique_ptr<SharedMemoryRegion> shm;
215 };
216
217 // Queue for incoming input buffers.
218 typedef std::queue<linked_ptr<InputBuffer> > InputBuffers;
219 InputBuffers input_buffers_;
220 // Signalled when input buffers are queued onto the input_buffers_ queue.
221 base::ConditionVariable input_ready_;
222
223 // Current input buffer at decoder.
224 linked_ptr<InputBuffer> curr_input_buffer_;
225
226 // Queue for incoming output buffers (texture ids).
227 typedef std::queue<int32_t> OutputBuffers;
228 OutputBuffers output_buffers_;
229
230 scoped_refptr<VaapiWrapper> vaapi_wrapper_;
231
232 typedef std::map<int32_t, linked_ptr<VaapiPicture>> Pictures;
233 // All allocated Pictures, regardless of their current state.
234 // Pictures are allocated once and destroyed at the end of decode.
235 // Comes after vaapi_wrapper_ to ensure all pictures are destroyed
236 // before vaapi_wrapper_ is destroyed.
237 Pictures pictures_;
238
239 // Return a VaapiPicture associated with given client-provided id.
240 VaapiPicture* PictureById(int32_t picture_buffer_id);
241
242 // VA Surfaces no longer in use that can be passed back to the decoder for
243 // reuse, once it requests them.
244 std::list<VASurfaceID> available_va_surfaces_;
245 // Signalled when output surfaces are queued onto the available_va_surfaces_
246 // queue.
247 base::ConditionVariable surfaces_available_;
248
249 // Pending output requests from the decoder. When it indicates that we should
250 // output a surface and we have an available Picture (i.e. texture) ready
251 // to use, we'll execute the callback passing the Picture. The callback
252 // will put the contents of the surface into the picture and return it to
253 // the client, releasing the surface as well.
254 // If we don't have any available Pictures at the time when the decoder
255 // requests output, we'll store the request on pending_output_cbs_ queue for
256 // later and run it once the client gives us more textures
257 // via ReusePictureBuffer().
258 typedef base::Callback<void(VaapiPicture*)> OutputCB;
259 std::queue<OutputCB> pending_output_cbs_;
260
261 // ChildThread's message loop
262 base::MessageLoop* message_loop_;
263
264 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder
265 // thread back to the ChildThread. Because the decoder thread is a member of
266 // this class, any task running on the decoder thread is guaranteed that this
267 // object is still alive. As a result, tasks posted from ChildThread to
268 // decoder thread should use base::Unretained(this), and tasks posted from the
269 // decoder thread to the ChildThread should use |weak_this_|.
270 base::WeakPtr<VaapiVideoDecodeAccelerator> weak_this_;
271
272 // Callback used when creating VASurface objects.
273 VASurface::ReleaseCB va_surface_release_cb_;
274
275 // To expose client callbacks from VideoDecodeAccelerator.
276 // NOTE: all calls to these objects *MUST* be executed on message_loop_.
277 std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_;
278 base::WeakPtr<Client> client_;
279
280 // Accelerators come after vaapi_wrapper_ to ensure they are destroyed first.
281 std::unique_ptr<VaapiH264Accelerator> h264_accelerator_;
282 std::unique_ptr<VaapiVP8Accelerator> vp8_accelerator_;
283 std::unique_ptr<VaapiVP9Accelerator> vp9_accelerator_;
284 // After *_accelerator_ to ensure correct destruction order.
285 std::unique_ptr<AcceleratedVideoDecoder> decoder_;
286
287 base::Thread decoder_thread_;
288 // Use this to post tasks to |decoder_thread_| instead of
289 // |decoder_thread_.message_loop()| because the latter will be NULL once
290 // |decoder_thread_.Stop()| returns.
291 scoped_refptr<base::SingleThreadTaskRunner> decoder_thread_task_runner_;
292
293 int num_frames_at_client_;
294 int num_stream_bufs_at_decoder_;
295
296 // Whether we are waiting for any pending_output_cbs_ to be run before
297 // NotifyingFlushDone.
298 bool finish_flush_pending_;
299
300 // Decoder requested a new surface set and we are waiting for all the surfaces
301 // to be returned before we can free them.
302 bool awaiting_va_surfaces_recycle_;
303
304 // Last requested number/resolution of output picture buffers.
305 size_t requested_num_pics_;
306 gfx::Size requested_pic_size_;
307
308 // Callback to make GL context current.
309 MakeGLContextCurrentCallback make_context_current_cb_;
310
311 // Callback to bind a GLImage to a given texture.
312 BindGLImageCallback bind_image_cb_;
313
314 // The WeakPtrFactory for |weak_this_|.
315 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_;
316
317 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator);
318 };
319
320 } // namespace content
321
322 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_
OLDNEW
« no previous file with comments | « content/common/gpu/media/vaapi_tfp_picture.cc ('k') | content/common/gpu/media/vaapi_video_decode_accelerator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698