Update
This commit is contained in:
261
apps/LoopThroughWithOpenGLCompositing/OpenGLComposite.h
Normal file
261
apps/LoopThroughWithOpenGLCompositing/OpenGLComposite.h
Normal file
@@ -0,0 +1,261 @@
|
||||
/* -LICENSE-START-
|
||||
** Copyright (c) 2012 Blackmagic Design
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person or organization
|
||||
** obtaining a copy of the software and accompanying documentation (the
|
||||
** "Software") to use, reproduce, display, distribute, sub-license, execute,
|
||||
** and transmit the Software, and to prepare derivative works of the Software,
|
||||
** and to permit third-parties to whom the Software is furnished to do so, in
|
||||
** accordance with:
|
||||
**
|
||||
** (1) if the Software is obtained from Blackmagic Design, the End User License
|
||||
** Agreement for the Software Development Kit ("EULA") available at
|
||||
** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or
|
||||
**
|
||||
** (2) if the Software is obtained from any third party, such licensing terms
|
||||
** as notified by that third party,
|
||||
**
|
||||
** and all subject to the following:
|
||||
**
|
||||
** (3) the copyright notices in the Software and this entire statement,
|
||||
** including the above license grant, this restriction and the following
|
||||
** disclaimer, must be included in all copies of the Software, in whole or in
|
||||
** part, and all derivative works of the Software, unless such copies or
|
||||
** derivative works are solely in the form of machine-executable object code
|
||||
** generated by a source language processor.
|
||||
**
|
||||
** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
** DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
** A copy of the Software is available free of charge at
|
||||
** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA.
|
||||
**
|
||||
** -LICENSE-END-
|
||||
*/
|
||||
|
||||
#ifndef __OPENGL_COMPOSITE_H__
|
||||
#define __OPENGL_COMPOSITE_H__
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <tchar.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
|
||||
#include <objbase.h>
|
||||
#include <atlbase.h>
|
||||
#include <comutil.h>
|
||||
#include "DeckLinkAPI_h.h"
|
||||
|
||||
#include "VideoFrameTransfer.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
class PlayoutDelegate;
|
||||
class CaptureDelegate;
|
||||
class PinnedMemoryAllocator;
|
||||
|
||||
|
||||
class OpenGLComposite
|
||||
{
|
||||
public:
|
||||
OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC);
|
||||
~OpenGLComposite();
|
||||
|
||||
bool InitDeckLink();
|
||||
bool Start();
|
||||
bool Stop();
|
||||
|
||||
void resizeGL(WORD width, WORD height);
|
||||
void paintGL();
|
||||
|
||||
void VideoFrameArrived(IDeckLinkVideoInputFrame* inputFrame, bool hasNoInputSource);
|
||||
void PlayoutFrameCompleted(IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result);
|
||||
|
||||
private:
|
||||
void resizeWindow(int width, int height);
|
||||
bool CheckOpenGLExtensions();
|
||||
|
||||
CaptureDelegate* mCaptureDelegate;
|
||||
PlayoutDelegate* mPlayoutDelegate;
|
||||
HWND hGLWnd;
|
||||
HDC hGLDC;
|
||||
HGLRC hGLRC;
|
||||
CRITICAL_SECTION pMutex;
|
||||
|
||||
// DeckLink
|
||||
IDeckLinkInput* mDLInput;
|
||||
IDeckLinkOutput* mDLOutput;
|
||||
std::deque<IDeckLinkMutableVideoFrame*> mDLOutputVideoFrameQueue;
|
||||
PinnedMemoryAllocator* mPlayoutAllocator;
|
||||
BMDTimeValue mFrameDuration;
|
||||
BMDTimeScale mFrameTimescale;
|
||||
unsigned mTotalPlayoutFrames;
|
||||
unsigned mFrameWidth;
|
||||
unsigned mFrameHeight;
|
||||
bool mHasNoInputSource;
|
||||
|
||||
// OpenGL data
|
||||
bool mFastTransferExtensionAvailable;
|
||||
GLuint mCaptureTexture;
|
||||
GLuint mFBOTexture;
|
||||
GLuint mUnpinnedTextureBuffer;
|
||||
GLuint mIdFrameBuf;
|
||||
GLuint mIdColorBuf;
|
||||
GLuint mIdDepthBuf;
|
||||
GLuint mProgram;
|
||||
GLuint mFragmentShader;
|
||||
GLfloat mRotateAngle;
|
||||
GLfloat mRotateAngleRate;
|
||||
int mViewWidth;
|
||||
int mViewHeight;
|
||||
|
||||
bool InitOpenGLState();
|
||||
bool compileFragmentShader(int errorMessageSize, char* errorMessage);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// PinnedMemoryAllocator
|
||||
////////////////////////////////////////////
|
||||
class PinnedMemoryAllocator : public IDeckLinkVideoBufferAllocator
|
||||
{
|
||||
public:
|
||||
PinnedMemoryAllocator(HDC hdc, HGLRC hglrc, VideoFrameTransfer::Direction direction, unsigned cacheSize, unsigned bufferSize);
|
||||
virtual ~PinnedMemoryAllocator();
|
||||
|
||||
bool transferFrame(void* address, GLuint gpuTexture);
|
||||
void waitForTransferComplete(void* address);
|
||||
unsigned bufferSize() { return mBufferSize; }
|
||||
|
||||
// IUnknown methods
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) override;
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef(void) override;
|
||||
virtual ULONG STDMETHODCALLTYPE Release(void) override;
|
||||
|
||||
// IDeckLinkVideoBufferAllocator methods
|
||||
virtual HRESULT STDMETHODCALLTYPE AllocateVideoBuffer (IDeckLinkVideoBuffer** allocatedBuffer) override;
|
||||
|
||||
private:
|
||||
|
||||
void unPinAddress(void* address);
|
||||
|
||||
private:
|
||||
HDC mHGLDC;
|
||||
HGLRC mHGLRC;
|
||||
std::atomic<ULONG> mRefCount;
|
||||
VideoFrameTransfer::Direction mDirection;
|
||||
std::map<void*, VideoFrameTransfer*> mFrameTransfer;
|
||||
unsigned mBufferSize;
|
||||
std::vector<void*> mFrameCache;
|
||||
unsigned mFrameCacheSize;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// InputAllocatorPool
|
||||
////////////////////////////////////////////
|
||||
|
||||
class InputAllocatorPool : public IDeckLinkVideoBufferAllocatorProvider
|
||||
{
|
||||
public:
|
||||
InputAllocatorPool(HDC hdc, HGLRC hglrc);
|
||||
|
||||
// IUnknown interface
|
||||
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||
ULONG STDMETHODCALLTYPE Release() override;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppv) override;
|
||||
|
||||
// IDeckLinkVideoBufferAllocatorProvider interface
|
||||
HRESULT STDMETHODCALLTYPE GetVideoBufferAllocator(
|
||||
/* [in] */ unsigned int bufferSize,
|
||||
/* [in] */ unsigned int width,
|
||||
/* [in] */ unsigned int height,
|
||||
/* [in] */ unsigned int rowBytes,
|
||||
/* [in] */ BMDPixelFormat pixelFormat,
|
||||
/* [out] */ IDeckLinkVideoBufferAllocator **allocator) override;
|
||||
|
||||
private:
|
||||
std::atomic<ULONG> mRefCount;
|
||||
std::map<unsigned int, CComPtr<PinnedMemoryAllocator> > mAllocatorBySize;
|
||||
HDC mHDC;
|
||||
HGLRC mHGLRC;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// DeckLinkVideoBuffer
|
||||
////////////////////////////////////////////
|
||||
class DeckLinkVideoBuffer : public IDeckLinkVideoBuffer
|
||||
{
|
||||
public:
|
||||
explicit DeckLinkVideoBuffer(std::shared_ptr<void>& buffer, PinnedMemoryAllocator* parent);
|
||||
virtual ~DeckLinkVideoBuffer() = default;
|
||||
|
||||
// IUnknown interface
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override;
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef(void) override;
|
||||
virtual ULONG STDMETHODCALLTYPE Release(void) override;
|
||||
|
||||
// IDeckLinkVideoBuffer interface
|
||||
virtual HRESULT STDMETHODCALLTYPE GetBytes(void** buffer) override;
|
||||
virtual HRESULT STDMETHODCALLTYPE GetSize(uint64_t* size) override;
|
||||
virtual HRESULT STDMETHODCALLTYPE StartAccess(BMDBufferAccessFlags flags) override;
|
||||
virtual HRESULT STDMETHODCALLTYPE EndAccess(BMDBufferAccessFlags flags) override;
|
||||
|
||||
private:
|
||||
CComPtr<PinnedMemoryAllocator> mParentAllocator; // Dual-purpose: allocator owns mem this points to, and to access transferFrame() via a QueryInterface
|
||||
std::atomic<ULONG> mRefCount;
|
||||
std::shared_ptr<void> mBuffer;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Capture Delegate Class
|
||||
////////////////////////////////////////////
|
||||
|
||||
class CaptureDelegate : public IDeckLinkInputCallback
|
||||
{
|
||||
OpenGLComposite* m_pOwner;
|
||||
LONG mRefCount;
|
||||
|
||||
public:
|
||||
CaptureDelegate (OpenGLComposite* pOwner);
|
||||
|
||||
// IUnknown needs only a dummy implementation
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID iid, LPVOID *ppv);
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef ();
|
||||
virtual ULONG STDMETHODCALLTYPE Release ();
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived (IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioPacket);
|
||||
virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged (BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode *newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Render Delegate Class
|
||||
////////////////////////////////////////////
|
||||
|
||||
class PlayoutDelegate : public IDeckLinkVideoOutputCallback
|
||||
{
|
||||
OpenGLComposite* m_pOwner;
|
||||
LONG mRefCount;
|
||||
|
||||
public:
|
||||
PlayoutDelegate (OpenGLComposite* pOwner);
|
||||
|
||||
// IUnknown needs only a dummy implementation
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID iid, LPVOID *ppv);
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef ();
|
||||
virtual ULONG STDMETHODCALLTYPE Release ();
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted (IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result);
|
||||
virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped ();
|
||||
};
|
||||
|
||||
#endif // __OPENGL_COMPOSITE_H__
|
||||
Reference in New Issue
Block a user