Input optional
This commit is contained in:
@@ -252,6 +252,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
wglMakeCurrent( NULL, NULL );
|
wglMakeCurrent( NULL, NULL );
|
||||||
if (pOpenGLComposite->Start())
|
if (pOpenGLComposite->Start())
|
||||||
break; // success
|
break; // success
|
||||||
|
MessageBoxA(NULL, "The OpenGL/DeckLink runtime initialized, but playout failed to start. See the previous DeckLink start message for the failing call.", "Startup failed", MB_OK | MB_ICONERROR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "The OpenGL/DeckLink runtime failed to initialize. See the previous initialization message for the failing call.", "Startup failed", MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failed to initialize - cleanup
|
// Failed to initialize - cleanup
|
||||||
|
|||||||
@@ -466,6 +466,7 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
BMDDisplayMode outputDisplayMode = bmdModeHD1080p5994;
|
BMDDisplayMode outputDisplayMode = bmdModeHD1080p5994;
|
||||||
std::string inputDisplayModeName = "1080p59.94";
|
std::string inputDisplayModeName = "1080p59.94";
|
||||||
std::string outputDisplayModeName = "1080p59.94";
|
std::string outputDisplayModeName = "1080p59.94";
|
||||||
|
std::string initFailureReason;
|
||||||
int outputFrameRowBytes;
|
int outputFrameRowBytes;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
||||||
@@ -550,8 +551,8 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a full duplex device as capture and playback, or half-duplex device
|
// Preserve the original input-then-output selection for half-duplex cards.
|
||||||
// as capture or playback.
|
// Input is optional later, but choosing output first can pick the wrong card.
|
||||||
bool inputUsed = false;
|
bool inputUsed = false;
|
||||||
if (!mDLInput && pDL->QueryInterface(IID_IDeckLinkInput, (void**)&mDLInput) == S_OK)
|
if (!mDLInput && pDL->QueryInterface(IID_IDeckLinkInput, (void**)&mDLInput) == S_OK)
|
||||||
inputUsed = true;
|
inputUsed = true;
|
||||||
@@ -575,26 +576,29 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! mDLOutput || ! mDLInput)
|
if (!mDLOutput)
|
||||||
{
|
{
|
||||||
MessageBox(NULL, _T("Expected both Input and Output DeckLink devices"), _T("This application requires two DeckLink devices."), MB_OK);
|
MessageBox(NULL, _T("Expected an Output DeckLink device"), _T("This application requires a DeckLink output device."), MB_OK);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDLInput->GetDisplayModeIterator(&pDLInputDisplayModeIterator) != S_OK)
|
if (mDLInput && mDLInput->GetDisplayModeIterator(&pDLInputDisplayModeIterator) != S_OK)
|
||||||
{
|
{
|
||||||
MessageBox(NULL, _T("Cannot get input Display Mode Iterator."), _T("DeckLink error."), MB_OK);
|
MessageBox(NULL, _T("Cannot get input Display Mode Iterator."), _T("DeckLink error."), MB_OK);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FindDeckLinkDisplayMode(pDLInputDisplayModeIterator, inputDisplayMode, &pDLInputDisplayMode))
|
if (mDLInput && !FindDeckLinkDisplayMode(pDLInputDisplayModeIterator, inputDisplayMode, &pDLInputDisplayMode))
|
||||||
{
|
{
|
||||||
const std::string error = "Cannot get specified input BMDDisplayMode for configured mode: " + inputDisplayModeName;
|
const std::string error = "Cannot get specified input BMDDisplayMode for configured mode: " + inputDisplayModeName;
|
||||||
MessageBoxA(NULL, error.c_str(), "DeckLink input error.", MB_OK);
|
MessageBoxA(NULL, error.c_str(), "DeckLink input error.", MB_OK);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (pDLInputDisplayModeIterator)
|
||||||
|
{
|
||||||
pDLInputDisplayModeIterator->Release();
|
pDLInputDisplayModeIterator->Release();
|
||||||
pDLInputDisplayModeIterator = NULL;
|
pDLInputDisplayModeIterator = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDLOutput->GetDisplayModeIterator(&pDLOutputDisplayModeIterator) != S_OK)
|
if (mDLOutput->GetDisplayModeIterator(&pDLOutputDisplayModeIterator) != S_OK)
|
||||||
{
|
{
|
||||||
@@ -611,13 +615,18 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
pDLOutputDisplayModeIterator->Release();
|
pDLOutputDisplayModeIterator->Release();
|
||||||
pDLOutputDisplayModeIterator = NULL;
|
pDLOutputDisplayModeIterator = NULL;
|
||||||
|
|
||||||
mInputFrameWidth = pDLInputDisplayMode->GetWidth();
|
|
||||||
mInputFrameHeight = pDLInputDisplayMode->GetHeight();
|
|
||||||
mOutputFrameWidth = pDLOutputDisplayMode->GetWidth();
|
mOutputFrameWidth = pDLOutputDisplayMode->GetWidth();
|
||||||
mOutputFrameHeight = pDLOutputDisplayMode->GetHeight();
|
mOutputFrameHeight = pDLOutputDisplayMode->GetHeight();
|
||||||
|
mInputFrameWidth = pDLInputDisplayMode ? pDLInputDisplayMode->GetWidth() : mOutputFrameWidth;
|
||||||
|
mInputFrameHeight = pDLInputDisplayMode ? pDLInputDisplayMode->GetHeight() : mOutputFrameHeight;
|
||||||
|
if (!mDLInput)
|
||||||
|
mInputDisplayModeName = "No input - black frame";
|
||||||
|
|
||||||
if (! CheckOpenGLExtensions())
|
if (! CheckOpenGLExtensions())
|
||||||
|
{
|
||||||
|
initFailureReason = "OpenGL extension checks failed.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
if (mInputFrameWidth != mOutputFrameWidth || mInputFrameHeight != mOutputFrameHeight)
|
if (mInputFrameWidth != mOutputFrameWidth || mInputFrameHeight != mOutputFrameHeight)
|
||||||
{
|
{
|
||||||
mFastTransferExtensionAvailable = false;
|
mFastTransferExtensionAvailable = false;
|
||||||
@@ -625,7 +634,10 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! InitOpenGLState())
|
if (! InitOpenGLState())
|
||||||
|
{
|
||||||
|
initFailureReason = "OpenGL state initialization failed.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (mRuntimeHost)
|
if (mRuntimeHost)
|
||||||
{
|
{
|
||||||
@@ -660,26 +672,51 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDLInput)
|
||||||
{
|
{
|
||||||
// Use custom allocators so we pin only once then recycle them
|
// Use custom allocators so we pin only once then recycle them
|
||||||
CComPtr<IDeckLinkVideoBufferAllocatorProvider> captureAllocator(new (std::nothrow) InputAllocatorPool(hGLDC, hGLRC));
|
CComPtr<IDeckLinkVideoBufferAllocatorProvider> captureAllocator(new (std::nothrow) InputAllocatorPool(hGLDC, hGLRC));
|
||||||
|
|
||||||
if (mDLInput->EnableVideoInputWithAllocatorProvider(inputDisplayMode, bmdFormat8BitYUV, bmdVideoInputFlagDefault, captureAllocator) != S_OK)
|
if (mDLInput->EnableVideoInputWithAllocatorProvider(inputDisplayMode, bmdFormat8BitYUV, bmdVideoInputFlagDefault, captureAllocator) != S_OK)
|
||||||
goto error;
|
{
|
||||||
|
OutputDebugStringA("DeckLink input could not be enabled; continuing in output-only black-frame mode.\n");
|
||||||
|
mDLInput->Release();
|
||||||
|
mDLInput = NULL;
|
||||||
|
mHasNoInputSource = true;
|
||||||
|
mInputDisplayModeName = "No input - black frame";
|
||||||
|
if (mRuntimeHost)
|
||||||
|
mRuntimeHost->SetSignalStatus(false, mInputFrameWidth, mInputFrameHeight, mInputDisplayModeName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDLInput)
|
||||||
|
{
|
||||||
mCaptureDelegate = new CaptureDelegate(this);
|
mCaptureDelegate = new CaptureDelegate(this);
|
||||||
if (mDLInput->SetCallback(mCaptureDelegate) != S_OK)
|
if (mDLInput->SetCallback(mCaptureDelegate) != S_OK)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink input setup failed while installing the capture callback.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mRuntimeHost)
|
||||||
|
{
|
||||||
|
mRuntimeHost->SetSignalStatus(false, mInputFrameWidth, mInputFrameHeight, mInputDisplayModeName);
|
||||||
|
}
|
||||||
|
|
||||||
if (mDLOutput->RowBytesForPixelFormat(bmdFormat8BitBGRA, mOutputFrameWidth, &outputFrameRowBytes) != S_OK)
|
if (mDLOutput->RowBytesForPixelFormat(bmdFormat8BitBGRA, mOutputFrameWidth, &outputFrameRowBytes) != S_OK)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink output setup failed while calculating BGRA row bytes.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
// Use a custom allocator so we pin only once then recycle them
|
// Use a custom allocator so we pin only once then recycle them
|
||||||
mPlayoutAllocator = new PinnedMemoryAllocator(hGLDC, hGLRC, VideoFrameTransfer::GPUtoCPU, 1, outputFrameRowBytes * mOutputFrameHeight);
|
mPlayoutAllocator = new PinnedMemoryAllocator(hGLDC, hGLRC, VideoFrameTransfer::GPUtoCPU, 1, outputFrameRowBytes * mOutputFrameHeight);
|
||||||
|
|
||||||
if (mDLOutput->EnableVideoOutput(outputDisplayMode, bmdVideoOutputFlagDefault) != S_OK)
|
if (mDLOutput->EnableVideoOutput(outputDisplayMode, bmdVideoOutputFlagDefault) != S_OK)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink output setup failed while enabling video output.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDLOutput->QueryInterface(IID_IDeckLinkKeyer, (void**)&mDLKeyer) == S_OK && mDLKeyer != NULL)
|
if (mDLOutput->QueryInterface(IID_IDeckLinkKeyer, (void**)&mDLKeyer) == S_OK && mDLKeyer != NULL)
|
||||||
mDeckLinkKeyerInterfaceAvailable = true;
|
mDeckLinkKeyerInterfaceAvailable = true;
|
||||||
@@ -734,26 +771,41 @@ bool OpenGLComposite::InitDeckLink()
|
|||||||
IDeckLinkVideoBuffer* outputFrameBuffer = NULL;
|
IDeckLinkVideoBuffer* outputFrameBuffer = NULL;
|
||||||
|
|
||||||
if (mPlayoutAllocator->AllocateVideoBuffer(&outputFrameBuffer) != S_OK)
|
if (mPlayoutAllocator->AllocateVideoBuffer(&outputFrameBuffer) != S_OK)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink output setup failed while allocating an output frame buffer.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDLOutput->CreateVideoFrameWithBuffer(mOutputFrameWidth, mOutputFrameHeight, outputFrameRowBytes, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, outputFrameBuffer, &outputFrame) != S_OK)
|
if (mDLOutput->CreateVideoFrameWithBuffer(mOutputFrameWidth, mOutputFrameHeight, outputFrameRowBytes, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, outputFrameBuffer, &outputFrame) != S_OK)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink output setup failed while creating an output video frame.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
mDLOutputVideoFrameQueue.push_back(outputFrame);
|
mDLOutputVideoFrameQueue.push_back(outputFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
mPlayoutDelegate = new PlayoutDelegate(this);
|
mPlayoutDelegate = new PlayoutDelegate(this);
|
||||||
if (mPlayoutDelegate == NULL)
|
if (mPlayoutDelegate == NULL)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink output setup failed while creating the playout callback.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDLOutput->SetScheduledFrameCompletionCallback(mPlayoutDelegate) != S_OK)
|
if (mDLOutput->SetScheduledFrameCompletionCallback(mPlayoutDelegate) != S_OK)
|
||||||
|
{
|
||||||
|
initFailureReason = "DeckLink output setup failed while installing the scheduled-frame callback.";
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
bSuccess = true;
|
bSuccess = true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (!bSuccess)
|
if (!bSuccess)
|
||||||
{
|
{
|
||||||
|
if (!initFailureReason.empty())
|
||||||
|
MessageBoxA(NULL, initFailureReason.c_str(), "DeckLink initialization failed", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
if (mDLKeyer != NULL)
|
if (mDLKeyer != NULL)
|
||||||
{
|
{
|
||||||
mDLKeyer->Disable();
|
mDLKeyer->Disable();
|
||||||
@@ -1195,6 +1247,7 @@ void OpenGLComposite::PlayoutFrameCompleted(IDeckLinkVideoFrame* completedFrame,
|
|||||||
if (mFastTransferExtensionAvailable)
|
if (mFastTransferExtensionAvailable)
|
||||||
{
|
{
|
||||||
// Finished with mCaptureTexture
|
// Finished with mCaptureTexture
|
||||||
|
if (!mHasNoInputSource)
|
||||||
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
||||||
|
|
||||||
if (! mPlayoutAllocator->transferFrame(pFrame, mOutputTexture))
|
if (! mPlayoutAllocator->transferFrame(pFrame, mOutputTexture))
|
||||||
@@ -1232,6 +1285,16 @@ void OpenGLComposite::PlayoutFrameCompleted(IDeckLinkVideoFrame* completedFrame,
|
|||||||
bool OpenGLComposite::Start()
|
bool OpenGLComposite::Start()
|
||||||
{
|
{
|
||||||
mTotalPlayoutFrames = 0;
|
mTotalPlayoutFrames = 0;
|
||||||
|
if (!mDLOutput)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Cannot start playout because no DeckLink output device is available.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mDLOutputVideoFrameQueue.empty())
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Cannot start playout because the output frame queue is empty.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Preroll frames
|
// Preroll frames
|
||||||
for (unsigned i = 0; i < kPrerollFrameCount; i++)
|
for (unsigned i = 0; i < kPrerollFrameCount; i++)
|
||||||
@@ -1244,11 +1307,15 @@ bool OpenGLComposite::Start()
|
|||||||
// Start with a black frame for playout
|
// Start with a black frame for playout
|
||||||
IDeckLinkVideoBuffer* outputVideoFrameBuffer;
|
IDeckLinkVideoBuffer* outputVideoFrameBuffer;
|
||||||
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
|
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Could not query the preroll output frame buffer.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (outputVideoFrameBuffer->StartAccess(bmdBufferAccessWrite) != S_OK)
|
if (outputVideoFrameBuffer->StartAccess(bmdBufferAccessWrite) != S_OK)
|
||||||
{
|
{
|
||||||
outputVideoFrameBuffer->Release();
|
outputVideoFrameBuffer->Release();
|
||||||
|
MessageBoxA(NULL, "Could not write to the preroll output frame buffer.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1260,13 +1327,27 @@ bool OpenGLComposite::Start()
|
|||||||
outputVideoFrameBuffer->Release();
|
outputVideoFrameBuffer->Release();
|
||||||
|
|
||||||
if (mDLOutput->ScheduleVideoFrame(outputVideoFrame, (mTotalPlayoutFrames * mFrameDuration), mFrameDuration, mFrameTimescale) != S_OK)
|
if (mDLOutput->ScheduleVideoFrame(outputVideoFrame, (mTotalPlayoutFrames * mFrameDuration), mFrameDuration, mFrameTimescale) != S_OK)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Could not schedule a preroll output frame.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mTotalPlayoutFrames++;
|
mTotalPlayoutFrames++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDLInput->StartStreams();
|
if (mDLInput)
|
||||||
mDLOutput->StartScheduledPlayback(0, mFrameTimescale, 1.0);
|
{
|
||||||
|
if (mDLInput->StartStreams() != S_OK)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Could not start the DeckLink input stream.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mDLOutput->StartScheduledPlayback(0, mFrameTimescale, 1.0) != S_OK)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Could not start DeckLink scheduled playback.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1296,11 +1377,17 @@ bool OpenGLComposite::Stop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDLInput)
|
||||||
|
{
|
||||||
mDLInput->StopStreams();
|
mDLInput->StopStreams();
|
||||||
mDLInput->DisableVideoInput();
|
mDLInput->DisableVideoInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDLOutput)
|
||||||
|
{
|
||||||
mDLOutput->StopScheduledPlayback(0, NULL, 0);
|
mDLOutput->StopScheduledPlayback(0, NULL, 0);
|
||||||
mDLOutput->DisableVideoOutput();
|
mDLOutput->DisableVideoOutput();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1920,10 +2007,8 @@ void OpenGLComposite::renderEffect()
|
|||||||
{
|
{
|
||||||
PollRuntimeChanges();
|
PollRuntimeChanges();
|
||||||
|
|
||||||
if (mHasNoInputSource)
|
const bool hasInputSource = !mHasNoInputSource;
|
||||||
return;
|
if (hasInputSource && mFastTransferExtensionAvailable)
|
||||||
|
|
||||||
if (mFastTransferExtensionAvailable)
|
|
||||||
{
|
{
|
||||||
// Signal that we're about to draw using mCaptureTexture onto mFBOTexture.
|
// Signal that we're about to draw using mCaptureTexture onto mFBOTexture.
|
||||||
VideoFrameTransfer::beginTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
VideoFrameTransfer::beginTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
||||||
@@ -1931,7 +2016,17 @@ void OpenGLComposite::renderEffect()
|
|||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
if (hasInputSource)
|
||||||
|
{
|
||||||
renderDecodePass();
|
renderDecodePass();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, mDecodeFrameBuf);
|
||||||
|
glViewport(0, 0, mInputFrameWidth, mInputFrameHeight);
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<RuntimeRenderState> layerStates = mRuntimeHost ? mRuntimeHost->GetLayerRenderStates(mInputFrameWidth, mInputFrameHeight) : std::vector<RuntimeRenderState>();
|
const std::vector<RuntimeRenderState> layerStates = mRuntimeHost ? mRuntimeHost->GetLayerRenderStates(mInputFrameWidth, mInputFrameHeight) : std::vector<RuntimeRenderState>();
|
||||||
if (layerStates.empty() || mLayerPrograms.empty())
|
if (layerStates.empty() || mLayerPrograms.empty())
|
||||||
@@ -1963,7 +2058,7 @@ void OpenGLComposite::renderEffect()
|
|||||||
|
|
||||||
pushFramebufferToHistoryRing(mDecodeFrameBuf, mSourceHistoryRing);
|
pushFramebufferToHistoryRing(mDecodeFrameBuf, mSourceHistoryRing);
|
||||||
|
|
||||||
if (mFastTransferExtensionAvailable)
|
if (hasInputSource && mFastTransferExtensionAvailable)
|
||||||
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user