| 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/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/task_runner_util.h" | 14 #include "base/task_runner_util.h" |
| 15 #include "media/base/bind_to_loop.h" | 15 #include "media/base/bind_to_loop.h" |
| 16 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
| 17 #include "media/base/pipeline.h" | 17 #include "media/base/pipeline.h" |
| 18 #include "media/base/pipeline_status.h" | 18 #include "media/base/pipeline_status.h" |
| 19 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 20 #include "media/filters/gpu_video_decoder_factories.h" | 20 #include "media/filters/gpu_video_accelerator_factories.h" |
| 21 | 21 |
| 22 namespace media { | 22 namespace media { |
| 23 | 23 |
| 24 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. | 24 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. |
| 25 // Higher values allow better pipelining in the GPU, but also require more | 25 // Higher values allow better pipelining in the GPU, but also require more |
| 26 // resources. | 26 // resources. |
| 27 enum { kMaxInFlightDecodes = 4 }; | 27 enum { kMaxInFlightDecodes = 4 }; |
| 28 | 28 |
| 29 // Size of shared-memory segments we allocate. Since we reuse them we let them | 29 // Size of shared-memory segments we allocate. Since we reuse them we let them |
| 30 // be on the beefy side. | 30 // be on the beefy side. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 45 | 45 |
| 46 GpuVideoDecoder::BufferData::BufferData( | 46 GpuVideoDecoder::BufferData::BufferData( |
| 47 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) | 47 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) |
| 48 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), | 48 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), |
| 49 natural_size(ns) { | 49 natural_size(ns) { |
| 50 } | 50 } |
| 51 | 51 |
| 52 GpuVideoDecoder::BufferData::~BufferData() {} | 52 GpuVideoDecoder::BufferData::~BufferData() {} |
| 53 | 53 |
| 54 GpuVideoDecoder::GpuVideoDecoder( | 54 GpuVideoDecoder::GpuVideoDecoder( |
| 55 const scoped_refptr<GpuVideoDecoderFactories>& factories) | 55 const scoped_refptr<GpuVideoAcceleratorFactories>& factories) |
| 56 : needs_bitstream_conversion_(false), | 56 : needs_bitstream_conversion_(false), |
| 57 gvd_loop_proxy_(factories->GetMessageLoop()), | 57 gvd_loop_proxy_(factories->GetMessageLoop()), |
| 58 weak_factory_(this), | 58 weak_factory_(this), |
| 59 factories_(factories), | 59 factories_(factories), |
| 60 state_(kNormal), | 60 state_(kNormal), |
| 61 decoder_texture_target_(0), | 61 decoder_texture_target_(0), |
| 62 next_picture_buffer_id_(0), | 62 next_picture_buffer_id_(0), |
| 63 next_bitstream_buffer_id_(0), | 63 next_bitstream_buffer_id_(0), |
| 64 available_pictures_(0) { | 64 available_pictures_(0) { |
| 65 DCHECK(factories_.get()); | 65 DCHECK(factories_.get()); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 DVLOG(1) << "GpuVideoDecoder reinitialization not supported."; | 142 DVLOG(1) << "GpuVideoDecoder reinitialization not supported."; |
| 143 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 143 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 144 return; | 144 return; |
| 145 } | 145 } |
| 146 | 146 |
| 147 if (!IsCodedSizeSupported(config.coded_size())) { | 147 if (!IsCodedSizeSupported(config.coded_size())) { |
| 148 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 148 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 149 return; | 149 return; |
| 150 } | 150 } |
| 151 | 151 |
| 152 vda_.reset(factories_->CreateVideoDecodeAccelerator(config.profile(), this)); | 152 vda_ = |
| 153 factories_->CreateVideoDecodeAccelerator(config.profile(), this).Pass(); |
| 153 if (!vda_) { | 154 if (!vda_) { |
| 154 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 155 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 155 return; | 156 return; |
| 156 } | 157 } |
| 157 | 158 |
| 158 config_ = config; | 159 config_ = config; |
| 159 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 160 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
| 160 | 161 |
| 161 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; | 162 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; |
| 162 status_cb.Run(PIPELINE_OK); | 163 status_cb.Run(PIPELINE_OK); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 pb.texture_mailbox(), | 408 pb.texture_mailbox(), |
| 408 0, // sync_point | 409 0, // sync_point |
| 409 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::ReusePictureBuffer, | 410 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::ReusePictureBuffer, |
| 410 weak_this_, | 411 weak_this_, |
| 411 picture.picture_buffer_id()))), | 412 picture.picture_buffer_id()))), |
| 412 decoder_texture_target_, | 413 decoder_texture_target_, |
| 413 pb.size(), | 414 pb.size(), |
| 414 visible_rect, | 415 visible_rect, |
| 415 natural_size, | 416 natural_size, |
| 416 timestamp, | 417 timestamp, |
| 417 base::Bind(&GpuVideoDecoderFactories::ReadPixels, | 418 base::Bind(&GpuVideoAcceleratorFactories::ReadPixels, |
| 418 factories_, | 419 factories_, |
| 419 pb.texture_id(), | 420 pb.texture_id(), |
| 420 decoder_texture_target_, | 421 decoder_texture_target_, |
| 421 gfx::Size(visible_rect.width(), visible_rect.height())), | 422 gfx::Size(visible_rect.width(), visible_rect.height())), |
| 422 base::Closure())); | 423 base::Closure())); |
| 423 CHECK_GT(available_pictures_, 0); | 424 CHECK_GT(available_pictures_, 0); |
| 424 --available_pictures_; | 425 --available_pictures_; |
| 425 bool inserted = | 426 bool inserted = |
| 426 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; | 427 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; |
| 427 DCHECK(inserted); | 428 DCHECK(inserted); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 | 576 |
| 576 state_ = kError; | 577 state_ = kError; |
| 577 | 578 |
| 578 if (!pending_read_cb_.is_null()) { | 579 if (!pending_read_cb_.is_null()) { |
| 579 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 580 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 580 return; | 581 return; |
| 581 } | 582 } |
| 582 } | 583 } |
| 583 | 584 |
| 584 } // namespace media | 585 } // namespace media |
| OLD | NEW |