| 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 | 
|---|