// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once #include #include #include "VideoFrameToTensorConverter.h" #include "TensorToVideoFrameConverter.h" namespace _winml { // Forward Declare class ConverterResourceStore; struct ConverterResourceDescription { DWORD pixel_format; int width; int height; LUID luid; bool operator==(_In_ ConverterResourceDescription& desc) { // Converter resources DON'T match if // 1) the resources have different dimensions // 2) the resources are on different devices // 3) the resources have different pixel formats if (desc.width != width || desc.height != height || desc.luid.HighPart != luid.HighPart || desc.luid.LowPart != luid.LowPart || desc.pixel_format != pixel_format) { return false; } return true; } }; class ConverterResources : public std::enable_shared_from_this { using Pool = std::weak_ptr; public: template static std::shared_ptr Create(Pool pool, ConverterResourceDescription& descriptor) { return std::make_shared(pool, descriptor); } ConverterResources(Pool& pool, ConverterResourceDescription& descriptor); void ReturnToCache(); public: ConverterResourceDescription Descriptor; std::unique_ptr<_winml::VideoFrameToTensorConverter> Tensorizer; std::unique_ptr<_winml::TensorToVideoFrameConverter> Detensorizer; private: Pool m_pool; }; // This class retains tensorization and detensorization // resources in a store, and evicts the oldest resource object // when the size of the pool is maxed out. Objects in the pool // can be reused for caching purposes to enhance performance during // tensorization. class ConverterResourceStore : public std::enable_shared_from_this { struct PoolObject { std::shared_ptr Resource; uint64_t StoreId; }; public: template static std::shared_ptr Create(TArgs&&... args) { return std::make_shared(std::forward(args)...); } ConverterResourceStore(size_t nCacheSize); std::shared_ptr Fetch(ConverterResourceDescription& descriptor); void Store(std::shared_ptr object); private: std::shared_ptr FetchAndRemoveObject(ConverterResourceDescription& desc); void EvictOldestPoolObject(); private: std::vector m_objects; size_t m_cacheSize; std::mutex m_mutex; uint64_t storeId = 0; }; class PoolObjectWrapper { public: template static std::shared_ptr Create(TArgs&&... args) { return std::make_shared(std::forward(args)...); } explicit PoolObjectWrapper(std::shared_ptr&& resources) : m_resources(resources) {} ~PoolObjectWrapper() { if (m_resources) { m_resources->ReturnToCache(); } } std::shared_ptr Get() { return m_resources; } private: std::shared_ptr m_resources; }; } // namespace _winml