| 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 "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/cpu.h" | 11 #include "base/cpu.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/synchronization/waitable_event.h" | |
| 16 #include "base/task_runner_util.h" | 15 #include "base/task_runner_util.h" |
| 17 #include "media/base/bind_to_current_loop.h" | 16 #include "media/base/bind_to_current_loop.h" |
| 18 #include "media/base/decoder_buffer.h" | 17 #include "media/base/decoder_buffer.h" |
| 19 #include "media/base/media_log.h" | 18 #include "media/base/media_log.h" |
| 20 #include "media/base/pipeline.h" | 19 #include "media/base/pipeline.h" |
| 21 #include "media/base/pipeline_status.h" | 20 #include "media/base/pipeline_status.h" |
| 22 #include "media/base/video_decoder_config.h" | 21 #include "media/base/video_decoder_config.h" |
| 23 #include "media/filters/gpu_video_accelerator_factories.h" | 22 #include "media/filters/gpu_video_accelerator_factories.h" |
| 24 #include "third_party/skia/include/core/SkBitmap.h" | |
| 25 | 23 |
| 26 namespace media { | 24 namespace media { |
| 27 | 25 |
| 28 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. | 26 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. |
| 29 // Higher values allow better pipelining in the GPU, but also require more | 27 // Higher values allow better pipelining in the GPU, but also require more |
| 30 // resources. | 28 // resources. |
| 31 enum { kMaxInFlightDecodes = 4 }; | 29 enum { kMaxInFlightDecodes = 4 }; |
| 32 | 30 |
| 33 // Size of shared-memory segments we allocate. Since we reuse them we let them | 31 // Size of shared-memory segments we allocate. Since we reuse them we let them |
| 34 // be on the beefy side. | 32 // be on the beefy side. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 next_picture_buffer_id_(0), | 65 next_picture_buffer_id_(0), |
| 68 next_bitstream_buffer_id_(0), | 66 next_bitstream_buffer_id_(0), |
| 69 available_pictures_(0) { | 67 available_pictures_(0) { |
| 70 DCHECK(factories_.get()); | 68 DCHECK(factories_.get()); |
| 71 } | 69 } |
| 72 | 70 |
| 73 void GpuVideoDecoder::Reset(const base::Closure& closure) { | 71 void GpuVideoDecoder::Reset(const base::Closure& closure) { |
| 74 DVLOG(3) << "Reset()"; | 72 DVLOG(3) << "Reset()"; |
| 75 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 73 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 76 | 74 |
| 77 if (state_ == kDrainingDecoder) { | 75 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { |
| 78 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 76 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 79 &GpuVideoDecoder::Reset, weak_this_, closure)); | 77 &GpuVideoDecoder::Reset, weak_this_, closure)); |
| 80 // NOTE: if we're deferring Reset() until a Flush() completes, return | 78 // NOTE: if we're deferring Reset() until a Flush() completes, return |
| 81 // queued pictures to the VDA so they can be used to finish that Flush(). | 79 // queued pictures to the VDA so they can be used to finish that Flush(). |
| 82 if (pending_decode_cb_.is_null()) | 80 if (pending_decode_cb_.is_null()) |
| 83 ready_video_frames_.clear(); | 81 ready_video_frames_.clear(); |
| 84 return; | 82 return; |
| 85 } | 83 } |
| 86 | 84 |
| 87 // Throw away any already-decoded, not-yet-delivered frames. | 85 // Throw away any already-decoded, not-yet-delivered frames. |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 CHECK_GT(available_pictures_, 0); | 413 CHECK_GT(available_pictures_, 0); |
| 416 --available_pictures_; | 414 --available_pictures_; |
| 417 } else { | 415 } else { |
| 418 // Texture in display. Postpone deletion until after it's returned to us. | 416 // Texture in display. Postpone deletion until after it's returned to us. |
| 419 bool inserted = dismissed_picture_buffers_.insert(std::make_pair( | 417 bool inserted = dismissed_picture_buffers_.insert(std::make_pair( |
| 420 id, buffer_to_dismiss)).second; | 418 id, buffer_to_dismiss)).second; |
| 421 DCHECK(inserted); | 419 DCHECK(inserted); |
| 422 } | 420 } |
| 423 } | 421 } |
| 424 | 422 |
| 425 static void ReadPixelsSyncInner( | |
| 426 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | |
| 427 uint32 texture_id, | |
| 428 const gfx::Rect& visible_rect, | |
| 429 const SkBitmap& pixels, | |
| 430 base::WaitableEvent* event) { | |
| 431 factories->ReadPixels(texture_id, visible_rect, pixels); | |
| 432 event->Signal(); | |
| 433 } | |
| 434 | |
| 435 static void ReadPixelsSync( | |
| 436 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, | |
| 437 uint32 texture_id, | |
| 438 const gfx::Rect& visible_rect, | |
| 439 const SkBitmap& pixels) { | |
| 440 base::WaitableEvent event(true, false); | |
| 441 if (!factories->GetTaskRunner()->PostTask(FROM_HERE, | |
| 442 base::Bind(&ReadPixelsSyncInner, | |
| 443 factories, | |
| 444 texture_id, | |
| 445 visible_rect, | |
| 446 pixels, | |
| 447 &event))) | |
| 448 return; | |
| 449 event.Wait(); | |
| 450 } | |
| 451 | |
| 452 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { | 423 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { |
| 453 DVLOG(3) << "PictureReady()"; | 424 DVLOG(3) << "PictureReady()"; |
| 454 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 425 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 455 | 426 |
| 456 PictureBufferMap::iterator it = | 427 PictureBufferMap::iterator it = |
| 457 assigned_picture_buffers_.find(picture.picture_buffer_id()); | 428 assigned_picture_buffers_.find(picture.picture_buffer_id()); |
| 458 if (it == assigned_picture_buffers_.end()) { | 429 if (it == assigned_picture_buffers_.end()) { |
| 459 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); | 430 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); |
| 460 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 431 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 461 return; | 432 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 475 pb.texture_mailbox(), | 446 pb.texture_mailbox(), |
| 476 0, // sync_point | 447 0, // sync_point |
| 477 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::ReusePictureBuffer, | 448 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::ReusePictureBuffer, |
| 478 weak_this_, | 449 weak_this_, |
| 479 picture.picture_buffer_id())))), | 450 picture.picture_buffer_id())))), |
| 480 decoder_texture_target_, | 451 decoder_texture_target_, |
| 481 pb.size(), | 452 pb.size(), |
| 482 visible_rect, | 453 visible_rect, |
| 483 natural_size, | 454 natural_size, |
| 484 timestamp, | 455 timestamp, |
| 485 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect), | 456 base::Bind(&GpuVideoAcceleratorFactories::ReadPixels, |
| 457 factories_, |
| 458 pb.texture_id(), |
| 459 gfx::Size(visible_rect.width(), visible_rect.height())), |
| 486 base::Closure())); | 460 base::Closure())); |
| 487 CHECK_GT(available_pictures_, 0); | 461 CHECK_GT(available_pictures_, 0); |
| 488 --available_pictures_; | 462 --available_pictures_; |
| 489 bool inserted = | 463 bool inserted = |
| 490 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; | 464 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; |
| 491 DCHECK(inserted); | 465 DCHECK(inserted); |
| 492 | 466 |
| 493 EnqueueFrameAndTriggerFrameDelivery(frame); | 467 EnqueueFrameAndTriggerFrameDelivery(frame); |
| 494 } | 468 } |
| 495 | 469 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 return; | 621 return; |
| 648 } | 622 } |
| 649 } | 623 } |
| 650 | 624 |
| 651 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 625 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
| 652 const { | 626 const { |
| 653 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 627 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 654 } | 628 } |
| 655 | 629 |
| 656 } // namespace media | 630 } // namespace media |
| OLD | NEW |