123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543 |
- // 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 "media/renderers/win/media_foundation_texture_pool.h"
- #include "base/memory/raw_ptr.h"
- #include "base/test/mock_callback.h"
- #include "base/test/task_environment.h"
- #include "media/base/mock_filters.h"
- #include "media/base/test_helpers.h"
- #include "media/base/win/test_utils.h"
- #include <d3d11.h>
- #include <dxgi1_2.h>
- #include <wrl/client.h>
- using Microsoft::WRL::ComPtr;
- namespace media {
- class MockD3D11Texture2D;
- class MockD3D11Resource final : public IDXGIResource1 {
- public:
- MockD3D11Resource() {}
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
- void** ppvObject) override;
- ULONG STDMETHODCALLTYPE AddRef(void) override {
- return InterlockedIncrement(&refcount_);
- }
- ULONG STDMETHODCALLTYPE Release(void) override {
- ULONG refcount = InterlockedDecrement(&refcount_);
- if (refcount == 0) {
- refcount_ = 0xBAADF00D;
- delete this;
- }
- return refcount;
- }
- // IDXGIResource1
- HRESULT STDMETHODCALLTYPE
- CreateSubresourceSurface(UINT index, IDXGISurface2** ppSurface) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateSharedHandle(const SECURITY_ATTRIBUTES* pAttributes,
- DWORD dwAccess,
- LPCWSTR lpName,
- HANDLE* pHandle) override;
- // IDXGIResource
- HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE* pSharedHandle) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE GetUsage(DXGI_USAGE* pUsage) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- SetEvictionPriority(UINT eviction_priority) override;
- HRESULT STDMETHODCALLTYPE
- GetEvictionPriority(UINT* eviction_priority) override;
- // IDXGIDeviceSubObject
- HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void** ppDevice) override {
- return E_NOTIMPL;
- }
- // IDXGIObject
- HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void** ppParent) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid,
- UINT* pDataSize,
- void* pData) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid,
- UINT DataSize,
- const void* pData) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- SetPrivateDataInterface(REFGUID guid, const IUnknown* pData) override;
- private:
- raw_ptr<MockD3D11Texture2D> parent_;
- volatile ULONG refcount_ = 1;
- };
- class MockD3D11Texture2D final : public ID3D11Texture2D {
- private:
- MockD3D11Texture2D(const D3D11_TEXTURE2D_DESC* texture_description)
- : resource_(new MockD3D11Resource()) {
- memcpy(&texture_description_, texture_description,
- sizeof(D3D11_TEXTURE2D_DESC));
- }
- public:
- static HRESULT CreateInstance(const D3D11_TEXTURE2D_DESC* texture_description,
- ID3D11Texture2D** texture2D);
- // IUnknown
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
- void** ppvObject) override {
- if (ppvObject == nullptr) {
- return E_POINTER;
- }
- if (FAILED(QueryInterfaceInternal(riid, ppvObject))) {
- if (resource_ != nullptr)
- return resource_->QueryInterface(riid, ppvObject);
- else
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE QueryInterfaceInternal(REFIID riid,
- void** ppvObject) {
- if (ppvObject == nullptr) {
- return E_POINTER;
- }
- if (riid == IID_ID3D11Texture2D || riid == IID_IUnknown) {
- *ppvObject = static_cast<ID3D11Texture2D*>(this);
- } else if (riid == IID_ID3D11Resource) {
- *ppvObject = static_cast<ID3D11Resource*>(this);
- } else if (riid == IID_ID3D11DeviceChild) {
- *ppvObject = static_cast<ID3D11DeviceChild*>(this);
- } else {
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- ULONG STDMETHODCALLTYPE AddRef(void) override {
- return InterlockedIncrement(&refcount_);
- }
- ULONG STDMETHODCALLTYPE Release(void) override {
- ULONG refcount = InterlockedDecrement(&refcount_);
- if (refcount == 0) {
- refcount_ = 0xBAADF00D;
- delete this;
- }
- return refcount;
- }
- // ID3D11Texture2D
- void STDMETHODCALLTYPE GetDesc(D3D11_TEXTURE2D_DESC* description) override {
- memset(description, 0, sizeof(D3D11_TEXTURE2D_DESC));
- }
- // ID3D11Resource
- void STDMETHODCALLTYPE
- GetType(D3D11_RESOURCE_DIMENSION* resource_dimension) override {
- *resource_dimension =
- D3D11_RESOURCE_DIMENSION::D3D11_RESOURCE_DIMENSION_TEXTURE2D;
- }
- void STDMETHODCALLTYPE SetEvictionPriority(UINT eviction_priority) override {
- eviction_priority_ = eviction_priority;
- }
- UINT STDMETHODCALLTYPE GetEvictionPriority() override {
- return eviction_priority_;
- }
- // ID3D11DeviceChild
- void STDMETHODCALLTYPE GetDevice(ID3D11Device** ppDevice) override {
- device_.CopyTo(ppDevice);
- }
- HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid,
- UINT* pDataSize,
- void* pData) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid,
- UINT DataSize,
- const void* pData) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- SetPrivateDataInterface(REFGUID guid, const IUnknown* pData) override {
- // Our tests aren't checking for this right now
- return S_OK;
- }
- private:
- volatile ULONG refcount_ = 1;
- UINT eviction_priority_ = 0;
- D3D11_TEXTURE2D_DESC texture_description_;
- ComPtr<ID3D11Device> device_;
- ComPtr<IDXGIResource1> resource_;
- };
- class MockD3D11Device : public ID3D11Device {
- public:
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
- void** ppvObject) override {
- if (ppvObject == nullptr) {
- return E_POINTER;
- }
- if (riid == IID_ID3D11Device || riid == IID_IUnknown) {
- *ppvObject = this;
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- ULONG STDMETHODCALLTYPE AddRef(void) override { return 1; }
- ULONG STDMETHODCALLTYPE Release(void) override { return 1; }
- HRESULT STDMETHODCALLTYPE
- CreateBuffer(const D3D11_BUFFER_DESC* pDesc,
- const D3D11_SUBRESOURCE_DATA* pInitialData,
- ID3D11Buffer** ppBuffer) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateTexture1D(const D3D11_TEXTURE1D_DESC* pDesc,
- const D3D11_SUBRESOURCE_DATA* pInitialData,
- ID3D11Texture1D** ppTexture1D) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateTexture2D(const D3D11_TEXTURE2D_DESC* pDesc,
- const D3D11_SUBRESOURCE_DATA* pInitialData,
- ID3D11Texture2D** ppTexture2D) override;
- HRESULT STDMETHODCALLTYPE
- CreateTexture3D(const D3D11_TEXTURE3D_DESC* pDesc,
- const D3D11_SUBRESOURCE_DATA* pInitialData,
- ID3D11Texture3D** ppTexture3D) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateShaderResourceView(ID3D11Resource* pResource,
- const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc,
- ID3D11ShaderResourceView** ppSRView) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateUnorderedAccessView(ID3D11Resource* pResource,
- const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc,
- ID3D11UnorderedAccessView** ppUAView) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateRenderTargetView(ID3D11Resource* pResource,
- const D3D11_RENDER_TARGET_VIEW_DESC* pDesc,
- ID3D11RenderTargetView** ppRTView) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateDepthStencilView(ID3D11Resource* pResource,
- const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc,
- ID3D11DepthStencilView** ppDepthStencilView) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs,
- UINT NumElements,
- const void* pShaderBytecodeWithInputSignature,
- SIZE_T BytecodeLength,
- ID3D11InputLayout** ppInputLayout) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateVertexShader(const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11VertexShader** ppVertexShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateGeometryShader(const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11GeometryShader** ppGeometryShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput(
- const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- const D3D11_SO_DECLARATION_ENTRY* pSODeclaration,
- UINT NumEntries,
- const UINT* pBufferStrides,
- UINT NumStrides,
- UINT RasterizedStream,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11GeometryShader** ppGeometryShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreatePixelShader(const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11PixelShader** ppPixelShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateHullShader(const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11HullShader** ppHullShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateDomainShader(const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11DomainShader** ppDomainShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateComputeShader(const void* pShaderBytecode,
- SIZE_T BytecodeLength,
- ID3D11ClassLinkage* pClassLinkage,
- ID3D11ComputeShader** ppComputeShader) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateClassLinkage(ID3D11ClassLinkage** ppLinkage) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateBlendState(const D3D11_BLEND_DESC* pBlendStateDesc,
- ID3D11BlendState** ppBlendState) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE CreateDepthStencilState(
- const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc,
- ID3D11DepthStencilState** ppDepthStencilState) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateRasterizerState(const D3D11_RASTERIZER_DESC* pRasterizerDesc,
- ID3D11RasterizerState** ppRasterizerState) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateSamplerState(const D3D11_SAMPLER_DESC* pSamplerDesc,
- ID3D11SamplerState** ppSamplerState) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE CreateQuery(const D3D11_QUERY_DESC* pQueryDesc,
- ID3D11Query** ppQuery) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreatePredicate(const D3D11_QUERY_DESC* pPredicateDesc,
- ID3D11Predicate** ppPredicate) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateCounter(const D3D11_COUNTER_DESC* pCounterDesc,
- ID3D11Counter** ppCounter) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CreateDeferredContext(UINT ContextFlags,
- ID3D11DeviceContext** ppDeferredContext) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE OpenSharedResource(HANDLE hResource,
- REFIID ReturnedInterface,
- void** ppResource) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE CheckFormatSupport(DXGI_FORMAT Format,
- UINT* pFormatSupport) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CheckMultisampleQualityLevels(DXGI_FORMAT Format,
- UINT SampleCount,
- UINT* pNumQualityLevels) override {
- return E_NOTIMPL;
- }
- void STDMETHODCALLTYPE
- CheckCounterInfo(D3D11_COUNTER_INFO* pCounterInfo) override {}
- HRESULT STDMETHODCALLTYPE CheckCounter(const D3D11_COUNTER_DESC* pDesc,
- D3D11_COUNTER_TYPE* pType,
- UINT* pActiveCounters,
- LPSTR szName,
- UINT* pNameLength,
- LPSTR szUnits,
- UINT* pUnitsLength,
- LPSTR szDescription,
- UINT* pDescriptionLength) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- CheckFeatureSupport(D3D11_FEATURE Feature,
- void* pFeatureSupportData,
- UINT FeatureSupportDataSize) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid,
- UINT* pDataSize,
- void* pData) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid,
- UINT DataSize,
- const void* pData) override {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE
- SetPrivateDataInterface(REFGUID guid, const IUnknown* pData) override {
- return E_NOTIMPL;
- }
- D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel(void) override {
- return D3D_FEATURE_LEVEL_11_1;
- }
- UINT STDMETHODCALLTYPE GetCreationFlags(void) override { return 0; }
- HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason(void) override {
- return E_NOTIMPL;
- }
- void STDMETHODCALLTYPE
- GetImmediateContext(ID3D11DeviceContext** ppImmediateContext) override {}
- HRESULT STDMETHODCALLTYPE SetExceptionMode(UINT RaiseFlags) override {
- return E_NOTIMPL;
- }
- UINT STDMETHODCALLTYPE GetExceptionMode(void) override { return 0; }
- };
- // MockD3D11Resource
- HRESULT STDMETHODCALLTYPE MockD3D11Resource::QueryInterface(REFIID riid,
- void** ppvObject) {
- if (ppvObject == nullptr) {
- return E_POINTER;
- }
- if (riid == IID_IDXGIResource1) {
- *ppvObject = static_cast<IDXGIResource1*>(this);
- } else if (riid == IID_IDXGIResource) {
- *ppvObject = static_cast<IDXGIResource*>(this);
- } else if (riid == IID_IDXGIDeviceSubObject) {
- *ppvObject = static_cast<IDXGIDeviceSubObject*>(this);
- } else if (riid == IID_IDXGIObject) {
- *ppvObject = static_cast<IDXGIObject*>(this);
- } else if (parent_ != nullptr) {
- return parent_->QueryInterfaceInternal(riid, ppvObject);
- } else {
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE
- MockD3D11Resource::SetEvictionPriority(UINT eviction_priority) {
- parent_->SetEvictionPriority(eviction_priority);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE
- MockD3D11Resource::GetEvictionPriority(UINT* eviction_priority) {
- *eviction_priority = parent_->GetEvictionPriority();
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE
- MockD3D11Resource::SetPrivateDataInterface(REFGUID guid,
- const IUnknown* pData) {
- return parent_->SetPrivateDataInterface(guid, pData);
- }
- HRESULT STDMETHODCALLTYPE
- MockD3D11Resource::CreateSharedHandle(const SECURITY_ATTRIBUTES* pAttributes,
- DWORD dwAccess,
- LPCWSTR lpName,
- HANDLE* pHandle) {
- // Using an event to create a valid nt handle
- *pHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- if (*pHandle == nullptr) {
- return HRESULT_FROM_WIN32(GetLastError());
- }
- return S_OK;
- }
- HRESULT MockD3D11Texture2D::CreateInstance(
- const D3D11_TEXTURE2D_DESC* texture_description,
- ID3D11Texture2D** texture2D) {
- MockD3D11Texture2D* mock_texture =
- new MockD3D11Texture2D(texture_description);
- if (!mock_texture) {
- return E_OUTOFMEMORY;
- }
- *texture2D = mock_texture;
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE
- MockD3D11Device::CreateTexture2D(const D3D11_TEXTURE2D_DESC* pDesc,
- const D3D11_SUBRESOURCE_DATA* pInitialData,
- ID3D11Texture2D** ppTexture2D) {
- return MockD3D11Texture2D::CreateInstance(pDesc, ppTexture2D);
- }
- class MediaFoundationTexturePoolTest : public testing::Test {
- public:
- MediaFoundationTexturePoolTest() {}
- base::WeakPtrFactory<MediaFoundationTexturePoolTest> weak_factory_{this};
- };
- TEST_F(MediaFoundationTexturePoolTest, VerifyTextureInitialization) {
- MockD3D11Device mock_d3d_device;
- media::MediaFoundationTexturePool test;
- base::WaitableEvent wait_event;
- gfx::Size frame_size(1920, 1080);
- class SpecialCallback {
- private:
- raw_ptr<base::WaitableEvent> wait_event_;
- raw_ptr<gfx::Size> frame_size_;
- public:
- SpecialCallback(base::WaitableEvent* wait_event, gfx::Size* frame_size)
- : wait_event_(wait_event), frame_size_(frame_size) {}
- void Invoke(std::vector<media::MediaFoundationFrameInfo> frame_textures,
- const gfx::Size& texture_size) {
- EXPECT_EQ(texture_size.width(), frame_size_->width());
- EXPECT_EQ(texture_size.height(), frame_size_->height());
- wait_event_->Signal();
- }
- } callback(&wait_event, &frame_size);
- EXPECT_HRESULT_SUCCEEDED(
- test.Initialize(&mock_d3d_device,
- base::BindRepeating(&SpecialCallback::Invoke,
- base::Unretained(&callback)),
- frame_size));
- wait_event.Wait();
- }
- } // namespace media
|