123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <dxgi1_2.h>
- #include "media/base/win/mf_helpers.h"
- #include "media/renderers/win/media_foundation_texture_pool.h"
- namespace {
- using Microsoft::WRL::ComPtr;
- // The Texture Count was determined empirically initially having a count of 30
- // and running many different video presentations in frame server mode and
- // recording the number of textures in use and the count never exceeded 3.
- // Therefore for a max of 3 in flight with the 3 being written requires that
- // we allocate 4 textures.
- constexpr int kTexturePoolCount = 4;
- } // namespace
- namespace media {
- MediaFoundationFrameInfo::MediaFoundationFrameInfo() = default;
- MediaFoundationFrameInfo::~MediaFoundationFrameInfo() = default;
- MediaFoundationFrameInfo::MediaFoundationFrameInfo(
- MediaFoundationFrameInfo&& other) = default;
- MediaFoundationTexturePool::TextureInfo::TextureInfo()
- : texture_in_use_(false) {}
- MediaFoundationTexturePool::TextureInfo::~TextureInfo() = default;
- MediaFoundationTexturePool::TextureInfo::TextureInfo(const TextureInfo& other) =
- default;
- MediaFoundationTexturePool::TextureInfo&
- MediaFoundationTexturePool::TextureInfo::operator=(
- const MediaFoundationTexturePool::TextureInfo& other) = default;
- MediaFoundationTexturePool::MediaFoundationTexturePool() = default;
- MediaFoundationTexturePool::~MediaFoundationTexturePool() = default;
- // TODO(crbug.com/1278157): The pool should release the textures when the media
- // engine is idling to save resources.
- HRESULT MediaFoundationTexturePool::Initialize(
- ID3D11Device* device,
- FramePoolInitializedCallback frame_pool_cb,
- const gfx::Size& frame_size) {
- D3D11_TEXTURE2D_DESC desc{
- static_cast<UINT>(frame_size.width()),
- static_cast<UINT>(frame_size.height()),
- 1,
- 1,
- // TODO(crbug.com/1276134): Need to handle higher bit-depths like HDR.
- DXGI_FORMAT_R8G8B8A8_UNORM,
- {1, 0},
- D3D11_USAGE_DEFAULT,
- D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
- 0,
- D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
- D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX};
- std::vector<MediaFoundationFrameInfo> frame_infos;
- bool callback_is_valid = !frame_pool_cb.is_null();
- if (callback_is_valid) {
- frame_infos.reserve(kTexturePoolCount);
- }
- // We can be reinitialized so remove all the previous textures from our
- // pool.
- texture_pool_.clear();
- for (int i = 0; i < kTexturePoolCount; ++i) {
- auto texture_info_element = std::make_unique<TextureInfo>();
- auto texture_token = base::UnguessableToken::Create();
- ComPtr<ID3D11Texture2D> d3d11_video_frame;
- RETURN_IF_FAILED(
- device->CreateTexture2D(&desc, nullptr, &d3d11_video_frame));
- SetDebugName(d3d11_video_frame.Get(), "Media_MFFrameServerMode_Pool");
- ComPtr<IDXGIResource1> d3d11_video_frame_resource;
- RETURN_IF_FAILED(d3d11_video_frame.As(&d3d11_video_frame_resource));
- HANDLE shared_texture_handle;
- RETURN_IF_FAILED(d3d11_video_frame_resource->CreateSharedHandle(
- nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
- nullptr, &shared_texture_handle));
- base::win::ScopedHandle scoped_shared_texture_handle;
- scoped_shared_texture_handle.Set(shared_texture_handle);
- shared_texture_handle = nullptr;
- texture_pool_[texture_token].texture_ = std::move(d3d11_video_frame);
- texture_pool_[texture_token].texture_in_use_ = false;
- if (callback_is_valid) {
- MediaFoundationFrameInfo frame_info;
- frame_info.dxgi_handle = std::move(scoped_shared_texture_handle);
- frame_info.token = texture_token;
- frame_infos.emplace_back(std::move(frame_info));
- }
- }
- if (callback_is_valid) {
- frame_pool_cb.Run(std::move(frame_infos), frame_size);
- }
- return S_OK;
- }
- ComPtr<ID3D11Texture2D> MediaFoundationTexturePool::AcquireTexture(
- base::UnguessableToken* texture_token) {
- for (auto& texture_item : texture_pool_) {
- if (!texture_item.second.texture_in_use_) {
- *texture_token = texture_item.first;
- texture_item.second.texture_in_use_ = true;
- return texture_item.second.texture_;
- }
- }
- return nullptr;
- }
- void MediaFoundationTexturePool::ReleaseTexture(
- const base::UnguessableToken& texture_token) {
- auto it = texture_pool_.find(texture_token);
- if (it != texture_pool_.end()) {
- it->second.texture_in_use_ = false;
- }
- }
- } // namespace media
|