| Index: media/filters/gpu_video_decoder.cc
|
| diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc
|
| index f5ef4b805ea6d4c00f5462a0565ac9f768bbcce6..02faf30378f0276713455bd1fa41fa796c783878 100644
|
| --- a/media/filters/gpu_video_decoder.cc
|
| +++ b/media/filters/gpu_video_decoder.cc
|
| @@ -21,6 +21,7 @@
|
| #include "media/base/decoder_buffer.h"
|
| #include "media/base/media_switches.h"
|
| #include "media/base/pipeline.h"
|
| +#include "media/base/surface_manager.h"
|
| #include "media/base/video_decoder_config.h"
|
| #include "media/renderers/gpu_video_accelerator_factories.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| @@ -64,10 +65,12 @@ GpuVideoDecoder::BufferData::BufferData(int32_t bbid,
|
|
|
| GpuVideoDecoder::BufferData::~BufferData() {}
|
|
|
| -GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories)
|
| +GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories,
|
| + const RequestSurfaceCB& request_surface_cb)
|
| : needs_bitstream_conversion_(false),
|
| factories_(factories),
|
| state_(kNormal),
|
| + request_surface_cb_(request_surface_cb),
|
| decoder_texture_target_(0),
|
| next_picture_buffer_id_(0),
|
| next_bitstream_buffer_id_(0),
|
| @@ -148,8 +151,8 @@ void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
|
| #endif
|
|
|
| bool previously_initialized = config_.IsValidConfig();
|
| - DVLOG(1) << "(Re)initializing GVD with config: "
|
| - << config.AsHumanReadableString();
|
| + DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing")
|
| + << "GVD with config: " << config.AsHumanReadableString();
|
|
|
| // TODO(posciak): destroy and create a new VDA on codec/profile change
|
| // (http://crbug.com/260224).
|
| @@ -187,25 +190,55 @@ void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
|
| }
|
|
|
| vda_ = factories_->CreateVideoDecodeAccelerator();
|
| -
|
| - VideoDecodeAccelerator::Config vda_config(config);
|
| -
|
| - if (!vda_ || !vda_->Initialize(vda_config, this)) {
|
| - DVLOG(1) << "VDA initialization failed.";
|
| + if (!vda_) {
|
| + DVLOG(1) << "Failed to create a VDA.";
|
| bound_init_cb.Run(false);
|
| return;
|
| }
|
|
|
| + // CompleteInitialization will clear both of these callbacks.
|
| + init_cb_ = bound_init_cb;
|
| if (config.is_encrypted()) {
|
| - init_cb_ = bound_init_cb;
|
| set_cdm_ready_cb_ = set_cdm_ready_cb;
|
| + }
|
| +
|
| + const bool supports_external_output_surface =
|
| + capabilities.flags &
|
| + VideoDecodeAccelerator::Capabilities::SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
|
| + if (supports_external_output_surface && !request_surface_cb_.is_null()) {
|
| + // If we have surface request callback we should call it and complete
|
| + // initialization with the returned surface.
|
| + request_surface_cb_.Run(BindToCurrentLoop(base::Bind(
|
| + &GpuVideoDecoder::CompleteInitialization, weak_factory_.GetWeakPtr())));
|
| + return;
|
| + }
|
| +
|
| + // Complete initialization with a null surface.
|
| + CompleteInitialization(SurfaceManager::kNoSurfaceID);
|
| +}
|
| +
|
| +void GpuVideoDecoder::CompleteInitialization(int surface_id) {
|
| + DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
|
| + DCHECK(!init_cb_.is_null());
|
| +
|
| + VideoDecodeAccelerator::Config vda_config(config_);
|
| + vda_config.surface_id = surface_id;
|
| + if (!vda_->Initialize(vda_config, this)) {
|
| + DVLOG(1) << "VDA::Initialize failed.";
|
| + set_cdm_ready_cb_.Reset();
|
| + base::ResetAndReturn(&init_cb_).Run(false);
|
| + return;
|
| + }
|
| +
|
| + // The VDA is now initialized, but If the stream is encrypted we need to
|
| + // request and attach the CDM before completing GVD's initialization.
|
| + if (config_.is_encrypted()) {
|
| set_cdm_ready_cb_.Run(BindToCurrentLoop(
|
| base::Bind(&GpuVideoDecoder::SetCdm, weak_factory_.GetWeakPtr())));
|
| return;
|
| }
|
|
|
| - DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded.";
|
| - bound_init_cb.Run(true);
|
| + base::ResetAndReturn(&init_cb_).Run(true);
|
| }
|
|
|
| void GpuVideoDecoder::SetCdm(CdmContext* cdm_context,
|
| @@ -612,6 +645,8 @@ GpuVideoDecoder::~GpuVideoDecoder() {
|
| base::ResetAndReturn(&cdm_attached_cb_).Run(false);
|
| if (!init_cb_.is_null())
|
| base::ResetAndReturn(&init_cb_).Run(false);
|
| + if (!request_surface_cb_.is_null())
|
| + base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB());
|
|
|
| for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
|
| delete available_shm_segments_[i];
|
|
|