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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 | 114 |
115 GpuVideoDecoder::BufferData::~BufferData() {} | 115 GpuVideoDecoder::BufferData::~BufferData() {} |
116 | 116 |
117 GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories, | 117 GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories, |
118 const RequestSurfaceCB& request_surface_cb, | 118 const RequestSurfaceCB& request_surface_cb, |
119 scoped_refptr<MediaLog> media_log) | 119 scoped_refptr<MediaLog> media_log) |
120 : needs_bitstream_conversion_(false), | 120 : needs_bitstream_conversion_(false), |
121 factories_(factories), | 121 factories_(factories), |
122 request_surface_cb_(request_surface_cb), | 122 request_surface_cb_(request_surface_cb), |
123 media_log_(media_log), | 123 media_log_(media_log), |
| 124 vda_initialized_(false), |
124 state_(kNormal), | 125 state_(kNormal), |
125 decoder_texture_target_(0), | 126 decoder_texture_target_(0), |
126 pixel_format_(PIXEL_FORMAT_UNKNOWN), | 127 pixel_format_(PIXEL_FORMAT_UNKNOWN), |
127 next_picture_buffer_id_(0), | 128 next_picture_buffer_id_(0), |
128 next_bitstream_buffer_id_(0), | 129 next_bitstream_buffer_id_(0), |
129 available_pictures_(0), | 130 available_pictures_(0), |
130 needs_all_picture_buffers_to_decode_(false), | 131 needs_all_picture_buffers_to_decode_(false), |
131 supports_deferred_initialization_(false), | 132 supports_deferred_initialization_(false), |
132 requires_texture_copy_(false), | 133 requires_texture_copy_(false), |
133 cdm_id_(CdmContext::kInvalidCdmId), | 134 cdm_id_(CdmContext::kInvalidCdmId), |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 requires_restart_for_external_output_surface, | 321 requires_restart_for_external_output_surface, |
321 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::OnSurfaceAvailable, | 322 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::OnSurfaceAvailable, |
322 weak_factory_.GetWeakPtr()))); | 323 weak_factory_.GetWeakPtr()))); |
323 return; | 324 return; |
324 } | 325 } |
325 | 326 |
326 // If external surfaces are not supported we can complete initialization now. | 327 // If external surfaces are not supported we can complete initialization now. |
327 CompleteInitialization(SurfaceManager::kNoSurfaceID); | 328 CompleteInitialization(SurfaceManager::kNoSurfaceID); |
328 } | 329 } |
329 | 330 |
| 331 // OnSurfaceAvailable() might be called at any time between Initialize() and |
| 332 // ~GpuVideoDecoder() so we have to be careful to not make assumptions about |
| 333 // the current state. |
330 void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) { | 334 void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) { |
331 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 335 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
332 | 336 |
333 // It's possible for the vda to become null if NotifyError is called. | 337 if (!vda_) |
334 if (!vda_) { | 338 return; |
335 if (!init_cb_.is_null()) | 339 |
336 base::ResetAndReturn(&init_cb_).Run(false); | 340 // If the VDA has not been initialized, we were waiting for the first surface |
| 341 // so it can be passed to Initialize() via the config. We can't call |
| 342 // SetSurface() before initializing because there is no remote VDA to handle |
| 343 // the call yet. |
| 344 if (!vda_initialized_) { |
| 345 CompleteInitialization(surface_id); |
337 return; | 346 return; |
338 } | 347 } |
339 | 348 |
340 // If initialization has already completed, there's nothing to do but try to | 349 // 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 | 350 // progress) so we can call SetSurface(). |
342 // the config since the remote VDA has not yet been created. | 351 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 } | 352 } |
351 | 353 |
352 void GpuVideoDecoder::CompleteInitialization(int surface_id) { | 354 void GpuVideoDecoder::CompleteInitialization(int surface_id) { |
353 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 355 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
354 DCHECK(vda_); | 356 DCHECK(vda_); |
355 DCHECK(!init_cb_.is_null()); | 357 DCHECK(!init_cb_.is_null()); |
| 358 DCHECK(!vda_initialized_); |
356 | 359 |
357 VideoDecodeAccelerator::Config vda_config; | 360 VideoDecodeAccelerator::Config vda_config; |
358 vda_config.profile = config_.profile(); | 361 vda_config.profile = config_.profile(); |
359 vda_config.cdm_id = cdm_id_; | 362 vda_config.cdm_id = cdm_id_; |
360 vda_config.surface_id = surface_id; | 363 vda_config.surface_id = surface_id; |
361 vda_config.encryption_scheme = config_.encryption_scheme(); | 364 vda_config.encryption_scheme = config_.encryption_scheme(); |
362 vda_config.is_deferred_initialization_allowed = true; | 365 vda_config.is_deferred_initialization_allowed = true; |
363 vda_config.initial_expected_coded_size = config_.coded_size(); | 366 vda_config.initial_expected_coded_size = config_.coded_size(); |
364 | 367 |
365 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) | 368 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
366 // We pass the SPS and PPS on Android because it lets us initialize | 369 // We pass the SPS and PPS on Android because it lets us initialize |
367 // MediaCodec more reliably (http://crbug.com/649185). | 370 // MediaCodec more reliably (http://crbug.com/649185). |
368 if (config_.codec() == kCodecH264) | 371 if (config_.codec() == kCodecH264) |
369 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); | 372 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); |
370 #endif | 373 #endif |
371 | 374 |
| 375 vda_initialized_ = true; |
372 if (!vda_->Initialize(vda_config, this)) { | 376 if (!vda_->Initialize(vda_config, this)) { |
373 DVLOG(1) << "VDA::Initialize failed."; | 377 DVLOG(1) << "VDA::Initialize failed."; |
| 378 // It's important to set |vda_| to null so that OnSurfaceAvailable() will |
| 379 // not call SetSurface() on a nonexistent remote VDA. |
| 380 DestroyVDA(); |
374 base::ResetAndReturn(&init_cb_).Run(false); | 381 base::ResetAndReturn(&init_cb_).Run(false); |
375 return; | 382 return; |
376 } | 383 } |
377 | 384 |
378 // If deferred initialization is not supported, initialization is complete. | 385 // If deferred initialization is not supported, initialization is complete. |
379 // Otherwise, a call to NotifyInitializationComplete will follow with the | 386 // Otherwise, a call to NotifyInitializationComplete will follow with the |
380 // result of deferred initialization. | 387 // result of deferred initialization. |
381 if (!supports_deferred_initialization_) | 388 if (!supports_deferred_initialization_) |
382 base::ResetAndReturn(&init_cb_).Run(true); | 389 base::ResetAndReturn(&init_cb_).Run(true); |
383 } | 390 } |
384 | 391 |
385 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { | 392 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { |
386 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; | 393 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; |
387 DCHECK(!init_cb_.is_null()); | |
388 | 394 |
389 base::ResetAndReturn(&init_cb_).Run(success); | 395 if (init_cb_) |
| 396 base::ResetAndReturn(&init_cb_).Run(success); |
390 } | 397 } |
391 | 398 |
392 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { | 399 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { |
393 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 400 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
394 for (const auto& kv : *buffers) { | 401 for (const auto& kv : *buffers) { |
395 for (uint32_t id : kv.second.client_texture_ids()) | 402 for (uint32_t id : kv.second.client_texture_ids()) |
396 factories_->DeleteTexture(id); | 403 factories_->DeleteTexture(id); |
397 } | 404 } |
398 | 405 |
399 buffers->clear(); | 406 buffers->clear(); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 | 861 |
855 if (!pending_reset_cb_.is_null()) | 862 if (!pending_reset_cb_.is_null()) |
856 base::ResetAndReturn(&pending_reset_cb_).Run(); | 863 base::ResetAndReturn(&pending_reset_cb_).Run(); |
857 } | 864 } |
858 | 865 |
859 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 866 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
860 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 867 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
861 if (!vda_) | 868 if (!vda_) |
862 return; | 869 return; |
863 | 870 |
| 871 if (init_cb_) |
| 872 base::ResetAndReturn(&init_cb_).Run(false); |
| 873 |
864 // If we have any bitstream buffers, then notify one that an error has | 874 // 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 | 875 // 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 | 876 // 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. | 877 // won't be another decode request to report the error. |
868 if (!bitstream_buffers_in_decoder_.empty()) { | 878 if (!bitstream_buffers_in_decoder_.empty()) { |
869 auto it = bitstream_buffers_in_decoder_.begin(); | 879 auto it = bitstream_buffers_in_decoder_.begin(); |
870 it->second.done_cb.Run(DecodeStatus::DECODE_ERROR); | 880 it->second.done_cb.Run(DecodeStatus::DECODE_ERROR); |
871 bitstream_buffers_in_decoder_.erase(it); | 881 bitstream_buffers_in_decoder_.erase(it); |
872 } | 882 } |
873 | 883 |
(...skipping 27 matching lines...) Expand all Loading... |
901 } | 911 } |
902 return false; | 912 return false; |
903 } | 913 } |
904 | 914 |
905 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 915 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
906 const { | 916 const { |
907 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 917 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
908 } | 918 } |
909 | 919 |
910 } // namespace media | 920 } // namespace media |
OLD | NEW |