Chromium Code Reviews| 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 #include <array> | 8 #include <array> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "media/base/pipeline_status.h" | 29 #include "media/base/pipeline_status.h" |
| 30 #include "media/base/surface_manager.h" | 30 #include "media/base/surface_manager.h" |
| 31 #include "media/base/video_decoder_config.h" | 31 #include "media/base/video_decoder_config.h" |
| 32 #include "media/renderers/gpu_video_accelerator_factories.h" | 32 #include "media/renderers/gpu_video_accelerator_factories.h" |
| 33 #include "third_party/skia/include/core/SkBitmap.h" | 33 #include "third_party/skia/include/core/SkBitmap.h" |
| 34 | 34 |
| 35 #if defined(USE_PROPRIETARY_CODECS) | 35 #if defined(USE_PROPRIETARY_CODECS) |
| 36 #include "media/formats/mp4/box_definitions.h" | 36 #include "media/formats/mp4/box_definitions.h" |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 #if defined(OS_ANDROID) | |
| 40 #include "base/android/build_info.h" | |
| 41 #endif | |
| 42 | |
| 39 namespace media { | 43 namespace media { |
| 40 namespace { | 44 namespace { |
| 41 | 45 |
| 42 // Size of shared-memory segments we allocate. Since we reuse them we let them | 46 // Size of shared-memory segments we allocate. Since we reuse them we let them |
| 43 // be on the beefy side. | 47 // be on the beefy side. |
| 44 static const size_t kSharedMemorySegmentBytes = 100 << 10; | 48 static const size_t kSharedMemorySegmentBytes = 100 << 10; |
| 45 | 49 |
| 46 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) | 50 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
| 47 // Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed | 51 // Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed |
| 48 // with 0x0001, the Annex B framing bytes. The out parameters are not modified | 52 // with 0x0001, the Annex B framing bytes. The out parameters are not modified |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 const InitCB& init_cb, | 209 const InitCB& init_cb, |
| 206 const OutputCB& output_cb) { | 210 const OutputCB& output_cb) { |
| 207 DVLOG(3) << "Initialize()"; | 211 DVLOG(3) << "Initialize()"; |
| 208 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 212 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 209 DCHECK(config.IsValidConfig()); | 213 DCHECK(config.IsValidConfig()); |
| 210 | 214 |
| 211 InitCB bound_init_cb = | 215 InitCB bound_init_cb = |
| 212 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, | 216 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, |
| 213 BindToCurrentLoop(init_cb), media_log_); | 217 BindToCurrentLoop(init_cb), media_log_); |
| 214 | 218 |
| 219 bool requires_restart_for_external_output_surface = false; | |
| 215 #if !defined(OS_ANDROID) | 220 #if !defined(OS_ANDROID) |
| 216 if (config.is_encrypted()) { | 221 if (config.is_encrypted()) { |
| 217 DVLOG(1) << "Encrypted stream not supported."; | 222 DVLOG(1) << "Encrypted stream not supported."; |
| 218 bound_init_cb.Run(false); | 223 bound_init_cb.Run(false); |
| 219 return; | 224 return; |
| 220 } | 225 } |
| 226 #else | |
| 227 requires_restart_for_external_output_surface = | |
| 228 base::android::BuildInfo::GetInstance()->sdk_int() < 23; | |
| 221 #endif | 229 #endif |
| 222 | 230 |
| 223 bool previously_initialized = config_.IsValidConfig(); | 231 bool previously_initialized = config_.IsValidConfig(); |
| 224 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing") | 232 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing") |
| 225 << " GVD with config: " << config.AsHumanReadableString(); | 233 << " GVD with config: " << config.AsHumanReadableString(); |
| 226 | 234 |
| 227 // Disallow codec changes between configuration changes. | 235 // Disallow codec changes between configuration changes. |
| 228 if (previously_initialized && config_.codec() != config.codec()) { | 236 if (previously_initialized && config_.codec() != config.codec()) { |
| 229 DVLOG(1) << "Codec changed, cannot reinitialize."; | 237 DVLOG(1) << "Codec changed, cannot reinitialize."; |
| 230 bound_init_cb.Run(false); | 238 bound_init_cb.Run(false); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 | 310 |
| 303 init_cb_ = bound_init_cb; | 311 init_cb_ = bound_init_cb; |
| 304 | 312 |
| 305 const bool supports_external_output_surface = | 313 const bool supports_external_output_surface = |
| 306 (capabilities.flags & VideoDecodeAccelerator::Capabilities:: | 314 (capabilities.flags & VideoDecodeAccelerator::Capabilities:: |
| 307 SUPPORTS_EXTERNAL_OUTPUT_SURFACE) != 0; | 315 SUPPORTS_EXTERNAL_OUTPUT_SURFACE) != 0; |
| 308 if (supports_external_output_surface && !request_surface_cb_.is_null()) { | 316 if (supports_external_output_surface && !request_surface_cb_.is_null()) { |
| 309 // If we have a surface request callback we should call it and complete | 317 // If we have a surface request callback we should call it and complete |
| 310 // initialization with the returned surface. | 318 // initialization with the returned surface. |
| 311 request_surface_cb_.Run( | 319 request_surface_cb_.Run( |
| 320 requires_restart_for_external_output_surface, | |
| 312 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::CompleteInitialization, | 321 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::CompleteInitialization, |
| 313 weak_factory_.GetWeakPtr(), cdm_id))); | 322 weak_factory_.GetWeakPtr(), cdm_id))); |
| 314 return; | 323 return; |
| 315 } | 324 } |
| 316 | 325 |
| 317 // If we don't have to wait for a surface complete initialization with a null | 326 // If we don't have to wait for a surface complete initialization with a null |
| 318 // surface. | 327 // surface. |
| 319 CompleteInitialization(cdm_id, SurfaceManager::kNoSurfaceID); | 328 CompleteInitialization(cdm_id, SurfaceManager::kNoSurfaceID); |
| 320 } | 329 } |
| 321 | 330 |
| 322 void GpuVideoDecoder::CompleteInitialization(int cdm_id, int surface_id) { | 331 void GpuVideoDecoder::CompleteInitialization(int cdm_id, int surface_id) { |
| 323 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 332 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 324 DCHECK(!init_cb_.is_null()); | |
| 325 | 333 |
| 326 // It's possible for the vda to become null if NotifyError is called. | 334 // It's possible for the vda to become null if NotifyError is called. |
| 327 if (!vda_) { | 335 if (!vda_) { |
| 328 base::ResetAndReturn(&init_cb_).Run(false); | 336 base::ResetAndReturn(&init_cb_).Run(false); |
|
watk
2016/11/08 22:59:03
Need to check if init_cb_.is_null()
| |
| 329 return; | 337 return; |
| 330 } | 338 } |
| 331 | 339 |
| 340 vda_->SetSurface(surface_id); | |
| 341 | |
| 342 // If initialization has already completed, there's nothing left to do. | |
| 343 if (init_cb_.is_null()) | |
| 344 return; | |
|
watk
2016/11/08 22:59:03
Any chance you could rework this a bit to make it
DaleCurtis
2016/11/08 23:50:10
Hmm, without redesigning how we provide the surfac
watk
2016/11/08 23:58:12
Fair enough. I guess I was thinking we could have
DaleCurtis
2016/11/09 00:19:03
Ah, this is good, but required some reworking of |
| |
| 345 | |
| 332 VideoDecodeAccelerator::Config vda_config; | 346 VideoDecodeAccelerator::Config vda_config; |
| 333 vda_config.profile = config_.profile(); | 347 vda_config.profile = config_.profile(); |
| 334 vda_config.cdm_id = cdm_id; | 348 vda_config.cdm_id = cdm_id; |
| 335 vda_config.is_encrypted = config_.is_encrypted(); | 349 vda_config.is_encrypted = config_.is_encrypted(); |
| 336 vda_config.surface_id = surface_id; | |
| 337 vda_config.is_deferred_initialization_allowed = true; | 350 vda_config.is_deferred_initialization_allowed = true; |
| 338 vda_config.initial_expected_coded_size = config_.coded_size(); | 351 vda_config.initial_expected_coded_size = config_.coded_size(); |
| 339 | 352 |
| 340 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) | 353 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
| 341 // We pass the SPS and PPS on Android because it lets us initialize | 354 // We pass the SPS and PPS on Android because it lets us initialize |
| 342 // MediaCodec more reliably (http://crbug.com/649185). | 355 // MediaCodec more reliably (http://crbug.com/649185). |
| 343 if (config_.codec() == kCodecH264) | 356 if (config_.codec() == kCodecH264) |
| 344 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); | 357 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); |
| 345 #endif | 358 #endif |
| 346 | 359 |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 778 DVLOG(3) << __func__; | 791 DVLOG(3) << __func__; |
| 779 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 792 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 780 | 793 |
| 781 if (vda_) | 794 if (vda_) |
| 782 DestroyVDA(); | 795 DestroyVDA(); |
| 783 DCHECK(assigned_picture_buffers_.empty()); | 796 DCHECK(assigned_picture_buffers_.empty()); |
| 784 | 797 |
| 785 if (!init_cb_.is_null()) | 798 if (!init_cb_.is_null()) |
| 786 base::ResetAndReturn(&init_cb_).Run(false); | 799 base::ResetAndReturn(&init_cb_).Run(false); |
| 787 if (!request_surface_cb_.is_null()) | 800 if (!request_surface_cb_.is_null()) |
| 788 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); | 801 base::ResetAndReturn(&request_surface_cb_).Run(false, SurfaceCreatedCB()); |
| 789 | 802 |
| 790 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 803 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
| 791 delete available_shm_segments_[i]; | 804 delete available_shm_segments_[i]; |
| 792 } | 805 } |
| 793 available_shm_segments_.clear(); | 806 available_shm_segments_.clear(); |
| 794 | 807 |
| 795 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = | 808 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = |
| 796 bitstream_buffers_in_decoder_.begin(); | 809 bitstream_buffers_in_decoder_.begin(); |
| 797 it != bitstream_buffers_in_decoder_.end(); ++it) { | 810 it != bitstream_buffers_in_decoder_.end(); ++it) { |
| 798 delete it->second.shm_buffer; | 811 delete it->second.shm_buffer; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 } | 883 } |
| 871 return false; | 884 return false; |
| 872 } | 885 } |
| 873 | 886 |
| 874 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 887 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
| 875 const { | 888 const { |
| 876 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 889 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 877 } | 890 } |
| 878 | 891 |
| 879 } // namespace media | 892 } // namespace media |
| OLD | NEW |