16bit processing
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
#include "OpenGLDeckLinkBridge.h"
|
||||
|
||||
#include "DeckLinkFrameTransfer.h"
|
||||
#include "DeckLinkSession.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "RuntimeHost.h"
|
||||
#include "VideoFrameTransfer.h"
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <chrono>
|
||||
#include <gl/gl.h>
|
||||
|
||||
@@ -87,29 +84,20 @@ void OpenGLDeckLinkBridge::VideoFrameArrived(IDeckLinkVideoInputFrame* inputFram
|
||||
|
||||
wglMakeCurrent(mHdc, mHglrc); // make OpenGL context current in this thread
|
||||
|
||||
if (mRenderer.FastTransferAvailable())
|
||||
{
|
||||
CComQIPtr<PinnedMemoryAllocator, &IID_PinnedMemoryAllocator> allocator(inputFrameBuffer);
|
||||
if (!allocator || !allocator->transferFrame(videoPixels, mRenderer.CaptureTexture()))
|
||||
OutputDebugStringA("Capture: transferFrame() failed\n");
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mRenderer.TextureUploadBuffer());
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, textureSize, videoPixels, GL_DYNAMIC_DRAW);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderer.CaptureTexture());
|
||||
|
||||
allocator->waitForTransferComplete(videoPixels);
|
||||
}
|
||||
// NULL for last arg indicates use current GL_PIXEL_UNPACK_BUFFER target as texture data.
|
||||
if (mDeckLink.InputPixelFormat() == VideoIOPixelFormat::V210)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mDeckLink.CaptureTextureWidth(), mDeckLink.InputFrameHeight(), GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
else
|
||||
{
|
||||
// Use a straightforward texture buffer
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mRenderer.UnpinnedTextureBuffer());
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, textureSize, videoPixels, GL_DYNAMIC_DRAW);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderer.CaptureTexture());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mDeckLink.CaptureTextureWidth(), mDeckLink.InputFrameHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
// NULL for last arg indicates use current GL_PIXEL_UNPACK_BUFFER target as texture data
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mDeckLink.InputFrameWidth() / 2, mDeckLink.InputFrameHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
|
||||
@@ -135,17 +123,35 @@ void OpenGLDeckLinkBridge::PlayoutFrameCompleted(IDeckLinkVideoFrame* completedF
|
||||
|
||||
// Draw the effect output to the off-screen framebuffer.
|
||||
const auto renderStartTime = std::chrono::steady_clock::now();
|
||||
if (mRenderer.FastTransferAvailable())
|
||||
VideoFrameTransfer::beginTextureInUse(VideoFrameTransfer::GPUtoCPU);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mRenderer.CompositeFramebuffer());
|
||||
mRenderEffect();
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mRenderer.CompositeFramebuffer());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mRenderer.OutputFramebuffer());
|
||||
glBlitFramebuffer(0, 0, mDeckLink.InputFrameWidth(), mDeckLink.InputFrameHeight(), 0, 0, mDeckLink.OutputFrameWidth(), mDeckLink.OutputFrameHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mRenderer.OutputFramebuffer());
|
||||
if (mDeckLink.OutputIsTenBit())
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mRenderer.OutputPackFramebuffer());
|
||||
glViewport(0, 0, mDeckLink.OutputPackTextureWidth(), mDeckLink.OutputFrameHeight());
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderer.OutputTexture());
|
||||
glBindVertexArray(mRenderer.FullscreenVertexArray());
|
||||
glUseProgram(mRenderer.OutputPackProgram());
|
||||
const GLint outputResolutionLocation = glGetUniformLocation(mRenderer.OutputPackProgram(), "uOutputVideoResolution");
|
||||
const GLint activeWordsLocation = glGetUniformLocation(mRenderer.OutputPackProgram(), "uActiveV210Words");
|
||||
if (outputResolutionLocation >= 0)
|
||||
glUniform2f(outputResolutionLocation, static_cast<float>(mDeckLink.OutputFrameWidth()), static_cast<float>(mDeckLink.OutputFrameHeight()));
|
||||
if (activeWordsLocation >= 0)
|
||||
glUniform1f(activeWordsLocation, static_cast<float>(ActiveV210WordsForWidth(mDeckLink.OutputFrameWidth())));
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
glFlush();
|
||||
if (mRenderer.FastTransferAvailable())
|
||||
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::GPUtoCPU);
|
||||
const auto renderEndTime = std::chrono::steady_clock::now();
|
||||
const double frameBudgetMilliseconds = mDeckLink.FrameBudgetMilliseconds();
|
||||
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(renderEndTime - renderStartTime).count();
|
||||
@@ -171,23 +177,19 @@ void OpenGLDeckLinkBridge::PlayoutFrameCompleted(IDeckLinkVideoFrame* completedF
|
||||
void* pFrame;
|
||||
outputVideoFrameBuffer->GetBytes(&pFrame);
|
||||
|
||||
if (mRenderer.FastTransferAvailable())
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
if (mDeckLink.OutputIsTenBit())
|
||||
{
|
||||
if (!mDeckLink.TransferPlayoutFrame(pFrame, mRenderer.OutputTexture()))
|
||||
OutputDebugStringA("Playback: transferFrame() failed\n");
|
||||
|
||||
// Wait for transfer to system memory to complete
|
||||
mDeckLink.WaitForPlayoutTransferComplete(pFrame);
|
||||
mPaint();
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mRenderer.OutputPackFramebuffer());
|
||||
glReadPixels(0, 0, mDeckLink.OutputPackTextureWidth(), mDeckLink.OutputFrameHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mRenderer.OutputFramebuffer());
|
||||
glReadPixels(0, 0, mDeckLink.OutputFrameWidth(), mDeckLink.OutputFrameHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pFrame);
|
||||
mPaint();
|
||||
}
|
||||
mPaint();
|
||||
|
||||
outputVideoFrameBuffer->EndAccess(bmdBufferAccessWrite);
|
||||
outputVideoFrameBuffer->Release();
|
||||
|
||||
Reference in New Issue
Block a user