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

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

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

Powered by Google App Engine
This is Rietveld 408576698