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

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

Issue 9814001: Add VAVDA, the VAAPI Video Decode Accelerator for Intel CPUs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing previous CR + threading redesign Created 8 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 | Annotate | Revision Log
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 #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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698