| 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" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 PipelineStatus status = success ? PIPELINE_OK : DECODER_ERROR_NOT_SUPPORTED; | 114 PipelineStatus status = success ? PIPELINE_OK : DECODER_ERROR_NOT_SUPPORTED; |
| 115 UMA_HISTOGRAM_ENUMERATION( | 115 UMA_HISTOGRAM_ENUMERATION( |
| 116 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); | 116 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); |
| 117 cb.Run(success); | 117 cb.Run(success); |
| 118 } | 118 } |
| 119 | 119 |
| 120 std::string GpuVideoDecoder::GetDisplayName() const { | 120 std::string GpuVideoDecoder::GetDisplayName() const { |
| 121 return kDecoderName; | 121 return kDecoderName; |
| 122 } | 122 } |
| 123 | 123 |
| 124 // TODO(xhwang): Support CDM setting using |set_cdm_ready_cb|. | |
| 125 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, | 124 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, |
| 126 bool /* low_delay */, | 125 bool /* low_delay */, |
| 127 const SetCdmReadyCB& /* set_cdm_ready_cb */, | 126 const SetCdmReadyCB& set_cdm_ready_cb, |
| 128 const InitCB& init_cb, | 127 const InitCB& init_cb, |
| 129 const OutputCB& output_cb) { | 128 const OutputCB& output_cb) { |
| 130 DVLOG(3) << "Initialize()"; | 129 DVLOG(3) << "Initialize()"; |
| 131 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 130 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 132 DCHECK(config.IsValidConfig()); | 131 DCHECK(config.IsValidConfig()); |
| 133 | 132 |
| 134 InitCB bound_init_cb = | 133 InitCB bound_init_cb = |
| 135 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, | 134 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, |
| 136 BindToCurrentLoop(init_cb)); | 135 BindToCurrentLoop(init_cb)); |
| 137 | 136 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 149 | 148 |
| 150 // TODO(posciak): destroy and create a new VDA on codec/profile change | 149 // TODO(posciak): destroy and create a new VDA on codec/profile change |
| 151 // (http://crbug.com/260224). | 150 // (http://crbug.com/260224). |
| 152 if (previously_initialized && (config_.profile() != config.profile())) { | 151 if (previously_initialized && (config_.profile() != config.profile())) { |
| 153 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; | 152 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; |
| 154 bound_init_cb.Run(false); | 153 bound_init_cb.Run(false); |
| 155 return; | 154 return; |
| 156 } | 155 } |
| 157 | 156 |
| 158 if (!IsProfileSupported(config.profile(), config.coded_size())) { | 157 if (!IsProfileSupported(config.profile(), config.coded_size())) { |
| 158 DVLOG(1) << "Profile " << config.profile() << " or coded size " |
| 159 << config.coded_size().ToString() << " not supported."; |
| 159 bound_init_cb.Run(false); | 160 bound_init_cb.Run(false); |
| 160 return; | 161 return; |
| 161 } | 162 } |
| 162 | 163 |
| 163 config_ = config; | 164 config_ = config; |
| 164 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 165 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
| 165 output_cb_ = BindToCurrentLoop(output_cb); | 166 output_cb_ = BindToCurrentLoop(output_cb); |
| 166 | 167 |
| 167 if (previously_initialized) { | 168 if (previously_initialized) { |
| 168 // Reinitialization with a different config (but same codec and profile). | 169 // Reinitialization with a different config (but same codec and profile). |
| 169 // VDA should handle it by detecting this in-stream by itself, | 170 // VDA should handle it by detecting this in-stream by itself, |
| 170 // no need to notify it. | 171 // no need to notify it. |
| 171 bound_init_cb.Run(true); | 172 bound_init_cb.Run(true); |
| 172 return; | 173 return; |
| 173 } | 174 } |
| 174 | 175 |
| 175 vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); | 176 vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); |
| 176 if (!vda_ || !vda_->Initialize(config.profile(), this)) { | 177 if (!vda_ || !vda_->Initialize(config.profile(), this)) { |
| 178 DVLOG(1) << "VDA initialization failed."; |
| 177 bound_init_cb.Run(false); | 179 bound_init_cb.Run(false); |
| 178 return; | 180 return; |
| 179 } | 181 } |
| 180 | 182 |
| 183 if (config.is_encrypted()) { |
| 184 init_cb_ = bound_init_cb; |
| 185 set_cdm_ready_cb_ = set_cdm_ready_cb; |
| 186 set_cdm_ready_cb_.Run(BindToCurrentLoop( |
| 187 base::Bind(&GpuVideoDecoder::SetCdm, weak_factory_.GetWeakPtr()))); |
| 188 return; |
| 189 } |
| 190 |
| 181 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; | 191 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; |
| 182 bound_init_cb.Run(true); | 192 bound_init_cb.Run(true); |
| 183 } | 193 } |
| 184 | 194 |
| 195 void GpuVideoDecoder::SetCdm(CdmContext* cdm_context, |
| 196 const CdmAttachedCB& cdm_attached_cb) { |
| 197 DVLOG(2) << __FUNCTION__; |
| 198 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 199 |
| 200 DCHECK(!init_cb_.is_null()); |
| 201 DCHECK(!set_cdm_ready_cb_.is_null()); |
| 202 set_cdm_ready_cb_.Reset(); |
| 203 |
| 204 if (!cdm_context || cdm_context->GetCdmId() == CdmContext::kInvalidCdmId) { |
| 205 DVLOG(1) << "CDM ID not available."; |
| 206 cdm_attached_cb.Run(false); |
| 207 base::ResetAndReturn(&init_cb_).Run(false); |
| 208 return; |
| 209 } |
| 210 |
| 211 cdm_attached_cb_ = cdm_attached_cb; |
| 212 vda_->SetCdm(cdm_context->GetCdmId()); |
| 213 } |
| 214 |
| 215 void GpuVideoDecoder::NotifyCdmAttached(bool success) { |
| 216 DVLOG_IF(2, !success) << __FUNCTION__ << ": CDM not attached."; |
| 217 DCHECK(!init_cb_.is_null()); |
| 218 DCHECK(!cdm_attached_cb_.is_null()); |
| 219 |
| 220 base::ResetAndReturn(&cdm_attached_cb_).Run(success); |
| 221 base::ResetAndReturn(&init_cb_).Run(success); |
| 222 } |
| 223 |
| 185 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { | 224 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { |
| 186 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 225 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 187 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); | 226 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); |
| 188 ++it) { | 227 ++it) { |
| 189 factories_->DeleteTexture(it->second.texture_id()); | 228 factories_->DeleteTexture(it->second.texture_id()); |
| 190 } | 229 } |
| 191 | 230 |
| 192 buffers->clear(); | 231 buffers->clear(); |
| 193 } | 232 } |
| 194 | 233 |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 } | 577 } |
| 539 | 578 |
| 540 GpuVideoDecoder::~GpuVideoDecoder() { | 579 GpuVideoDecoder::~GpuVideoDecoder() { |
| 541 DVLOG(3) << __FUNCTION__; | 580 DVLOG(3) << __FUNCTION__; |
| 542 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 581 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 543 | 582 |
| 544 if (vda_) | 583 if (vda_) |
| 545 DestroyVDA(); | 584 DestroyVDA(); |
| 546 DCHECK(assigned_picture_buffers_.empty()); | 585 DCHECK(assigned_picture_buffers_.empty()); |
| 547 | 586 |
| 587 if (!set_cdm_ready_cb_.is_null()) |
| 588 base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); |
| 589 if (!cdm_attached_cb_.is_null()) |
| 590 base::ResetAndReturn(&cdm_attached_cb_).Run(false); |
| 591 if (!init_cb_.is_null()) |
| 592 base::ResetAndReturn(&init_cb_).Run(false); |
| 593 |
| 548 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 594 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
| 549 delete available_shm_segments_[i]; | 595 delete available_shm_segments_[i]; |
| 550 } | 596 } |
| 551 available_shm_segments_.clear(); | 597 available_shm_segments_.clear(); |
| 552 | 598 |
| 553 for (std::map<int32, PendingDecoderBuffer>::iterator it = | 599 for (std::map<int32, PendingDecoderBuffer>::iterator it = |
| 554 bitstream_buffers_in_decoder_.begin(); | 600 bitstream_buffers_in_decoder_.begin(); |
| 555 it != bitstream_buffers_in_decoder_.end(); ++it) { | 601 it != bitstream_buffers_in_decoder_.end(); ++it) { |
| 556 delete it->second.shm_buffer; | 602 delete it->second.shm_buffer; |
| 557 it->second.done_cb.Run(kAborted); | 603 it->second.done_cb.Run(kAborted); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 } | 654 } |
| 609 return false; | 655 return false; |
| 610 } | 656 } |
| 611 | 657 |
| 612 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 658 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
| 613 const { | 659 const { |
| 614 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 660 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 615 } | 661 } |
| 616 | 662 |
| 617 } // namespace media | 663 } // namespace media |
| OLD | NEW |