| OLD | NEW |
| 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 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 using content::VaapiH264Decoder; | 29 using content::VaapiH264Decoder; |
| 30 | 30 |
| 31 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() { | 31 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() { |
| 32 } | 32 } |
| 33 | 33 |
| 34 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { | 34 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { |
| 35 } | 35 } |
| 36 | 36 |
| 37 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { | 37 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { |
| 38 if (message_loop_ != MessageLoop::current()) { | 38 if (message_loop_ != MessageLoop::current()) { |
| 39 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
| 39 message_loop_->PostTask(FROM_HERE, base::Bind( | 40 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 40 &VaapiVideoDecodeAccelerator::NotifyError, this, error)); | 41 &VaapiVideoDecodeAccelerator::NotifyError, weak_this_, error)); |
| 41 return; | 42 return; |
| 42 } | 43 } |
| 43 | 44 |
| 44 DVLOG(1) << "Notifying of error " << error; | 45 DVLOG(1) << "Notifying of error " << error; |
| 45 | 46 |
| 46 if (client_) { | 47 if (client_) { |
| 47 client_->NotifyError(error); | 48 client_->NotifyError(error); |
| 48 client_ptr_factory_.InvalidateWeakPtrs(); | 49 client_ptr_factory_.InvalidateWeakPtrs(); |
| 49 } | 50 } |
| 50 Destroy(); | 51 Destroy(false); |
| 51 } | 52 } |
| 52 | 53 |
| 53 VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( | 54 VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( |
| 54 Client* client, | 55 Client* client, |
| 55 const base::Callback<bool(void)>& make_context_current) | 56 const base::Callback<bool(void)>& make_context_current) |
| 56 : make_context_current_(make_context_current), | 57 : make_context_current_(make_context_current), |
| 57 state_(kUninitialized), | 58 state_(kUninitialized), |
| 58 input_ready_(&lock_), | 59 input_ready_(&lock_), |
| 59 output_ready_(&lock_), | 60 output_ready_(&lock_), |
| 60 message_loop_(MessageLoop::current()), | 61 message_loop_(MessageLoop::current()), |
| 62 weak_this_(base::AsWeakPtr(this)), |
| 61 client_ptr_factory_(client), | 63 client_ptr_factory_(client), |
| 62 client_(client_ptr_factory_.GetWeakPtr()), | 64 client_(client_ptr_factory_.GetWeakPtr()), |
| 63 decoder_thread_("VaapiDecoderThread") { | 65 decoder_thread_("VaapiDecoderThread") { |
| 64 DCHECK(client); | 66 DCHECK(client); |
| 65 } | 67 } |
| 66 | 68 |
| 67 VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { | 69 VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { |
| 68 DCHECK_EQ(message_loop_, MessageLoop::current()); | 70 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 69 } | 71 } |
| 70 | 72 |
| 71 bool VaapiVideoDecodeAccelerator::Initialize( | 73 bool VaapiVideoDecodeAccelerator::Initialize( |
| 72 media::VideoCodecProfile profile) { | 74 media::VideoCodecProfile profile) { |
| 73 DCHECK_EQ(message_loop_, MessageLoop::current()); | 75 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 74 | 76 |
| 75 base::AutoLock auto_lock(lock_); | 77 base::AutoLock auto_lock(lock_); |
| 76 DCHECK_EQ(state_, kUninitialized); | 78 DCHECK_EQ(state_, kUninitialized); |
| 77 DVLOG(2) << "Initializing VAVDA, profile: " << profile; | 79 DVLOG(2) << "Initializing VAVDA, profile: " << profile; |
| 78 | 80 |
| 79 bool res = decoder_.Initialize( | 81 bool res = decoder_.Initialize( |
| 80 profile, x_display_, glx_context_, make_context_current_, | 82 profile, x_display_, glx_context_, make_context_current_, |
| 81 base::Bind(&VaapiVideoDecodeAccelerator::OutputPicCallback, this)); | 83 base::Bind(&VaapiVideoDecodeAccelerator::OutputPicCallback, |
| 84 base::Unretained(this))); |
| 82 if (!res) { | 85 if (!res) { |
| 83 DVLOG(1) << "Failed initializing decoder"; | 86 DVLOG(1) << "Failed initializing decoder"; |
| 84 return false; | 87 return false; |
| 85 } | 88 } |
| 86 | 89 |
| 87 CHECK(decoder_thread_.Start()); | 90 CHECK(decoder_thread_.Start()); |
| 88 | 91 |
| 89 state_ = kInitialized; | 92 state_ = kInitialized; |
| 90 | 93 |
| 91 message_loop_->PostTask(FROM_HERE, base::Bind( | 94 message_loop_->PostTask(FROM_HERE, base::Bind( |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 DVLOG(1) << "Requesting " << num_pics << " pictures of size: " | 177 DVLOG(1) << "Requesting " << num_pics << " pictures of size: " |
| 175 << size.width() << "x" << size.height(); | 178 << size.width() << "x" << size.height(); |
| 176 message_loop_->PostTask(FROM_HERE, base::Bind( | 179 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 177 &Client::ProvidePictureBuffers, client_, | 180 &Client::ProvidePictureBuffers, client_, |
| 178 num_pics, size, GL_TEXTURE_2D)); | 181 num_pics, size, GL_TEXTURE_2D)); |
| 179 } else { | 182 } else { |
| 180 base::AutoLock auto_lock(lock_); | 183 base::AutoLock auto_lock(lock_); |
| 181 DCHECK_EQ(state_, kIdle); | 184 DCHECK_EQ(state_, kIdle); |
| 182 state_ = kDecoding; | 185 state_ = kDecoding; |
| 183 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 186 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 184 &VaapiVideoDecodeAccelerator::DecodeTask, this)); | 187 &VaapiVideoDecodeAccelerator::DecodeTask, |
| 188 base::Unretained(this))); |
| 185 } | 189 } |
| 186 return; | 190 return; |
| 187 | 191 |
| 188 case VaapiH264Decoder::kNeedMoreStreamData: | 192 case VaapiH264Decoder::kNeedMoreStreamData: |
| 189 ReturnCurrInputBuffer(); | 193 ReturnCurrInputBuffer(); |
| 190 break; | 194 break; |
| 191 | 195 |
| 192 case VaapiH264Decoder::kDecodeError: | 196 case VaapiH264Decoder::kDecodeError: |
| 193 RETURN_AND_NOTIFY_ON_FAILURE(false, "Error in decoding", | 197 RETURN_AND_NOTIFY_ON_FAILURE(false, "Error in decoding", |
| 194 PLATFORM_FAILURE, ); | 198 PLATFORM_FAILURE, ); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 TRACE_EVENT1("Video Decoder", "VAVDA::Decode", "Buffer id", | 339 TRACE_EVENT1("Video Decoder", "VAVDA::Decode", "Buffer id", |
| 336 bitstream_buffer.id()); | 340 bitstream_buffer.id()); |
| 337 | 341 |
| 338 // We got a new input buffer from the client, map it and queue for later use. | 342 // We got a new input buffer from the client, map it and queue for later use. |
| 339 MapAndQueueNewInputBuffer(bitstream_buffer); | 343 MapAndQueueNewInputBuffer(bitstream_buffer); |
| 340 | 344 |
| 341 base::AutoLock auto_lock(lock_); | 345 base::AutoLock auto_lock(lock_); |
| 342 switch (state_) { | 346 switch (state_) { |
| 343 case kInitialized: | 347 case kInitialized: |
| 344 // Initial decode to get the required size of output buffers. | 348 // Initial decode to get the required size of output buffers. |
| 345 decoder_thread_.message_loop()->PostTask(FROM_HERE, | 349 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 346 base::Bind(&VaapiVideoDecodeAccelerator::InitialDecodeTask, this)); | 350 &VaapiVideoDecodeAccelerator::InitialDecodeTask, |
| 351 base::Unretained(this))); |
| 347 break; | 352 break; |
| 348 | 353 |
| 349 case kPicturesRequested: | 354 case kPicturesRequested: |
| 350 // Waiting for pictures, return. | 355 // Waiting for pictures, return. |
| 351 break; | 356 break; |
| 352 | 357 |
| 353 case kDecoding: | 358 case kDecoding: |
| 354 break; | 359 break; |
| 355 | 360 |
| 356 case kIdle: | 361 case kIdle: |
| 357 // Need to get decoder into suitable stream location to resume. | 362 // Need to get decoder into suitable stream location to resume. |
| 358 decoder_thread_.message_loop()->PostTask(FROM_HERE, | 363 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 359 base::Bind(&VaapiVideoDecodeAccelerator::InitialDecodeTask, this)); | 364 &VaapiVideoDecodeAccelerator::InitialDecodeTask, |
| 365 base::Unretained(this))); |
| 360 break; | 366 break; |
| 361 | 367 |
| 362 default: | 368 default: |
| 363 DVLOG(1) << "Decode request from client in invalid state: " << state_; | 369 DVLOG(1) << "Decode request from client in invalid state: " << state_; |
| 364 return; | 370 return; |
| 365 } | 371 } |
| 366 } | 372 } |
| 367 | 373 |
| 368 void VaapiVideoDecodeAccelerator::AssignPictureBuffers( | 374 void VaapiVideoDecodeAccelerator::AssignPictureBuffers( |
| 369 const std::vector<media::PictureBuffer>& buffers) { | 375 const std::vector<media::PictureBuffer>& buffers) { |
| 370 DCHECK_EQ(message_loop_, MessageLoop::current()); | 376 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 371 | 377 |
| 372 base::AutoLock auto_lock(lock_); | 378 base::AutoLock auto_lock(lock_); |
| 373 DCHECK_EQ(state_, kPicturesRequested); | 379 DCHECK_EQ(state_, kPicturesRequested); |
| 374 | 380 |
| 375 for (size_t i = 0; i < buffers.size(); ++i) { | 381 for (size_t i = 0; i < buffers.size(); ++i) { |
| 376 DVLOG(2) << "Assigning picture id " << buffers[i].id() | 382 DVLOG(2) << "Assigning picture id " << buffers[i].id() |
| 377 << " to texture id " << buffers[i].texture_id(); | 383 << " to texture id " << buffers[i].texture_id(); |
| 378 | 384 |
| 379 bool res = decoder_.AssignPictureBuffer(buffers[i].id(), | 385 bool res = decoder_.AssignPictureBuffer(buffers[i].id(), |
| 380 buffers[i].texture_id()); | 386 buffers[i].texture_id()); |
| 381 RETURN_AND_NOTIFY_ON_FAILURE( | 387 RETURN_AND_NOTIFY_ON_FAILURE( |
| 382 res, "Failed assigning picture buffer id: " << buffers[i].id() << | 388 res, "Failed assigning picture buffer id: " << buffers[i].id() << |
| 383 ", texture id: " << buffers[i].texture_id(), PLATFORM_FAILURE, ); | 389 ", texture id: " << buffers[i].texture_id(), PLATFORM_FAILURE, ); |
| 384 } | 390 } |
| 385 | 391 |
| 386 state_ = kDecoding; | 392 state_ = kDecoding; |
| 387 decoder_thread_.message_loop()->PostTask(FROM_HERE, | 393 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 388 base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask, this)); | 394 &VaapiVideoDecodeAccelerator::DecodeTask, base::Unretained(this))); |
| 389 } | 395 } |
| 390 | 396 |
| 391 void VaapiVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { | 397 void VaapiVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { |
| 392 DCHECK_EQ(message_loop_, MessageLoop::current()); | 398 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 393 TRACE_EVENT1("Video Decoder", "VAVDA::ReusePictureBuffer", "Picture id", | 399 TRACE_EVENT1("Video Decoder", "VAVDA::ReusePictureBuffer", "Picture id", |
| 394 picture_buffer_id); | 400 picture_buffer_id); |
| 395 | 401 |
| 396 base::AutoLock auto_lock(lock_); | 402 base::AutoLock auto_lock(lock_); |
| 397 output_buffers_.push(picture_buffer_id); | 403 output_buffers_.push(picture_buffer_id); |
| 398 output_ready_.Signal(); | 404 output_ready_.Signal(); |
| 399 } | 405 } |
| 400 | 406 |
| 401 void VaapiVideoDecodeAccelerator::FlushTask() { | 407 void VaapiVideoDecodeAccelerator::FlushTask() { |
| 402 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 408 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
| 403 DVLOG(1) << "Flush task"; | 409 DVLOG(1) << "Flush task"; |
| 404 | 410 |
| 405 // First flush all the pictures that haven't been outputted, notifying the | 411 // First flush all the pictures that haven't been outputted, notifying the |
| 406 // client to output them. | 412 // client to output them. |
| 407 bool res = decoder_.Flush(); | 413 bool res = decoder_.Flush(); |
| 408 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.", | 414 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.", |
| 409 PLATFORM_FAILURE, ); | 415 PLATFORM_FAILURE, ); |
| 410 | 416 |
| 411 // Put the decoder in idle state, ready to resume. | 417 // Put the decoder in idle state, ready to resume. |
| 412 decoder_.Reset(); | 418 decoder_.Reset(); |
| 413 | 419 |
| 414 message_loop_->PostTask(FROM_HERE, | 420 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 415 base::Bind(&VaapiVideoDecodeAccelerator::FinishFlush, this)); | 421 &VaapiVideoDecodeAccelerator::FinishFlush, weak_this_)); |
| 416 } | 422 } |
| 417 | 423 |
| 418 void VaapiVideoDecodeAccelerator::Flush() { | 424 void VaapiVideoDecodeAccelerator::Flush() { |
| 419 DCHECK_EQ(message_loop_, MessageLoop::current()); | 425 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 420 DVLOG(1) << "Got flush request"; | 426 DVLOG(1) << "Got flush request"; |
| 421 | 427 |
| 422 base::AutoLock auto_lock(lock_); | 428 base::AutoLock auto_lock(lock_); |
| 423 state_ = kFlushing; | 429 state_ = kFlushing; |
| 424 // Queue a flush task after all existing decoding tasks to clean up. | 430 // Queue a flush task after all existing decoding tasks to clean up. |
| 425 decoder_thread_.message_loop()->PostTask(FROM_HERE, | 431 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 426 base::Bind(&VaapiVideoDecodeAccelerator::FlushTask, this)); | 432 &VaapiVideoDecodeAccelerator::FlushTask, base::Unretained(this))); |
| 427 | 433 |
| 428 input_ready_.Signal(); | 434 input_ready_.Signal(); |
| 429 output_ready_.Signal(); | 435 output_ready_.Signal(); |
| 430 } | 436 } |
| 431 | 437 |
| 432 void VaapiVideoDecodeAccelerator::FinishFlush() { | 438 void VaapiVideoDecodeAccelerator::FinishFlush() { |
| 433 DCHECK_EQ(message_loop_, MessageLoop::current()); | 439 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 434 | 440 |
| 435 base::AutoLock auto_lock(lock_); | 441 base::AutoLock auto_lock(lock_); |
| 436 if (state_ != kFlushing) { | 442 if (state_ != kFlushing) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 453 // by now, as this task was scheduled after them and client is expected not | 459 // by now, as this task was scheduled after them and client is expected not |
| 454 // to call Decode() after Reset() and before NotifyResetDone. | 460 // to call Decode() after Reset() and before NotifyResetDone. |
| 455 decoder_.Reset(); | 461 decoder_.Reset(); |
| 456 | 462 |
| 457 // Return current input buffer, if present. | 463 // Return current input buffer, if present. |
| 458 if (curr_input_buffer_.get()) | 464 if (curr_input_buffer_.get()) |
| 459 ReturnCurrInputBuffer(); | 465 ReturnCurrInputBuffer(); |
| 460 | 466 |
| 461 // And let client know that we are done with reset. | 467 // And let client know that we are done with reset. |
| 462 message_loop_->PostTask(FROM_HERE, base::Bind( | 468 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 463 &VaapiVideoDecodeAccelerator::FinishReset, this)); | 469 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); |
| 464 } | 470 } |
| 465 | 471 |
| 466 void VaapiVideoDecodeAccelerator::Reset() { | 472 void VaapiVideoDecodeAccelerator::Reset() { |
| 467 DCHECK_EQ(message_loop_, MessageLoop::current()); | 473 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 468 DVLOG(1) << "Got reset request"; | 474 DVLOG(1) << "Got reset request"; |
| 469 | 475 |
| 470 // This will make any new decode tasks exit early. | 476 // This will make any new decode tasks exit early. |
| 471 base::AutoLock auto_lock(lock_); | 477 base::AutoLock auto_lock(lock_); |
| 472 state_ = kResetting; | 478 state_ = kResetting; |
| 473 | 479 |
| 474 decoder_thread_.message_loop()->PostTask(FROM_HERE, | 480 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 475 base::Bind(&VaapiVideoDecodeAccelerator::ResetTask, this)); | 481 &VaapiVideoDecodeAccelerator::ResetTask, base::Unretained(this))); |
| 476 | 482 |
| 477 input_ready_.Signal(); | 483 input_ready_.Signal(); |
| 478 output_ready_.Signal(); | 484 output_ready_.Signal(); |
| 479 } | 485 } |
| 480 | 486 |
| 481 void VaapiVideoDecodeAccelerator::FinishReset() { | 487 void VaapiVideoDecodeAccelerator::FinishReset() { |
| 482 DCHECK_EQ(message_loop_, MessageLoop::current()); | 488 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 483 | 489 |
| 484 base::AutoLock auto_lock(lock_); | 490 base::AutoLock auto_lock(lock_); |
| 485 if (state_ != kResetting) { | 491 if (state_ != kResetting) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 496 } | 502 } |
| 497 | 503 |
| 498 state_ = kIdle; | 504 state_ = kIdle; |
| 499 | 505 |
| 500 message_loop_->PostTask(FROM_HERE, base::Bind( | 506 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 501 &Client::NotifyResetDone, client_)); | 507 &Client::NotifyResetDone, client_)); |
| 502 | 508 |
| 503 DVLOG(1) << "Reset finished"; | 509 DVLOG(1) << "Reset finished"; |
| 504 } | 510 } |
| 505 | 511 |
| 506 void VaapiVideoDecodeAccelerator::Destroy() { | 512 void VaapiVideoDecodeAccelerator::Destroy(bool pass_ownership) { |
| 507 DCHECK_EQ(message_loop_, MessageLoop::current()); | 513 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 514 scoped_ptr<VideoDecodeAccelerator> self(pass_ownership ? this : NULL); |
| 508 | 515 |
| 509 if (state_ == kUninitialized || state_ == kDestroying) | 516 if (state_ == kUninitialized || state_ == kDestroying) |
| 510 return; | 517 return; |
| 511 | 518 |
| 512 DVLOG(1) << "Destroying VAVDA"; | 519 DVLOG(1) << "Destroying VAVDA"; |
| 513 base::AutoLock auto_lock(lock_); | 520 base::AutoLock auto_lock(lock_); |
| 514 state_ = kDestroying; | 521 state_ = kDestroying; |
| 515 | 522 |
| 516 client_ptr_factory_.InvalidateWeakPtrs(); | 523 client_ptr_factory_.InvalidateWeakPtrs(); |
| 517 | 524 |
| 518 { | 525 { |
| 519 base::AutoUnlock auto_unlock(lock_); | 526 base::AutoUnlock auto_unlock(lock_); |
| 520 // Post a dummy task to the decoder_thread_ to ensure it is drained. | 527 // Post a dummy task to the decoder_thread_ to ensure it is drained. |
| 521 base::WaitableEvent waiter(false, false); | 528 base::WaitableEvent waiter(false, false); |
| 522 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 529 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 523 &base::WaitableEvent::Signal, base::Unretained(&waiter))); | 530 &base::WaitableEvent::Signal, base::Unretained(&waiter))); |
| 524 input_ready_.Signal(); | 531 input_ready_.Signal(); |
| 525 output_ready_.Signal(); | 532 output_ready_.Signal(); |
| 526 waiter.Wait(); | 533 waiter.Wait(); |
| 534 decoder_thread_.Stop(); |
| 527 } | 535 } |
| 528 | 536 |
| 529 decoder_.Destroy(); | 537 decoder_.Destroy(); |
| 530 state_ = kUninitialized; | 538 state_ = kUninitialized; |
| 531 } | 539 } |
| 532 | 540 |
| 533 void VaapiVideoDecodeAccelerator::OutputPicCallback(int32 input_id, | 541 void VaapiVideoDecodeAccelerator::OutputPicCallback(int32 input_id, |
| 534 int32 output_id) { | 542 int32 output_id) { |
| 535 TRACE_EVENT2("Video Decoder", "VAVDA::OutputPicCallback", | 543 TRACE_EVENT2("Video Decoder", "VAVDA::OutputPicCallback", |
| 536 "Input id", input_id, "Picture id", output_id); | 544 "Input id", input_id, "Picture id", output_id); |
| 537 DVLOG(4) << "Outputting picture, input id: " << input_id | 545 DVLOG(4) << "Outputting picture, input id: " << input_id |
| 538 << " output id: " << output_id; | 546 << " output id: " << output_id; |
| 539 | 547 |
| 540 // Forward the request to the main thread. | 548 // Forward the request to the main thread. |
| 541 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); | 549 DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current()); |
| 542 message_loop_->PostTask(FROM_HERE, | 550 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 543 base::Bind(&VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady, | 551 &VaapiVideoDecodeAccelerator::SyncAndNotifyPictureReady, weak_this_, |
| 544 this, input_id, output_id)); | 552 input_id, output_id)); |
| 545 } | 553 } |
| OLD | NEW |