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

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

Issue 1040513003: VAVDA: Use the new, generic video decoder and accelerator infrastructure. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
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 bool WaitForSurfaces_Locked();
92 95
93 // Continue decoding given input buffers and sleep waiting for input/output 96 // 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 97 // as needed. Will exit if a new set of surfaces or reset/flush/destroy
95 // is requested. 98 // is requested.
96 void DecodeTask(); 99 void DecodeTask();
97 100
98 // Scheduled after receiving a flush request and executed after the current 101 // Scheduled after receiving a flush request and executed after the current
99 // decoding task finishes decoding pending inputs. Makes the decoder return 102 // decoding task finishes decoding pending inputs. Makes the decoder return
100 // all remaining output pictures and puts it in an idle state, ready 103 // all remaining output pictures and puts it in an idle state, ready
101 // to resume if needed and schedules a FinishFlush. 104 // to resume if needed and schedules a FinishFlush.
(...skipping 15 matching lines...) Expand all
117 // finished. 120 // finished.
118 void FinishReset(); 121 void FinishReset();
119 122
120 // Helper for Destroy(), doing all the actual work except for deleting self. 123 // Helper for Destroy(), doing all the actual work except for deleting self.
121 void Cleanup(); 124 void Cleanup();
122 125
123 // Get a usable framebuffer configuration for use in binding textures 126 // Get a usable framebuffer configuration for use in binding textures
124 // or return false on failure. 127 // or return false on failure.
125 bool InitializeFBConfig(); 128 bool InitializeFBConfig();
126 129
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 130 // Callback to be executed once we have a |va_surface| to be output and
132 // an available |picture| to use for output. 131 // an available |picture| to use for output.
133 // Puts contents of |va_surface| into given |picture|, releases the 132 // Puts contents of |va_surface| into given |picture|, releases the
134 // surface and passes the resulting picture to client for output. 133 // surface and passes the resulting picture to client for output.
135 void OutputPicture(const scoped_refptr<VASurface>& va_surface, 134 void OutputPicture(const scoped_refptr<VASurface>& va_surface,
136 int32 input_id, 135 int32 input_id,
137 VaapiPicture* picture); 136 VaapiPicture* picture);
138 137
139 // Try to OutputPicture() if we have both a ready surface and picture. 138 // Try to OutputPicture() if we have both a ready surface and picture.
140 void TryOutputSurface(); 139 void TryOutputSurface();
141 140
142 // Called when a VASurface is no longer in use by the decoder or is not being 141 // 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 142 // synced/waiting to be synced to a picture. Returns it to available surfaces
144 // pool. 143 // pool.
145 void RecycleVASurfaceID(VASurfaceID va_surface_id); 144 void RecycleVASurfaceID(VASurfaceID va_surface_id);
146 145
147 // Initiate wait cycle for surfaces to be released before we release them 146 // Initiate wait cycle for surfaces to be released before we release them
148 // and allocate new ones, as requested by the decoder. 147 // and allocate new ones, as requested by the decoder.
149 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); 148 void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size);
149
150 // Check if the surfaces have been released or post ourselves for later. 150 // Check if the surfaces have been released or post ourselves for later.
151 void TryFinishSurfaceSetChange(); 151 void TryFinishSurfaceSetChange();
152 152
153 //
154 // Below methods are used by accelerator implementations.
155 //
156 // Decode of |dec_surface| is ready to be submitted and all codec-specific
157 // settings are set in hardware.
158 bool DecodeSurface(const scoped_refptr<VaapiDecodeSurface>& dec_surface);
159
160 // |dec_surface| is ready to be outputted once decode is finished.
161 // This can be called before decode is actually done in hardware, and this
162 // method is responsible for maintaining the ordering, i.e. the surfaces have
163 // to be outputted in the same order as SurfaceReady is called.
164 // On Intel, we don't have to explicitly maintain the ordering however, as the
165 // driver will maintain ordering, as well as dependencies, and will process
166 // each submitted command in order, and run each command only if its
167 // dependencies are ready.
168 void SurfaceReady(const scoped_refptr<VaapiDecodeSurface>& dec_surface);
169
170 // Return a new VaapiDecodeSurface for decoding into, or nullptr if not
171 // available.
172 scoped_refptr<VaapiDecodeSurface> CreateSurface();
173
174
153 // Client-provided GL state. 175 // Client-provided GL state.
154 base::Callback<bool(void)> make_context_current_; 176 base::Callback<bool(void)> make_context_current_;
155 177
156 // VAVDA state. 178 // VAVDA state.
157 enum State { 179 enum State {
158 // Initialize() not called yet or failed. 180 // Initialize() not called yet or failed.
159 kUninitialized, 181 kUninitialized,
160 // DecodeTask running. 182 // DecodeTask running.
161 kDecoding, 183 kDecoding,
162 // Resetting, waiting for decoder to finish current task and cleanup. 184 // Resetting, waiting for decoder to finish current task and cleanup.
163 kResetting, 185 kResetting,
164 // Flushing, waiting for decoder to finish current task and cleanup. 186 // Flushing, waiting for decoder to finish current task and cleanup.
165 kFlushing, 187 kFlushing,
166 // Idle, decoder in state ready to start/resume decoding. 188 // Idle, decoder in state ready to start/resume decoding.
167 kIdle, 189 kIdle,
168 // Destroying, waiting for the decoder to finish current task. 190 // Destroying, waiting for the decoder to finish current task.
169 kDestroying, 191 kDestroying,
170 }; 192 };
171 193
172 // Protects input buffer and surface queues and state_. 194 // Protects input buffer and surface queues and state_.
wuchengli 2015/04/07 09:36:47 Not related to this CL. What are all the variables
kcwu1 2015/04/07 09:42:47 I have the same concern.
Pawel Osciak 2015/04/08 08:36:03 Yes, looks like a dormant bug, but shouldn't have
173 base::Lock lock_; 195 base::Lock lock_;
174 State state_; 196 State state_;
175 197
176 // An input buffer awaiting consumption, provided by the client. 198 // An input buffer awaiting consumption, provided by the client.
177 struct InputBuffer { 199 struct InputBuffer {
178 InputBuffer(); 200 InputBuffer();
179 ~InputBuffer(); 201 ~InputBuffer();
180 202
181 int32 id; 203 int32 id;
182 size_t size; 204 size_t size;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // Callback used when creating VASurface objects. 263 // Callback used when creating VASurface objects.
242 VASurface::ReleaseCB va_surface_release_cb_; 264 VASurface::ReleaseCB va_surface_release_cb_;
243 265
244 // To expose client callbacks from VideoDecodeAccelerator. 266 // To expose client callbacks from VideoDecodeAccelerator.
245 // NOTE: all calls to these objects *MUST* be executed on message_loop_. 267 // NOTE: all calls to these objects *MUST* be executed on message_loop_.
246 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; 268 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
247 base::WeakPtr<Client> client_; 269 base::WeakPtr<Client> client_;
248 270
249 // Comes after vaapi_wrapper_ to ensure its destructor is executed before 271 // Comes after vaapi_wrapper_ to ensure its destructor is executed before
250 // vaapi_wrapper_ is destroyed. 272 // vaapi_wrapper_ is destroyed.
251 scoped_ptr<VaapiH264Decoder> decoder_; 273 scoped_ptr<VaapiH264Accelerator> h264_accelerator_;
274 // After h264_accelerator_ to ensure correct destruction order.
275 scoped_ptr<AcceleratedVideoDecoder> decoder_;
276
252 base::Thread decoder_thread_; 277 base::Thread decoder_thread_;
253 // Use this to post tasks to |decoder_thread_| instead of 278 // Use this to post tasks to |decoder_thread_| instead of
254 // |decoder_thread_.message_loop()| because the latter will be NULL once 279 // |decoder_thread_.message_loop()| because the latter will be NULL once
255 // |decoder_thread_.Stop()| returns. 280 // |decoder_thread_.Stop()| returns.
256 scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_; 281 scoped_refptr<base::MessageLoopProxy> decoder_thread_proxy_;
257 282
258 int num_frames_at_client_; 283 int num_frames_at_client_;
259 int num_stream_bufs_at_decoder_; 284 int num_stream_bufs_at_decoder_;
260 285
261 // Whether we are waiting for any pending_output_cbs_ to be run before 286 // Whether we are waiting for any pending_output_cbs_ to be run before
(...skipping 14 matching lines...) Expand all
276 301
277 // The WeakPtrFactory for |weak_this_|. 302 // The WeakPtrFactory for |weak_this_|.
278 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; 303 base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_;
279 304
280 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator); 305 DISALLOW_COPY_AND_ASSIGN(VaapiVideoDecodeAccelerator);
281 }; 306 };
282 307
283 } // namespace content 308 } // namespace content
284 309
285 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_ 310 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_DECODE_ACCELERATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698