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 |