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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 return; | 323 return; |
324 } | 324 } |
325 | 325 |
326 // If external surfaces are not supported we can complete initialization now. | 326 // If external surfaces are not supported we can complete initialization now. |
327 CompleteInitialization(SurfaceManager::kNoSurfaceID); | 327 CompleteInitialization(SurfaceManager::kNoSurfaceID); |
328 } | 328 } |
329 | 329 |
330 void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) { | 330 void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) { |
331 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 331 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
332 | 332 |
333 // It's possible for the vda to become null if NotifyError is called. | 333 if (!vda_) |
334 if (!vda_) { | 334 return; |
335 if (!init_cb_.is_null()) | 335 |
336 base::ResetAndReturn(&init_cb_).Run(false); | 336 // If the VDA has not been initialized, we were waiting for the first surface |
| 337 // so it can be passed to Initialize() via the config. We can't call |
| 338 // SetSurface() before initializing because there is no remote VDA to handle |
| 339 // the call yet. |
| 340 if (!vda_initialized_) { |
| 341 CompleteInitialization(surface_id); |
337 return; | 342 return; |
338 } | 343 } |
339 | 344 |
340 // If initialization has already completed, there's nothing to do but try to | 345 // The VDA must be already initialized (or async initialization is in |
341 // set the surface. If we're still initializing, we must pass the surface via | 346 // progress) so we can call SetSurface(). |
342 // the config since the remote VDA has not yet been created. | 347 vda_->SetSurface(surface_id); |
343 if (init_cb_.is_null()) { | |
344 vda_->SetSurface(surface_id); | |
345 return; | |
346 } | |
347 | |
348 // Otherwise initialization was waiting for the surface, so complete it now. | |
349 CompleteInitialization(surface_id); | |
350 } | 348 } |
351 | 349 |
352 void GpuVideoDecoder::CompleteInitialization(int surface_id) { | 350 void GpuVideoDecoder::CompleteInitialization(int surface_id) { |
353 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 351 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
354 DCHECK(vda_); | 352 DCHECK(vda_); |
355 DCHECK(!init_cb_.is_null()); | 353 DCHECK(!init_cb_.is_null()); |
| 354 DCHECK(!vda_initialized_); |
356 | 355 |
357 VideoDecodeAccelerator::Config vda_config; | 356 VideoDecodeAccelerator::Config vda_config; |
358 vda_config.profile = config_.profile(); | 357 vda_config.profile = config_.profile(); |
359 vda_config.cdm_id = cdm_id_; | 358 vda_config.cdm_id = cdm_id_; |
360 vda_config.surface_id = surface_id; | 359 vda_config.surface_id = surface_id; |
361 vda_config.encryption_scheme = config_.encryption_scheme(); | 360 vda_config.encryption_scheme = config_.encryption_scheme(); |
362 vda_config.is_deferred_initialization_allowed = true; | 361 vda_config.is_deferred_initialization_allowed = true; |
363 vda_config.initial_expected_coded_size = config_.coded_size(); | 362 vda_config.initial_expected_coded_size = config_.coded_size(); |
364 | 363 |
365 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) | 364 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
366 // We pass the SPS and PPS on Android because it lets us initialize | 365 // We pass the SPS and PPS on Android because it lets us initialize |
367 // MediaCodec more reliably (http://crbug.com/649185). | 366 // MediaCodec more reliably (http://crbug.com/649185). |
368 if (config_.codec() == kCodecH264) | 367 if (config_.codec() == kCodecH264) |
369 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); | 368 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); |
370 #endif | 369 #endif |
371 | 370 |
| 371 vda_initialized_ = true; |
372 if (!vda_->Initialize(vda_config, this)) { | 372 if (!vda_->Initialize(vda_config, this)) { |
373 DVLOG(1) << "VDA::Initialize failed."; | 373 DVLOG(1) << "VDA::Initialize failed."; |
| 374 // It's important to set |vda_| to null so that OnSurfaceAvailable() will |
| 375 // not call SetSurface() on a nonexistent remote VDA. |
| 376 DestroyVDA(); |
374 base::ResetAndReturn(&init_cb_).Run(false); | 377 base::ResetAndReturn(&init_cb_).Run(false); |
375 return; | 378 return; |
376 } | 379 } |
377 | 380 |
378 // If deferred initialization is not supported, initialization is complete. | 381 // If deferred initialization is not supported, initialization is complete. |
379 // Otherwise, a call to NotifyInitializationComplete will follow with the | 382 // Otherwise, a call to NotifyInitializationComplete will follow with the |
380 // result of deferred initialization. | 383 // result of deferred initialization. |
381 if (!supports_deferred_initialization_) | 384 if (!supports_deferred_initialization_) |
382 base::ResetAndReturn(&init_cb_).Run(true); | 385 base::ResetAndReturn(&init_cb_).Run(true); |
383 } | 386 } |
384 | 387 |
385 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { | 388 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { |
386 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; | 389 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; |
387 DCHECK(!init_cb_.is_null()); | |
388 | 390 |
389 base::ResetAndReturn(&init_cb_).Run(success); | 391 if (init_cb_) |
| 392 base::ResetAndReturn(&init_cb_).Run(success); |
390 } | 393 } |
391 | 394 |
392 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { | 395 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { |
393 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 396 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
394 for (const auto& kv : *buffers) { | 397 for (const auto& kv : *buffers) { |
395 for (uint32_t id : kv.second.client_texture_ids()) | 398 for (uint32_t id : kv.second.client_texture_ids()) |
396 factories_->DeleteTexture(id); | 399 factories_->DeleteTexture(id); |
397 } | 400 } |
398 | 401 |
399 buffers->clear(); | 402 buffers->clear(); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 | 857 |
855 if (!pending_reset_cb_.is_null()) | 858 if (!pending_reset_cb_.is_null()) |
856 base::ResetAndReturn(&pending_reset_cb_).Run(); | 859 base::ResetAndReturn(&pending_reset_cb_).Run(); |
857 } | 860 } |
858 | 861 |
859 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 862 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
860 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 863 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
861 if (!vda_) | 864 if (!vda_) |
862 return; | 865 return; |
863 | 866 |
| 867 if (init_cb_) |
| 868 base::ResetAndReturn(&init_cb_).Run(false); |
| 869 |
864 // If we have any bitstream buffers, then notify one that an error has | 870 // If we have any bitstream buffers, then notify one that an error has |
865 // occurred. This guarantees that somebody finds out about the error. If | 871 // occurred. This guarantees that somebody finds out about the error. If |
866 // we don't do this, and if the max decodes are already in flight, then there | 872 // we don't do this, and if the max decodes are already in flight, then there |
867 // won't be another decode request to report the error. | 873 // won't be another decode request to report the error. |
868 if (!bitstream_buffers_in_decoder_.empty()) { | 874 if (!bitstream_buffers_in_decoder_.empty()) { |
869 auto it = bitstream_buffers_in_decoder_.begin(); | 875 auto it = bitstream_buffers_in_decoder_.begin(); |
870 it->second.done_cb.Run(DecodeStatus::DECODE_ERROR); | 876 it->second.done_cb.Run(DecodeStatus::DECODE_ERROR); |
871 bitstream_buffers_in_decoder_.erase(it); | 877 bitstream_buffers_in_decoder_.erase(it); |
872 } | 878 } |
873 | 879 |
(...skipping 27 matching lines...) Expand all Loading... |
901 } | 907 } |
902 return false; | 908 return false; |
903 } | 909 } |
904 | 910 |
905 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 911 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
906 const { | 912 const { |
907 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 913 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
908 } | 914 } |
909 | 915 |
910 } // namespace media | 916 } // namespace media |
OLD | NEW |