OLD | NEW |
---|---|
(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 #include "vaapi_video_decode_accelerator.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/command_line.h" | |
9 #include "base/debug/trace_event.h" | |
10 #include "base/logging.h" | |
11 #include "base/stl_util.h" | |
12 #include "base/string_util.h" | |
13 #include "base/synchronization/waitable_event.h" | |
14 #include "gpu/command_buffer/service/gpu_switches.h" | |
15 #include "content/public/common/content_switches.h" | |
16 #include "content/common/gpu/gpu_channel.h" | |
17 #include "media/video/picture.h" | |
18 #include "third_party/libva/va/va.h" | |
19 #include "ui/gfx/gl/gl_bindings.h" | |
20 | |
21 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \ | |
22 do { \ | |
23 if (!(result)) { \ | |
24 DVLOG(1) << log; \ | |
25 Destroy(); \ | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
Does this want to:
DCHECK_EQ(message_loop_, Messag
Pawel Osciak
2012/05/06 17:49:19
The functions will re-post themselves as needed.
| |
26 NotifyError(error_code); \ | |
27 return ret; \ | |
28 } \ | |
29 } while (0) | |
30 | |
31 using content::VaapiH264Decoder; | |
32 | |
33 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { | |
34 if (message_loop_ != MessageLoop::current()) { | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
I think this can never be true, since the only cal
Pawel Osciak
2012/05/06 17:49:19
True, Destroy() should be re-posting itself.
| |
35 message_loop_->PostTask(FROM_HERE, base::Bind( | |
36 &VaapiVideoDecodeAccelerator::NotifyError, this, error)); | |
37 return; | |
38 } | |
39 | |
40 DVLOG(1) << "Stopping on error " << error; | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
S/Stopping on/Notifying of/
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
41 | |
42 if (client_) | |
43 client_->NotifyError(error); | |
44 client_ = NULL; | |
45 } | |
46 | |
47 VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(Client* client) | |
48 // manually Reset() and initially not signalled | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
drop comment (belongs to old WE impl)
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
49 : state_(kUninitialized), | |
50 input_ready_(&lock_), | |
51 output_ready_(&lock_), | |
52 message_loop_(MessageLoop::current()), | |
53 client_(client), | |
54 decoder_thread_("VaapiDecoderThread") { | |
55 } | |
56 | |
57 VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { | |
58 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
59 } | |
60 | |
61 bool VaapiVideoDecodeAccelerator::Initialize( | |
62 media::VideoCodecProfile profile) { | |
63 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
64 | |
65 DCHECK_EQ(state_, kUninitialized); | |
66 DCHECK(client_); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
move to ctor
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
67 DVLOG(2) << "Initializing VAVDA, profile: " << profile; | |
68 | |
69 // TODO(posciak): try moving the flag check up to higher layers, possibly | |
70 // out of the GPU process. | |
71 bool res = CommandLine::ForCurrentProcess()->HasSwitch( | |
72 switches::kEnableVaapi); | |
73 RETURN_AND_NOTIFY_ON_FAILURE(res, "Vaapi HW acceleration disabled", | |
74 PLATFORM_FAILURE, false); | |
75 | |
76 res = decoder_.Initialize(profile, x_display_, glx_context_, | |
77 base::Bind(&VaapiVideoDecodeAccelerator::OutputPicCallback, this)); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
indent style is inconsistent with first arg above.
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
78 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed initializing decoder", | |
79 PLATFORM_FAILURE, false); | |
80 | |
81 res = decoder_thread_.Start(); | |
82 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed starting decoder thread", | |
83 PLATFORM_FAILURE, false); | |
84 | |
85 state_ = kInitialized; | |
86 | |
87 message_loop_->PostTask(FROM_HERE, base::Bind( | |
88 &VaapiVideoDecodeAccelerator::NotifyInitializeDone, this)); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
GVDA is in charge of calling NotifyInitializeDone(
Pawel Osciak
2012/05/06 17:49:19
As per chat, this is required, at least for now.
| |
89 return true; | |
90 } | |
91 | |
92 void VaapiVideoDecodeAccelerator::NotifyInitializeDone() { | |
93 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
94 DCHECK(client_); | |
95 if (client_) | |
96 client_->NotifyInitializeDone(); | |
97 } | |
98 | |
99 void VaapiVideoDecodeAccelerator::SetGlxState(Display* x_display, | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
Add TODO to move these to be ctor params?
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
100 GLXContext glx_context) { | |
101 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
102 x_display_ = x_display; | |
103 glx_context_ = glx_context; | |
104 } | |
105 | |
106 void VaapiVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { | |
107 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
108 | |
109 DVLOG(4) << "Notifying end of input buffer " << input_buffer_id; | |
110 DCHECK(client_); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
DCHECK() means it is a programming invariant that
Pawel Osciak
2012/05/06 17:49:19
Yeah, debugging artifact.
| |
111 if (client_) | |
112 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); | |
113 } | |
114 | |
115 void VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady(int32 input_id, | |
116 int32 output_id) { | |
117 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
118 | |
119 // Sync the contents of the texture. | |
120 RETURN_AND_NOTIFY_ON_FAILURE(decoder_.PutPicToTexture(output_id), | |
121 "Failed putting picture to texture", | |
122 PLATFORM_FAILURE, ); | |
123 | |
124 // And notify the client a picture is ready to be displayed. | |
125 media::Picture picture(output_id, input_id); | |
126 DVLOG(4) << "Notifying output picture id " << output_id | |
127 << " for input "<< input_id << " is ready"; | |
128 DCHECK(client_); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
Ditto remove the DCHECK.
Please make a pass over
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
129 if (client_) | |
130 client_->PictureReady(picture); | |
131 } | |
132 | |
133 void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer( | |
134 const media::BitstreamBuffer& bitstream_buffer) { | |
135 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
136 | |
137 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() | |
138 << " size: " << (int)bitstream_buffer.size(); | |
139 | |
140 scoped_ptr<base::SharedMemory> shm( | |
141 new base::SharedMemory(bitstream_buffer.handle(), true)); | |
142 RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(bitstream_buffer.size()), | |
143 "Failed to map input buffer", UNREADABLE_INPUT,); | |
144 | |
145 // Set up a new input buffer and queue it for later. | |
146 linked_ptr<InputBuffer> input_buffer(new InputBuffer()); | |
147 input_buffer->shm.reset(shm.release()); | |
148 input_buffer->id = bitstream_buffer.id(); | |
149 input_buffer->size = bitstream_buffer.size(); | |
150 | |
151 base::AutoLock auto_lock(lock_); | |
152 input_buffers_.push(input_buffer); | |
153 input_ready_.Signal(); | |
154 } | |
155 | |
156 void VaapiVideoDecodeAccelerator::InitialDecodeTask() { | |
157 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
158 | |
159 // Try to initialize or resume playback after reset. | |
160 for (;;) { | |
161 if (!GetInputBuffer()) | |
162 return; | |
163 DCHECK(curr_input_buffer_.get()); | |
164 | |
165 VaapiH264Decoder::DecResult res = decoder_.DecodeInitial( | |
166 curr_input_buffer_->id); | |
167 switch (res) { | |
168 case VaapiH264Decoder::kReadyToDecode: | |
169 message_loop_->PostTask(FROM_HERE, base::Bind( | |
170 &VaapiVideoDecodeAccelerator::ReadyToDecode, this, | |
171 decoder_.GetRequiredNumOfPictures(), | |
172 decoder_.pic_width(), decoder_.pic_height())); | |
173 return; | |
174 | |
175 case VaapiH264Decoder::kNeedMoreStreamData: | |
176 ReturnCurrInputBuffer(); | |
177 break; | |
178 | |
179 case VaapiH264Decoder::kDecodeError: | |
180 RETURN_AND_NOTIFY_ON_FAILURE(false, "Error in decoding", | |
181 PLATFORM_FAILURE, ); | |
182 | |
183 default: | |
184 RETURN_AND_NOTIFY_ON_FAILURE(false, "Unexpected result from decoder", | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
s/decoder",/decoder: " << res,/
will also log the
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
185 PLATFORM_FAILURE, ); | |
186 } | |
187 } | |
188 } | |
189 | |
190 bool VaapiVideoDecodeAccelerator::GetInputBuffer() { | |
191 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
192 | |
193 base::AutoLock auto_lock(lock_); | |
194 | |
195 if (curr_input_buffer_.get()) | |
196 return true; | |
197 | |
198 while (input_buffers_.empty() && | |
199 (state_ == kDecoding || state_ == kInitialized || state_ == kIdle)) | |
200 input_ready_.Wait(); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
multi-line while/if/for statement requires braces
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
201 | |
202 if (state_ != kDecoding && state_ != kInitialized && state_ != kIdle) | |
203 return false; | |
204 | |
205 curr_input_buffer_ = input_buffers_.front(); | |
206 input_buffers_.pop(); | |
207 | |
208 DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id | |
209 << " size: " << (int)curr_input_buffer_->size; | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
(int) unnecessary
(and if it was, it should be usi
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
210 | |
211 decoder_.SetStream(static_cast<uint8*>(curr_input_buffer_->shm->memory()), | |
212 curr_input_buffer_->size); | |
213 return true; | |
214 } | |
215 | |
216 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer() { | |
217 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
218 | |
219 DCHECK(curr_input_buffer_.get()); | |
220 int32 id = curr_input_buffer_->id; | |
221 curr_input_buffer_.reset(); | |
222 message_loop_->PostTask(FROM_HERE, base::Bind( | |
223 &VaapiVideoDecodeAccelerator::NotifyInputBufferRead, this, id)); | |
224 } | |
225 | |
226 bool VaapiVideoDecodeAccelerator::GetOutputBuffers() { | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
This method doesn't call RequestPictureBuffers. W
Pawel Osciak
2012/05/06 17:49:19
GetInputBuffer() above doesn't request them either
| |
227 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
228 | |
229 base::AutoLock auto_lock(lock_); | |
230 | |
231 while (output_buffers_.empty() && state_ == kDecoding) | |
232 output_ready_.Wait(); | |
233 | |
234 if (state_ != kDecoding) | |
235 return false; | |
236 | |
237 while (!output_buffers_.empty()) { | |
238 decoder_.ReusePictureBuffer(output_buffers_.front()); | |
239 output_buffers_.pop(); | |
240 } | |
241 | |
242 return true; | |
243 } | |
244 | |
245 void VaapiVideoDecodeAccelerator::DecodeTask() { | |
246 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
247 VaapiH264Decoder::DecResult res; | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
declare at first use below?
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
248 | |
249 // Main decode task. | |
250 DVLOG(4) << "Decode task"; | |
251 DCHECK_EQ(state_, kDecoding); | |
252 | |
253 // Try to decode what stream data is (still) in the decoder until we run out | |
254 // of it. | |
255 for (;;) { | |
256 if (!GetInputBuffer()) | |
257 // Early exit requested. | |
258 return; | |
259 DCHECK(curr_input_buffer_.get()); | |
260 | |
261 res = decoder_.DecodeOneFrame(curr_input_buffer_->id); | |
262 switch (res) { | |
263 case VaapiH264Decoder::kNeedMoreStreamData: | |
264 ReturnCurrInputBuffer(); | |
265 break; | |
266 | |
267 case VaapiH264Decoder::kDecodedFrame: | |
268 // May still have more stream data, continue decoding. | |
269 break; | |
270 | |
271 case VaapiH264Decoder::kNoOutputAvailable: | |
272 // No more output buffers in the decoder, try getting more or go to | |
273 // sleep waiting for them. | |
274 if (!GetOutputBuffers()) | |
275 return; | |
276 break; | |
277 | |
278 case VaapiH264Decoder::kDecodeError: | |
279 RETURN_AND_NOTIFY_ON_FAILURE(false, "Error decoding stream", | |
280 PLATFORM_FAILURE, ); | |
281 return; | |
282 | |
283 default: | |
284 RETURN_AND_NOTIFY_ON_FAILURE(false, | |
285 "Unexpected result from the decoder", PLATFORM_FAILURE, ); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
inconsistent indent style
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
s/",/" << res,/
Pawel Osciak
2012/05/06 17:49:19
Now I know :)
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
286 return; | |
287 } | |
288 } | |
289 } | |
290 | |
291 void VaapiVideoDecodeAccelerator::ReadyToDecode(int num_pics, | |
292 int width, | |
293 int height) { | |
294 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
295 | |
296 base::AutoLock auto_lock(lock_); | |
297 switch (state_) { | |
298 case kInitialized: | |
299 DVLOG(1) << "Requesting " << num_pics << " pictures of size: " | |
300 << width << "x" << height; | |
301 DCHECK(client_); | |
302 if (client_) | |
303 client_->ProvidePictureBuffers(num_pics, gfx::Size(width, height)); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
FWIW, passing a gfx::Size instead of two ints is l
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
304 state_ = kPicturesRequested; | |
305 break; | |
306 case kIdle: | |
307 state_ = kDecoding; | |
308 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
309 base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask, this)); | |
310 break; | |
311 default: | |
312 NOTREACHED() << "Invalid state"; | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
RETURN_AND_NOTIFY_ON_FAILURE ?
Pawel Osciak
2012/05/06 17:49:19
Well, this would be a a bug, so I thought NOTREACH
| |
313 } | |
314 } | |
315 | |
316 void VaapiVideoDecodeAccelerator::Decode( | |
317 const media::BitstreamBuffer& bitstream_buffer) { | |
318 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
319 | |
320 TRACE_EVENT1("Video Decoder", "VAVDA::Decode", "Buffer id", | |
321 bitstream_buffer.id()); | |
322 | |
323 // We got a new input buffer from the client, map it and queue for later use. | |
324 MapAndQueueNewInputBuffer(bitstream_buffer); | |
325 | |
326 switch (state_) { | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
This is reading state_ without holding the lock_.
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
327 case kInitialized: | |
328 // Initial decode to get the required size of output buffers. | |
329 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
330 base::Bind(&VaapiVideoDecodeAccelerator::InitialDecodeTask, this)); | |
331 break; | |
332 | |
333 case kPicturesRequested: | |
334 // Waiting for pictures, return. | |
335 break; | |
336 | |
337 case kDecoding: | |
338 break; | |
339 | |
340 case kIdle: | |
341 // Need to get decoder into suitable stream location to resume. | |
342 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
343 base::Bind(&VaapiVideoDecodeAccelerator::InitialDecodeTask, this)); | |
344 break; | |
345 | |
346 default: | |
347 return; | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
silently? shouldn't this complain?
Pawel Osciak
2012/05/06 17:49:19
This means we are shutting down/destroying or othe
| |
348 } | |
349 } | |
350 | |
351 void VaapiVideoDecodeAccelerator::AssignPictureBuffers( | |
352 const std::vector<media::PictureBuffer>& buffers) { | |
353 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
354 | |
355 base::AutoLock auto_lock(lock_); | |
356 DCHECK_EQ(state_, kPicturesRequested); | |
357 | |
358 for (size_t i = 0; i < buffers.size(); ++i) { | |
359 DVLOG(2) << "Assigning picture id " << buffers[i].id() | |
360 << " to texture id " << buffers[i].texture_id(); | |
361 | |
362 bool res = decoder_.AssignPictureBuffer(buffers[i].id(), | |
363 buffers[i].texture_id()); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
inconsistent indent.
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
364 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed assigning picture buffer", | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
could also << the buffer's id & the texture's id (
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
365 PLATFORM_FAILURE, ); | |
366 } | |
367 | |
368 state_ = kDecoding; | |
369 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
370 base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask, this)); | |
371 } | |
372 | |
373 void VaapiVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { | |
374 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
375 TRACE_EVENT1("Video Decoder", "VAVDA::ReusePictureBuffer", "Picture id", | |
376 picture_buffer_id); | |
377 | |
378 base::AutoLock auto_lock(lock_); | |
379 output_buffers_.push(picture_buffer_id); | |
380 output_ready_.Signal(); | |
381 } | |
382 | |
383 void VaapiVideoDecodeAccelerator::FlushTask() { | |
384 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
385 DVLOG(1) << "Flush task"; | |
386 | |
387 // First flush all the pictures that haven't been outputted, notifying the | |
388 // client to output them. | |
389 decoder_.Flush(); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
If this fails shouldn't this NotifyError instead o
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
I think you missed this comment from my previous r
Pawel Osciak
2012/05/06 17:49:19
Good idea.
Pawel Osciak
2012/05/06 17:49:19
This task is posted by Reset, so it gets queued af
| |
390 | |
391 // Put the decoder in idle state, ready to resume. | |
392 decoder_.Reset(); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
Should Decoder::Flush always call its own Reset()?
Pawel Osciak
2012/05/06 17:49:19
No, there are cases when it flushes itself without
| |
393 | |
394 message_loop_->PostTask(FROM_HERE, | |
395 base::Bind(&VaapiVideoDecodeAccelerator::FinishFlush, this)); | |
396 } | |
397 | |
398 void VaapiVideoDecodeAccelerator::Flush() { | |
399 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
400 DVLOG(1) << "Got flush request"; | |
401 | |
402 base::AutoLock auto_lock(lock_); | |
403 state_ = kFlushing; | |
404 // Queue a flush task after all existing decoding tasks to clean up. | |
405 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
406 base::Bind(&VaapiVideoDecodeAccelerator::FlushTask, this)); | |
407 | |
408 input_ready_.Signal(); | |
409 output_ready_.Signal(); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
Both this pair of Signal()'s and the corresponding
Pawel Osciak
2012/05/06 17:49:19
I actually wanted to emphasize state being changed
| |
410 } | |
411 | |
412 void VaapiVideoDecodeAccelerator::FinishFlush() { | |
413 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
414 | |
415 base::AutoLock auto_lock(lock_); | |
416 | |
417 if (state_ != kFlushing) | |
418 return; // We could've gotten destroyed already. | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
DCHECK that?
Pawel Osciak
2012/05/06 17:49:19
This is an intentional early exit in case we get a
| |
419 | |
420 state_ = kIdle; | |
421 | |
422 if (client_) | |
423 client_->NotifyFlushDone(); | |
424 | |
425 DVLOG(1) << "Flush finished"; | |
426 } | |
427 | |
428 void VaapiVideoDecodeAccelerator::ResetTask() { | |
429 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
430 | |
431 // All the decoding tasks from before the reset request from client are done | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
english up this comment
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
432 // by now, since the client should not we got a reset request. | |
433 decoder_.Reset(); | |
434 | |
435 base::AutoLock auto_lock(lock_); | |
436 // Return current input buffer, if present. | |
437 if (curr_input_buffer_.get()) | |
438 ReturnCurrInputBuffer(); | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
indent -2
Pawel Osciak
2012/05/06 17:49:19
Done.
| |
439 | |
440 // And let client know that we are done with reset. | |
441 message_loop_->PostTask(FROM_HERE, base::Bind( | |
442 &VaapiVideoDecodeAccelerator::FinishReset, this)); | |
443 } | |
444 | |
445 void VaapiVideoDecodeAccelerator::Reset() { | |
446 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
447 DVLOG(1) << "Got reset request"; | |
448 | |
449 // This will make any new decode tasks exit early. | |
450 base::AutoLock auto_lock(lock_); | |
451 state_ = kResetting; | |
452 | |
453 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
454 base::Bind(&VaapiVideoDecodeAccelerator::ResetTask, this)); | |
455 | |
456 input_ready_.Signal(); | |
457 output_ready_.Signal(); | |
458 } | |
459 | |
460 void VaapiVideoDecodeAccelerator::FinishReset() { | |
461 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
462 | |
463 base::AutoLock auto_lock(lock_); | |
464 if (state_ != kResetting) | |
465 return; // We could've gotten destroyed already. | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
DCHECK that
Pawel Osciak
2012/05/06 17:49:19
This is an intentional early exit, if we get a des
| |
466 | |
467 // Drop all remaining input buffers, if present. | |
468 while (!input_buffers_.empty()) | |
469 input_buffers_.pop(); | |
470 | |
471 state_ = kIdle; | |
472 | |
473 if (client_) | |
474 client_->NotifyResetDone(); | |
475 | |
476 DVLOG(1) << "Reset finished"; | |
477 } | |
478 | |
479 void VaapiVideoDecodeAccelerator::DestroyTask() { | |
480 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
481 | |
482 base::AutoLock auto_lock(lock_); | |
483 decoder_.Destroy(); | |
484 state_ = kUninitialized; | |
485 } | |
486 | |
487 void VaapiVideoDecodeAccelerator::Destroy() { | |
488 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
489 | |
490 if (state_ == kUninitialized || state_ == kDestroying) | |
Ami GONE FROM CHROMIUM
2012/05/03 23:22:53
This reads state_ not under lock_.
Move the auto_l
Pawel Osciak
2012/05/06 17:49:19
All the places had been properly checked :)
This i
| |
491 return; | |
492 | |
493 DVLOG(1) << "Destroying VAVDA"; | |
494 | |
495 base::AutoLock auto_lock(lock_); | |
496 state_ = kDestroying; | |
497 input_ready_.Signal(); | |
498 output_ready_.Signal(); | |
499 | |
500 decoder_thread_.message_loop()->PostTask(FROM_HERE, | |
501 base::Bind(&VaapiVideoDecodeAccelerator::DestroyTask, this)); | |
502 client_ = NULL; | |
503 } | |
504 | |
505 void VaapiVideoDecodeAccelerator::OutputPicCallback(int32 input_id, | |
506 int32 output_id) { | |
507 TRACE_EVENT2("Video Decoder", "VAVDA::OutputPicCallback", | |
508 "Input id", input_id, "Picture id", output_id); | |
509 DVLOG(4) << "Outputting picture, input id: " << input_id | |
510 << " output id: " << output_id; | |
511 | |
512 // Forward the request to the main thread. | |
513 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | |
514 message_loop_->PostTask(FROM_HERE, | |
515 base::Bind(&VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady, | |
516 this, input_id, output_id)); | |
517 } | |
518 | |
OLD | NEW |