feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
81
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/AsyncCB.h
vendored
Normal file
81
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/AsyncCB.h
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AsyncCallback [template]
|
||||
//
|
||||
// Description:
|
||||
// Helper class that routes IMFAsyncCallback::Invoke calls to a class
|
||||
// method on the parent class.
|
||||
//
|
||||
// Usage:
|
||||
// Add this class as a member variable. In the parent class constructor,
|
||||
// initialize the AsyncCallback class like this:
|
||||
// m_cb(this, &CYourClass::OnInvoke)
|
||||
// where
|
||||
// m_cb = AsyncCallback object
|
||||
// CYourClass = parent class
|
||||
// OnInvoke = Method in the parent class to receive Invoke calls.
|
||||
//
|
||||
// The parent's OnInvoke method (you can name it anything you like) must
|
||||
// have a signature that matches the InvokeFn typedef below.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// T: Type of the parent object
|
||||
template<class T>
|
||||
class AsyncCallback : public IMFAsyncCallback
|
||||
{
|
||||
public:
|
||||
typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
|
||||
|
||||
AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
|
||||
{
|
||||
}
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP_(ULONG) AddRef() {
|
||||
// Delegate to parent class.
|
||||
return m_pParent->AddRef();
|
||||
}
|
||||
STDMETHODIMP_(ULONG) Release() {
|
||||
// Delegate to parent class.
|
||||
return m_pParent->Release();
|
||||
}
|
||||
STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
|
||||
{
|
||||
if (!ppv)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
if (iid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this));
|
||||
}
|
||||
else if (iid == __uuidof(IMFAsyncCallback))
|
||||
{
|
||||
*ppv = static_cast<IMFAsyncCallback*>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
// IMFAsyncCallback methods
|
||||
STDMETHODIMP GetParameters(DWORD*, DWORD*)
|
||||
{
|
||||
// Implementation of this method is optional.
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
|
||||
{
|
||||
return (m_pParent->*m_pInvokeFn)(pAsyncResult);
|
||||
}
|
||||
|
||||
T *m_pParent;
|
||||
InvokeFn m_pInvokeFn;
|
||||
};
|
101
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/BufferLock.h
vendored
Normal file
101
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/BufferLock.h
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// VideoBufferLock
|
||||
//
|
||||
// Description:
|
||||
// Locks a video buffer that might or might not support IMF2DBuffer.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class VideoBufferLock
|
||||
{
|
||||
public:
|
||||
VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL)
|
||||
{
|
||||
m_pBuffer = pBuffer;
|
||||
m_pBuffer->AddRef();
|
||||
|
||||
// Query for the 2-D buffer interface. OK if this fails.
|
||||
m_pBuffer->QueryInterface(IID_PPV_ARGS(&m_p2DBuffer));
|
||||
}
|
||||
|
||||
~VideoBufferLock()
|
||||
{
|
||||
UnlockBuffer();
|
||||
SafeRelease(&m_pBuffer);
|
||||
SafeRelease(&m_p2DBuffer);
|
||||
}
|
||||
|
||||
// LockBuffer:
|
||||
// Locks the buffer. Returns a pointer to scan line 0 and returns the stride.
|
||||
|
||||
// The caller must provide the default stride as an input parameter, in case
|
||||
// the buffer does not expose IMF2DBuffer. You can calculate the default stride
|
||||
// from the media type.
|
||||
|
||||
HRESULT LockBuffer(
|
||||
LONG lDefaultStride, // Minimum stride (with no padding).
|
||||
DWORD dwHeightInPixels, // Height of the image, in pixels.
|
||||
BYTE **ppbScanLine0, // Receives a pointer to the start of scan line 0.
|
||||
LONG *plStride // Receives the actual stride.
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Use the 2-D version if available.
|
||||
if (m_p2DBuffer)
|
||||
{
|
||||
hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use non-2D version.
|
||||
BYTE *pData = NULL;
|
||||
|
||||
hr = m_pBuffer->Lock(&pData, NULL, NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*plStride = lDefaultStride;
|
||||
if (lDefaultStride < 0)
|
||||
{
|
||||
// Bottom-up orientation. Return a pointer to the start of the
|
||||
// last row *in memory* which is the top row of the image.
|
||||
*ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Top-down orientation. Return a pointer to the start of the
|
||||
// buffer.
|
||||
*ppbScanLine0 = pData;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT UnlockBuffer()
|
||||
{
|
||||
if (m_p2DBuffer)
|
||||
{
|
||||
return m_p2DBuffer->Unlock2D();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_pBuffer->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
IMFMediaBuffer *m_pBuffer;
|
||||
IMF2DBuffer *m_p2DBuffer;
|
||||
};
|
62
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/CritSec.h
vendored
Normal file
62
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/CritSec.h
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CritSec
|
||||
// Description: Wraps a critical section.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CritSec
|
||||
{
|
||||
public:
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
public:
|
||||
CritSec()
|
||||
{
|
||||
InitializeCriticalSectionEx(&m_criticalSection, 100, 0);
|
||||
}
|
||||
|
||||
~CritSec()
|
||||
{
|
||||
DeleteCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
_Acquires_lock_(m_criticalSection)
|
||||
void Lock()
|
||||
{
|
||||
EnterCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
_Releases_lock_(m_criticalSection)
|
||||
void Unlock()
|
||||
{
|
||||
LeaveCriticalSection(&m_criticalSection);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AutoLock
|
||||
// Description: Provides automatic locking and unlocking of a
|
||||
// of a critical section.
|
||||
//
|
||||
// Note: The AutoLock object must go out of scope before the CritSec.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AutoLock
|
||||
{
|
||||
private:
|
||||
CritSec *m_pCriticalSection;
|
||||
public:
|
||||
_Acquires_lock_(m_pCriticalSection)
|
||||
AutoLock(CritSec& crit)
|
||||
{
|
||||
m_pCriticalSection = &crit;
|
||||
m_pCriticalSection->Lock();
|
||||
}
|
||||
|
||||
_Releases_lock_(m_pCriticalSection)
|
||||
~AutoLock()
|
||||
{
|
||||
m_pCriticalSection->Unlock();
|
||||
}
|
||||
};
|
516
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/LinkList.h
vendored
Normal file
516
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/LinkList.h
vendored
Normal file
@ -0,0 +1,516 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: Linklist.h
|
||||
// Desc: Linked list class.
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
// Notes:
|
||||
//
|
||||
// The List class template implements a simple double-linked list.
|
||||
// It uses STL's copy semantics.
|
||||
|
||||
// There are two versions of the Clear() method:
|
||||
// Clear(void) clears the list w/out cleaning up the object.
|
||||
// Clear(FN fn) takes a functor object that releases the objects, if they need cleanup.
|
||||
|
||||
// The List class supports enumeration. Example of usage:
|
||||
//
|
||||
// List<T>::POSIITON pos = list.GetFrontPosition();
|
||||
// while (pos != list.GetEndPosition())
|
||||
// {
|
||||
// T item;
|
||||
// hr = list.GetItemPos(&item);
|
||||
// pos = list.Next(pos);
|
||||
// }
|
||||
|
||||
// The ComPtrList class template derives from List<> and implements a list of COM pointers.
|
||||
|
||||
template <class T>
|
||||
struct NoOp
|
||||
{
|
||||
void operator()(T& t)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class List
|
||||
{
|
||||
protected:
|
||||
|
||||
// Nodes in the linked list
|
||||
struct Node
|
||||
{
|
||||
Node *prev;
|
||||
Node *next;
|
||||
T item;
|
||||
|
||||
Node() : prev(nullptr), next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Node(T item) : prev(nullptr), next(nullptr)
|
||||
{
|
||||
this->item = item;
|
||||
}
|
||||
|
||||
T Item() const { return item; }
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// Object for enumerating the list.
|
||||
class POSITION
|
||||
{
|
||||
friend class List<T>;
|
||||
|
||||
public:
|
||||
POSITION() : pNode(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const POSITION &p) const
|
||||
{
|
||||
return pNode == p.pNode;
|
||||
}
|
||||
|
||||
bool operator!=(const POSITION &p) const
|
||||
{
|
||||
return pNode != p.pNode;
|
||||
}
|
||||
|
||||
private:
|
||||
const Node *pNode;
|
||||
|
||||
POSITION(Node *p) : pNode(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
Node m_anchor; // Anchor node for the linked list.
|
||||
DWORD m_count; // Number of items in the list.
|
||||
|
||||
Node* Front() const
|
||||
{
|
||||
return m_anchor.next;
|
||||
}
|
||||
|
||||
Node* Back() const
|
||||
{
|
||||
return m_anchor.prev;
|
||||
}
|
||||
|
||||
virtual HRESULT InsertAfter(T item, Node *pBefore)
|
||||
{
|
||||
if (pBefore == nullptr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
Node *pNode = new Node(item);
|
||||
if (pNode == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
Node *pAfter = pBefore->next;
|
||||
|
||||
pBefore->next = pNode;
|
||||
pAfter->prev = pNode;
|
||||
|
||||
pNode->prev = pBefore;
|
||||
pNode->next = pAfter;
|
||||
|
||||
m_count++;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT GetItem(const Node *pNode, T* ppItem)
|
||||
{
|
||||
if (pNode == nullptr || ppItem == nullptr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
*ppItem = pNode->item;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// RemoveItem:
|
||||
// Removes a node and optionally returns the item.
|
||||
// ppItem can be nullptr.
|
||||
virtual HRESULT RemoveItem(Node *pNode, T *ppItem)
|
||||
{
|
||||
if (pNode == nullptr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
assert(pNode != &m_anchor); // We should never try to remove the anchor node.
|
||||
if (pNode == &m_anchor)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
||||
T item;
|
||||
|
||||
// The next node's previous is this node's previous.
|
||||
pNode->next->prev = pNode->prev;
|
||||
|
||||
// The previous node's next is this node's next.
|
||||
pNode->prev->next = pNode->next;
|
||||
|
||||
item = pNode->item;
|
||||
delete pNode;
|
||||
|
||||
m_count--;
|
||||
|
||||
if (ppItem)
|
||||
{
|
||||
*ppItem = item;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
List()
|
||||
{
|
||||
m_anchor.next = &m_anchor;
|
||||
m_anchor.prev = &m_anchor;
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
virtual ~List()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
// Insertion functions
|
||||
HRESULT InsertBack(T item)
|
||||
{
|
||||
return InsertAfter(item, m_anchor.prev);
|
||||
}
|
||||
|
||||
|
||||
HRESULT InsertFront(T item)
|
||||
{
|
||||
return InsertAfter(item, &m_anchor);
|
||||
}
|
||||
|
||||
HRESULT InsertPos(POSITION pos, T item)
|
||||
{
|
||||
if (pos.pNode == nullptr)
|
||||
{
|
||||
return InsertBack(item);
|
||||
}
|
||||
|
||||
return InsertAfter(item, pos.pNode->prev);
|
||||
}
|
||||
|
||||
// RemoveBack: Removes the tail of the list and returns the value.
|
||||
// ppItem can be nullptr if you don't want the item back. (But the method does not release the item.)
|
||||
HRESULT RemoveBack(T *ppItem)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RemoveItem(Back(), ppItem);
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveFront: Removes the head of the list and returns the value.
|
||||
// ppItem can be nullptr if you don't want the item back. (But the method does not release the item.)
|
||||
HRESULT RemoveFront(T *ppItem)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RemoveItem(Front(), ppItem);
|
||||
}
|
||||
}
|
||||
|
||||
// GetBack: Gets the tail item.
|
||||
HRESULT GetBack(T *ppItem)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetItem(Back(), ppItem);
|
||||
}
|
||||
}
|
||||
|
||||
// GetFront: Gets the front item.
|
||||
HRESULT GetFront(T *ppItem)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetItem(Front(), ppItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// GetCount: Returns the number of items in the list.
|
||||
DWORD GetCount() const { return m_count; }
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return (GetCount() == 0);
|
||||
}
|
||||
|
||||
// Clear: Takes a functor object whose operator()
|
||||
// frees the object on the list.
|
||||
template <class FN>
|
||||
void Clear(FN& clear_fn)
|
||||
{
|
||||
Node *n = m_anchor.next;
|
||||
|
||||
// Delete the nodes
|
||||
while (n != &m_anchor)
|
||||
{
|
||||
clear_fn(n->item);
|
||||
|
||||
Node *tmp = n->next;
|
||||
delete n;
|
||||
n = tmp;
|
||||
}
|
||||
|
||||
// Reset the anchor to point at itself
|
||||
m_anchor.next = &m_anchor;
|
||||
m_anchor.prev = &m_anchor;
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
// Clear: Clears the list. (Does not delete or release the list items.)
|
||||
virtual void Clear()
|
||||
{
|
||||
NoOp<T> clearOp;
|
||||
Clear<>(clearOp);
|
||||
}
|
||||
|
||||
|
||||
// Enumerator functions
|
||||
|
||||
POSITION FrontPosition()
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return POSITION(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return POSITION(Front());
|
||||
}
|
||||
}
|
||||
|
||||
POSITION EndPosition() const
|
||||
{
|
||||
return POSITION();
|
||||
}
|
||||
|
||||
HRESULT GetItemPos(POSITION pos, T *ppItem)
|
||||
{
|
||||
if (pos.pNode)
|
||||
{
|
||||
return GetItem(pos.pNode, ppItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
POSITION Next(const POSITION pos)
|
||||
{
|
||||
if (pos.pNode && (pos.pNode->next != &m_anchor))
|
||||
{
|
||||
return POSITION(pos.pNode->next);
|
||||
}
|
||||
else
|
||||
{
|
||||
return POSITION(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove an item at a position.
|
||||
// The item is returns in ppItem, unless ppItem is nullptr.
|
||||
// NOTE: This method invalidates the POSITION object.
|
||||
HRESULT Remove(POSITION& pos, T *ppItem)
|
||||
{
|
||||
if (pos.pNode)
|
||||
{
|
||||
// Remove const-ness temporarily...
|
||||
Node *pNode = const_cast<Node*>(pos.pNode);
|
||||
|
||||
pos = POSITION();
|
||||
|
||||
return RemoveItem(pNode, ppItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Typical functors for Clear method.
|
||||
|
||||
// ComAutoRelease: Releases COM pointers.
|
||||
// MemDelete: Deletes pointers to new'd memory.
|
||||
|
||||
class ComAutoRelease
|
||||
{
|
||||
public:
|
||||
void operator()(IUnknown *p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
p->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class MemDelete
|
||||
{
|
||||
public:
|
||||
void operator()(void *p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ComPtrList class
|
||||
// Derived class that makes it safer to store COM pointers in the List<> class.
|
||||
// It automatically AddRef's the pointers that are inserted onto the list
|
||||
// (unless the insertion method fails).
|
||||
//
|
||||
// T must be a COM interface type.
|
||||
// example: ComPtrList<IUnknown>
|
||||
//
|
||||
// NULLABLE: If true, client can insert nullptr pointers. This means GetItem can
|
||||
// succeed but return a nullptr pointer. By default, the list does not allow nullptr
|
||||
// pointers.
|
||||
|
||||
template <class T, bool NULLABLE = FALSE>
|
||||
class ComPtrList : public List<T*>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T* Ptr;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
ComAutoRelease car;
|
||||
List<Ptr>::Clear(car);
|
||||
}
|
||||
|
||||
~ComPtrList()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
HRESULT InsertAfter(Ptr item, Node *pBefore)
|
||||
{
|
||||
// Do not allow nullptr item pointers unless NULLABLE is true.
|
||||
if (item == nullptr && !NULLABLE)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (item)
|
||||
{
|
||||
item->AddRef();
|
||||
}
|
||||
|
||||
HRESULT hr = List<Ptr>::InsertAfter(item, pBefore);
|
||||
if (FAILED(hr) && item != nullptr)
|
||||
{
|
||||
item->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT GetItem(const Node *pNode, Ptr* ppItem)
|
||||
{
|
||||
Ptr pItem = nullptr;
|
||||
|
||||
// The base class gives us the pointer without AddRef'ing it.
|
||||
// If we return the pointer to the caller, we must AddRef().
|
||||
HRESULT hr = List<Ptr>::GetItem(pNode, &pItem);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
assert(pItem || NULLABLE);
|
||||
if (pItem)
|
||||
{
|
||||
*ppItem = pItem;
|
||||
(*ppItem)->AddRef();
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT RemoveItem(Node *pNode, Ptr *ppItem)
|
||||
{
|
||||
// ppItem can be nullptr, but we need to get the
|
||||
// item so that we can release it.
|
||||
|
||||
// If ppItem is not nullptr, we will AddRef it on the way out.
|
||||
|
||||
Ptr pItem = nullptr;
|
||||
|
||||
HRESULT hr = List<Ptr>::RemoveItem(pNode, &pItem);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
assert(pItem || NULLABLE);
|
||||
if (ppItem && pItem)
|
||||
{
|
||||
*ppItem = pItem;
|
||||
(*ppItem)->AddRef();
|
||||
}
|
||||
|
||||
if (pItem)
|
||||
{
|
||||
pItem->Release();
|
||||
pItem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
};
|
222
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/OpQueue.h
vendored
Normal file
222
3rdparty/opencv-4.5.4/samples/winrt/ImageManipulations/MediaExtensions/Common/OpQueue.h
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OpQueue.h
|
||||
// Async operation queue.
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4355 ) // 'this' used in base member initializer list
|
||||
|
||||
/*
|
||||
This header file defines an object to help queue and serialize
|
||||
asynchronous operations.
|
||||
|
||||
Background:
|
||||
|
||||
To perform an operation asynchronously in Media Foundation, an object
|
||||
does one of the following:
|
||||
|
||||
1. Calls MFPutWorkItem(Ex), using either a standard work queue
|
||||
identifier or a caller-allocated work queue. The work-queue
|
||||
thread invokes the object's callback.
|
||||
|
||||
2. Creates an async result object (IMFAsyncResult) and calls
|
||||
MFInvokeCallback to invoke the object's callback.
|
||||
|
||||
Ultimately, either of these cause the object's callback to be invoked
|
||||
from a work-queue thread. The object can then complete the operation
|
||||
inside the callback.
|
||||
|
||||
However, the Media Foundation platform may dispatch async callbacks in
|
||||
parallel on several threads. Putting an item on a work queue does NOT
|
||||
guarantee that one operation will complete before the next one starts,
|
||||
or even that work items will be dispatched in the same order they were
|
||||
called.
|
||||
|
||||
To serialize async operations that should not overlap, an object should
|
||||
use a queue. While one operation is pending, subsequent operations are
|
||||
put on the queue, and only dispatched after the previous operation is
|
||||
complete.
|
||||
|
||||
The granularity of a single "operation" depends on the requirements of
|
||||
that particular object. A single operation might involve several
|
||||
asynchronous calls before the object dispatches the next operation on
|
||||
the queue.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// OpQueue class template
|
||||
//
|
||||
// Base class for an async operation queue.
|
||||
//
|
||||
// TOperation: The class used to describe operations. This class must
|
||||
// implement IUnknown.
|
||||
//
|
||||
// The OpQueue class is an abstract class. The derived class must
|
||||
// implement the following pure-virtual methods:
|
||||
//
|
||||
// - IUnknown methods (AddRef, Release, QI)
|
||||
//
|
||||
// - DispatchOperation:
|
||||
//
|
||||
// Performs the asynchronous operation specified by pOp.
|
||||
//
|
||||
// At the end of each operation, the derived class must call
|
||||
// ProcessQueue to process the next operation in the queue.
|
||||
//
|
||||
// NOTE: An operation is not required to complete inside the
|
||||
// DispatchOperation method. A single operation might consist
|
||||
// of several asynchronous method calls.
|
||||
//
|
||||
// - ValidateOperation:
|
||||
//
|
||||
// Checks whether the object can perform the operation specified
|
||||
// by pOp at this time.
|
||||
//
|
||||
// If the object cannot perform the operation now (e.g., because
|
||||
// another operation is still in progress) the method should
|
||||
// return MF_E_NOTACCEPTING.
|
||||
//
|
||||
//-------------------------------------------------------------------
|
||||
#include "linklist.h"
|
||||
#include "AsyncCB.h"
|
||||
|
||||
template <class T, class TOperation>
|
||||
class OpQueue //: public IUnknown
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ComPtrList<TOperation> OpList;
|
||||
|
||||
HRESULT QueueOperation(TOperation *pOp);
|
||||
|
||||
protected:
|
||||
|
||||
HRESULT ProcessQueue();
|
||||
HRESULT ProcessQueueAsync(IMFAsyncResult *pResult);
|
||||
|
||||
virtual HRESULT DispatchOperation(TOperation *pOp) = 0;
|
||||
virtual HRESULT ValidateOperation(TOperation *pOp) = 0;
|
||||
|
||||
OpQueue(CRITICAL_SECTION& critsec)
|
||||
: m_OnProcessQueue(static_cast<T *>(this), &OpQueue::ProcessQueueAsync),
|
||||
m_critsec(critsec)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~OpQueue()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
OpList m_OpQueue; // Queue of operations.
|
||||
CRITICAL_SECTION& m_critsec; // Protects the queue state.
|
||||
AsyncCallback<T> m_OnProcessQueue; // ProcessQueueAsync callback.
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Place an operation on the queue.
|
||||
// Public method.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T, class TOperation>
|
||||
HRESULT OpQueue<T, TOperation>::QueueOperation(TOperation *pOp)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
EnterCriticalSection(&m_critsec);
|
||||
|
||||
hr = m_OpQueue.InsertBack(pOp);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ProcessQueue();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_critsec);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Process the next operation on the queue.
|
||||
// Protected method.
|
||||
//
|
||||
// Note: This method dispatches the operation to a work queue.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T, class TOperation>
|
||||
HRESULT OpQueue<T, TOperation>::ProcessQueue()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (m_OpQueue.GetCount() > 0)
|
||||
{
|
||||
hr = MFPutWorkItem2(
|
||||
MFASYNC_CALLBACK_QUEUE_STANDARD, // Use the standard work queue.
|
||||
0, // Default priority
|
||||
&m_OnProcessQueue, // Callback method.
|
||||
nullptr // State object.
|
||||
);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Process the next operation on the queue.
|
||||
// Protected method.
|
||||
//
|
||||
// Note: This method is called from a work-queue thread.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T, class TOperation>
|
||||
HRESULT OpQueue<T, TOperation>::ProcessQueueAsync(IMFAsyncResult *pResult)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
TOperation *pOp = nullptr;
|
||||
|
||||
EnterCriticalSection(&m_critsec);
|
||||
|
||||
if (m_OpQueue.GetCount() > 0)
|
||||
{
|
||||
hr = m_OpQueue.GetFront(&pOp);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ValidateOperation(pOp);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = m_OpQueue.RemoveFront(nullptr);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
(void)DispatchOperation(pOp);
|
||||
}
|
||||
}
|
||||
|
||||
if (pOp != nullptr)
|
||||
{
|
||||
pOp->Release();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_critsec);
|
||||
return hr;
|
||||
}
|
||||
|
||||
#pragma warning( pop )
|
Reference in New Issue
Block a user