diff options
Diffstat (limited to 'chromium/media/gpu/ipc/service/vda_video_decoder.cc')
-rw-r--r-- | chromium/media/gpu/ipc/service/vda_video_decoder.cc | 118 |
1 files changed, 91 insertions, 27 deletions
diff --git a/chromium/media/gpu/ipc/service/vda_video_decoder.cc b/chromium/media/gpu/ipc/service/vda_video_decoder.cc index ccf7b1fd7f6..73633231502 100644 --- a/chromium/media/gpu/ipc/service/vda_video_decoder.cc +++ b/chromium/media/gpu/ipc/service/vda_video_decoder.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -74,14 +74,19 @@ std::unique_ptr<VideoDecodeAccelerator> CreateAndInitializeVda( MediaLog* media_log, const VideoDecodeAccelerator::Config& config) { GpuVideoDecodeGLClient gl_client; - gl_client.get_context = base::BindRepeating( - &CommandBufferHelper::GetGLContext, command_buffer_helper); - gl_client.make_context_current = base::BindRepeating( - &CommandBufferHelper::MakeContextCurrent, command_buffer_helper); - gl_client.bind_image = base::BindRepeating(&BindImage, command_buffer_helper); - gl_client.is_passthrough = command_buffer_helper->IsPassthrough(); - gl_client.supports_arb_texture_rectangle = - command_buffer_helper->SupportsTextureRectangle(); + // |command_buffer_helper| is nullptr in IMPORT mode in which case, we + // shouldn't need to do any GL calls. + if (command_buffer_helper) { + gl_client.get_context = base::BindRepeating( + &CommandBufferHelper::GetGLContext, command_buffer_helper); + gl_client.make_context_current = base::BindRepeating( + &CommandBufferHelper::MakeContextCurrent, command_buffer_helper); + gl_client.bind_image = + base::BindRepeating(&BindImage, command_buffer_helper); + gl_client.is_passthrough = command_buffer_helper->IsPassthrough(); + gl_client.supports_arb_texture_rectangle = + command_buffer_helper->SupportsTextureRectangle(); + } std::unique_ptr<GpuVideoDecodeAcceleratorFactory> factory = GpuVideoDecodeAcceleratorFactory::Create(gl_client); @@ -119,17 +124,23 @@ std::unique_ptr<VideoDecoder> VdaVideoDecoder::Create( const gfx::ColorSpace& target_color_space, const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds, - GetStubCB get_stub_cb) { + GetStubCB get_stub_cb, + VideoDecodeAccelerator::Config::OutputMode output_mode) { auto* decoder = new VdaVideoDecoder( std::move(parent_task_runner), std::move(gpu_task_runner), std::move(media_log), target_color_space, - base::BindOnce(&PictureBufferManager::Create), - base::BindOnce(&CreateCommandBufferHelper, std::move(get_stub_cb)), + base::BindOnce(&PictureBufferManager::Create, + /*allocate_gpu_memory_buffers=*/output_mode == + VideoDecodeAccelerator::Config::OutputMode::IMPORT), + output_mode == VideoDecodeAccelerator::Config::OutputMode::ALLOCATE + ? base::BindOnce(&CreateCommandBufferHelper, std::move(get_stub_cb)) + : base::NullCallback(), base::BindRepeating(&CreateAndInitializeVda, gpu_preferences, gpu_workarounds), GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeCapabilities( GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities( - gpu_preferences, gpu_workarounds))); + gpu_preferences, gpu_workarounds)), + output_mode); return std::make_unique<AsyncDestroyVideoDecoder<VdaVideoDecoder>>( base::WrapUnique(decoder)); @@ -143,7 +154,8 @@ VdaVideoDecoder::VdaVideoDecoder( CreatePictureBufferManagerCB create_picture_buffer_manager_cb, CreateCommandBufferHelperCB create_command_buffer_helper_cb, CreateAndInitializeVdaCB create_and_initialize_vda_cb, - const VideoDecodeAccelerator::Capabilities& vda_capabilities) + const VideoDecodeAccelerator::Capabilities& vda_capabilities, + VideoDecodeAccelerator::Config::OutputMode output_mode) : parent_task_runner_(std::move(parent_task_runner)), gpu_task_runner_(std::move(gpu_task_runner)), media_log_(std::move(media_log)), @@ -152,6 +164,7 @@ VdaVideoDecoder::VdaVideoDecoder( std::move(create_command_buffer_helper_cb)), create_and_initialize_vda_cb_(std::move(create_and_initialize_vda_cb)), vda_capabilities_(vda_capabilities), + output_mode_(output_mode), timestamps_(128) { DVLOG(1) << __func__; DCHECK(parent_task_runner_->BelongsToCurrentThread()); @@ -262,7 +275,10 @@ void VdaVideoDecoder::Initialize(const VideoDecoderConfig& config, // TODO(sandersd): Change this to a capability if any VDA starts supporting // alpha channels. This is believed to be impossible right now because VPx // alpha channel data is passed in side data, which isn't sent to VDAs. - if (config.alpha_mode() != VideoDecoderConfig::AlphaMode::kIsOpaque) { + // HEVC is the codec that only has platform hardware decoder support, and + // macOS currently support HEVC with alpha, so don't block HEVC here. + if (config.alpha_mode() != VideoDecoderConfig::AlphaMode::kIsOpaque && + config.codec() != VideoCodec::kHEVC) { MEDIA_LOG(INFO, media_log_) << "Alpha formats are not supported"; EnterErrorState(); return; @@ -339,13 +355,16 @@ void VdaVideoDecoder::InitializeOnGpuThread() { // Set up |command_buffer_helper_|. if (!reinitializing_) { - command_buffer_helper_ = std::move(create_command_buffer_helper_cb_).Run(); - if (!command_buffer_helper_) { - parent_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&VdaVideoDecoder::InitializeDone, parent_weak_this_, - DecoderStatus::Codes::kFailed)); - return; + if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::ALLOCATE) { + command_buffer_helper_ = + std::move(create_command_buffer_helper_cb_).Run(); + if (!command_buffer_helper_) { + parent_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VdaVideoDecoder::InitializeDone, parent_weak_this_, + DecoderStatus::Codes::kFailed)); + return; + } } picture_buffer_manager_->Initialize(gpu_task_runner_, @@ -365,7 +384,7 @@ void VdaVideoDecoder::InitializeOnGpuThread() { vda_config.hdr_metadata = config_.hdr_metadata(); // vda_config.sps = [Only used by AVDA] // vda_config.pps = [Only used by AVDA] - // vda_config.output_mode = [Only used by ARC] + vda_config.output_mode = output_mode_; // vda_config.supported_output_formats = [Only used by PPAPI] // Create and initialize the VDA. @@ -505,6 +524,13 @@ int VdaVideoDecoder::GetMaxDecodeRequests() const { return 4; } +bool VdaVideoDecoder::FramesHoldExternalResources() const { + DVLOG(3) << __func__; + DCHECK(parent_task_runner_->BelongsToCurrentThread()); + + return output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT; +} + void VdaVideoDecoder::NotifyInitializationComplete(DecoderStatus status) { DVLOG(2) << __func__ << "(" << static_cast<int>(status.code()) << ")"; DCHECK(gpu_task_runner_->BelongsToCurrentThread()); @@ -531,6 +557,27 @@ void VdaVideoDecoder::ProvidePictureBuffers(uint32_t requested_num_of_buffers, textures_per_buffer, dimensions, texture_target)); } +void VdaVideoDecoder::ProvidePictureBuffersWithVisibleRect( + uint32_t requested_num_of_buffers, + VideoPixelFormat format, + uint32_t textures_per_buffer, + const gfx::Size& dimensions, + const gfx::Rect& visible_rect, + uint32_t texture_target) { + if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT) { + // In IMPORT mode, we (as the client of the underlying VDA) are responsible + // for buffer allocation with no textures (i.e., |texture_target| is + // irrelevant). Therefore, the logic in the base version of + // ProvidePictureBuffersWithVisibleRect() is not applicable. + ProvidePictureBuffers(requested_num_of_buffers, format, textures_per_buffer, + dimensions, texture_target); + return; + } + VideoDecodeAccelerator::Client::ProvidePictureBuffersWithVisibleRect( + requested_num_of_buffers, format, textures_per_buffer, dimensions, + visible_rect, texture_target); +} + void VdaVideoDecoder::ProvidePictureBuffersAsync(uint32_t count, VideoPixelFormat pixel_format, uint32_t planes, @@ -547,11 +594,14 @@ void VdaVideoDecoder::ProvidePictureBuffersAsync(uint32_t count, if (pixel_format == PIXEL_FORMAT_UNKNOWN) pixel_format = PIXEL_FORMAT_XRGB; - std::vector<PictureBuffer> picture_buffers = - picture_buffer_manager_->CreatePictureBuffers( + std::vector<std::pair<PictureBuffer, gfx::GpuMemoryBufferHandle>> + picture_buffers_and_gmbs = picture_buffer_manager_->CreatePictureBuffers( count, pixel_format, planes, texture_size, texture_target, - vda_->GetSharedImageTextureAllocationMode()); - if (picture_buffers.empty()) { + output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT + ? VideoDecodeAccelerator::TextureAllocationMode:: + kDoNotAllocateGLTextures + : vda_->GetSharedImageTextureAllocationMode()); + if (picture_buffers_and_gmbs.empty()) { parent_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VdaVideoDecoder::EnterErrorState, parent_weak_this_)); @@ -559,7 +609,19 @@ void VdaVideoDecoder::ProvidePictureBuffersAsync(uint32_t count, } DCHECK(gpu_weak_vda_); + std::vector<PictureBuffer> picture_buffers; + for (const auto& picture_buffer_and_gmb : picture_buffers_and_gmbs) { + picture_buffers.push_back(picture_buffer_and_gmb.first); + } vda_->AssignPictureBuffers(std::move(picture_buffers)); + + if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT) { + for (auto& picture_buffer_and_gmb : picture_buffers_and_gmbs) { + vda_->ImportBufferForPicture(picture_buffer_and_gmb.first.id(), + pixel_format, + std::move(picture_buffer_and_gmb.second)); + } + } } void VdaVideoDecoder::DismissPictureBuffer(int32_t picture_buffer_id) { @@ -771,10 +833,12 @@ void VdaVideoDecoder::NotifyError(VideoDecodeAccelerator::Error error) { } gpu::SharedImageStub* VdaVideoDecoder::GetSharedImageStub() const { + DCHECK_EQ(output_mode_, VideoDecodeAccelerator::Config::OutputMode::ALLOCATE); return command_buffer_helper_->GetSharedImageStub(); } CommandBufferHelper* VdaVideoDecoder::GetCommandBufferHelper() const { + DCHECK_EQ(output_mode_, VideoDecodeAccelerator::Config::OutputMode::ALLOCATE); return command_buffer_helper_.get(); } |