| Index: media/filters/gpu_video_decoder.cc
|
| diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc
|
| index 723c6da03b6bb0becb79a26ce75f7d64c9be2aae..5366b831f1b911e54a91a59a418fa002a51891c5 100644
|
| --- a/media/filters/gpu_video_decoder.cc
|
| +++ b/media/filters/gpu_video_decoder.cc
|
| @@ -330,29 +330,28 @@ void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
|
| void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) {
|
| DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
|
|
|
| - // It's possible for the vda to become null if NotifyError is called.
|
| - if (!vda_) {
|
| - if (!init_cb_.is_null())
|
| - base::ResetAndReturn(&init_cb_).Run(false);
|
| + if (!vda_)
|
| return;
|
| - }
|
|
|
| - // If initialization has already completed, there's nothing to do but try to
|
| - // set the surface. If we're still initializing, we must pass the surface via
|
| - // the config since the remote VDA has not yet been created.
|
| - if (init_cb_.is_null()) {
|
| - vda_->SetSurface(surface_id);
|
| + // If the VDA has not been initialized, we were waiting for the first surface
|
| + // so it can be passed to Initialize() via the config. We can't call
|
| + // SetSurface() before initializing because there is no remote VDA to handle
|
| + // the call yet.
|
| + if (!vda_initialized_) {
|
| + CompleteInitialization(surface_id);
|
| return;
|
| }
|
|
|
| - // Otherwise initialization was waiting for the surface, so complete it now.
|
| - CompleteInitialization(surface_id);
|
| + // The VDA must be already initialized (or async initialization is in
|
| + // progress) so we can call SetSurface().
|
| + vda_->SetSurface(surface_id);
|
| }
|
|
|
| void GpuVideoDecoder::CompleteInitialization(int surface_id) {
|
| DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
|
| DCHECK(vda_);
|
| DCHECK(!init_cb_.is_null());
|
| + DCHECK(!vda_initialized_);
|
|
|
| VideoDecodeAccelerator::Config vda_config;
|
| vda_config.profile = config_.profile();
|
| @@ -369,8 +368,12 @@ void GpuVideoDecoder::CompleteInitialization(int surface_id) {
|
| ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps);
|
| #endif
|
|
|
| + vda_initialized_ = true;
|
| if (!vda_->Initialize(vda_config, this)) {
|
| DVLOG(1) << "VDA::Initialize failed.";
|
| + // It's important to set |vda_| to null so that OnSurfaceAvailable() will
|
| + // not call SetSurface() on a nonexistent remote VDA.
|
| + DestroyVDA();
|
| base::ResetAndReturn(&init_cb_).Run(false);
|
| return;
|
| }
|
| @@ -384,9 +387,9 @@ void GpuVideoDecoder::CompleteInitialization(int surface_id) {
|
|
|
| void GpuVideoDecoder::NotifyInitializationComplete(bool success) {
|
| DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed.";
|
| - DCHECK(!init_cb_.is_null());
|
|
|
| - base::ResetAndReturn(&init_cb_).Run(success);
|
| + if (init_cb_)
|
| + base::ResetAndReturn(&init_cb_).Run(success);
|
| }
|
|
|
| void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) {
|
| @@ -861,6 +864,9 @@ void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
|
| if (!vda_)
|
| return;
|
|
|
| + if (init_cb_)
|
| + base::ResetAndReturn(&init_cb_).Run(false);
|
| +
|
| // If we have any bitstream buffers, then notify one that an error has
|
| // occurred. This guarantees that somebody finds out about the error. If
|
| // we don't do this, and if the max decodes are already in flight, then there
|
|
|