[all] added new format version field to frame header

This commit is contained in:
Geoffrey McRae 2020-10-12 18:52:37 +11:00
parent 6650e58a4a
commit b2961c7939
7 changed files with 126 additions and 89 deletions

View File

@ -375,6 +375,10 @@ static int frameThread(void * unused)
LGMP_STATUS status;
PLGMPClientQueue queue;
uint32_t formatVer = 0;
bool formatValid = false;
LG_RendererFormat lgrFormat;
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
lgWaitEvent(e_startup, TIMEOUT_INFINITE);
if (state.state != APP_STATE_RUNNING)
@ -421,56 +425,61 @@ static int frameThread(void * unused)
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
// setup the renderer format with the frame format details
LG_RendererFormat lgrFormat;
lgrFormat.type = frame->type;
lgrFormat.width = frame->width;
lgrFormat.height = frame->height;
lgrFormat.stride = frame->stride;
lgrFormat.pitch = frame->pitch;
size_t dataSize;
bool error = false;
switch(frame->type)
if (!formatValid || frame->formatVer != formatVer)
{
case FRAME_TYPE_RGBA:
case FRAME_TYPE_BGRA:
case FRAME_TYPE_RGBA10:
dataSize = lgrFormat.height * lgrFormat.pitch;
lgrFormat.bpp = 32;
break;
// setup the renderer format with the frame format details
lgrFormat.type = frame->type;
lgrFormat.width = frame->width;
lgrFormat.height = frame->height;
lgrFormat.stride = frame->stride;
lgrFormat.pitch = frame->pitch;
case FRAME_TYPE_RGBA16F:
dataSize = lgrFormat.height * lgrFormat.pitch;
lgrFormat.bpp = 64;
break;
size_t dataSize;
bool error = false;
switch(frame->type)
{
case FRAME_TYPE_RGBA:
case FRAME_TYPE_BGRA:
case FRAME_TYPE_RGBA10:
dataSize = lgrFormat.height * lgrFormat.pitch;
lgrFormat.bpp = 32;
break;
case FRAME_TYPE_YUV420:
dataSize = lgrFormat.height * lgrFormat.width;
dataSize += (dataSize / 4) * 2;
lgrFormat.bpp = 12;
break;
case FRAME_TYPE_RGBA16F:
dataSize = lgrFormat.height * lgrFormat.pitch;
lgrFormat.bpp = 64;
break;
default:
DEBUG_ERROR("Unsupported frameType");
error = true;
case FRAME_TYPE_YUV420:
dataSize = lgrFormat.height * lgrFormat.width;
dataSize += (dataSize / 4) * 2;
lgrFormat.bpp = 12;
break;
default:
DEBUG_ERROR("Unsupported frameType");
error = true;
break;
}
if (error)
{
lgmpClientMessageDone(queue);
state.state = APP_STATE_SHUTDOWN;
break;
}
formatValid = true;
formatVer = frame->formatVer;
}
if (error)
if (lgrFormat.width != state.srcSize.x || lgrFormat.height != state.srcSize.y)
{
lgmpClientMessageDone(queue);
state.state = APP_STATE_SHUTDOWN;
break;
}
if (frame->width != state.srcSize.x || frame->height != state.srcSize.y)
{
state.srcSize.x = frame->width;
state.srcSize.y = frame->height;
state.srcSize.x = lgrFormat.width;
state.srcSize.y = lgrFormat.height;
state.haveSrcSize = true;
if (params.autoResize)
SDL_SetWindowSize(state.window, frame->width, frame->height);
SDL_SetWindowSize(state.window, lgrFormat.width, lgrFormat.height);
updatePositionInfo();
}

View File

@ -52,7 +52,7 @@ typedef enum CursorType
CursorType;
#define KVMFR_MAGIC "KVMFR---"
#define KVMFR_VERSION 4
#define KVMFR_VERSION 5
typedef struct KVMFR
{
@ -75,6 +75,7 @@ KVMFRCursor;
typedef struct KVMFRFrame
{
uint32_t formatVer; // the frame format version number
FrameType type; // the frame data type
uint32_t width; // the width
uint32_t height; // the height

View File

@ -52,6 +52,7 @@ CaptureFormat;
typedef struct CaptureFrame
{
unsigned int formatVer;
unsigned int width;
unsigned int height;
unsigned int pitch;

View File

@ -57,6 +57,7 @@ enum TextureState
typedef struct Texture
{
unsigned int formatVer;
volatile enum TextureState state;
ID3D11Texture2D * tex;
D3D11_MAPPED_SUBRESOURCE map;
@ -91,6 +92,7 @@ struct iface
CapturePostPointerBuffer postPointerBufferFn;
LGEvent * frameEvent;
unsigned int formatVer;
unsigned int width;
unsigned int height;
unsigned int pitch;
@ -227,9 +229,10 @@ static bool dxgi_init()
HRESULT status;
DXGI_OUTPUT_DESC outputDesc;
this->stop = false;
this->texRIndex = 0;
this->texWIndex = 0;
this->stop = false;
this->texRIndex = 0;
this->texWIndex = 0;
this->formatVer = 0;
atomic_store(&this->texReady, 0);
lgResetEvent(this->frameEvent);
@ -386,6 +389,7 @@ static bool dxgi_init()
IDXGIAdapter1_GetDesc1(this->adapter, &adapterDesc);
this->width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left;
this->height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top;
++this->formatVer;
DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description);
DEBUG_INFO("Device Vendor ID : 0x%x" , adapterDesc.VendorId);
@ -805,7 +809,8 @@ static CaptureResult dxgi_capture()
ID3D11Texture2D_Release(src);
// set the state, and signal
tex->state = TEXTURE_STATE_PENDING_MAP;
tex->state = TEXTURE_STATE_PENDING_MAP;
tex->formatVer = this->formatVer;
if (atomic_fetch_add_explicit(&this->texReady, 1, memory_order_relaxed) == 0)
lgSignalEvent(this->frameEvent);
@ -950,11 +955,12 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
tex->state = TEXTURE_STATE_MAPPED;
frame->width = this->width;
frame->height = this->height;
frame->pitch = this->pitch;
frame->stride = this->stride;
frame->format = this->format;
frame->formatVer = tex->formatVer;
frame->width = this->width;
frame->height = this->height;
frame->pitch = this->pitch;
frame->stride = this->stride;
frame->format = this->format;
atomic_fetch_sub_explicit(&this->texReady, 1, memory_order_release);
return CAPTURE_RESULT_OK;

View File

@ -42,8 +42,11 @@ struct iface
CapturePostPointerBuffer postPointerBufferFn;
LGThread * pointerThread;
unsigned int maxWidth, maxHeight;
unsigned int width , height;
unsigned int maxWidth , maxHeight;
unsigned int width , height;
unsigned int formatVer;
unsigned int grabWidth, grabHeight, grabStride;
uint8_t * frameBuffer;
uint8_t * diffMap;
@ -195,6 +198,7 @@ static bool nvfbc_init()
return false;
}
++this->formatVer;
return true;
}
@ -284,10 +288,22 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame)
if (this->stop)
return CAPTURE_RESULT_REINIT;
frame->width = this->grabInfo.dwWidth;
frame->height = this->grabInfo.dwHeight;
frame->pitch = this->grabInfo.dwBufferWidth * 4;
frame->stride = this->grabInfo.dwBufferWidth;
if (
this->grabInfo.dwWidth != this->grabWidth ||
this->grabInfo.dwHeight != this->grabHeight ||
this->grabInfo.dwBufferWidth != this->grabStride)
{
this->grabWidth = this->grabInfo.dwWidth;
this->grabHeight = this->grabInfo.dwHeight;
this->grabStride = this->grabInfo.dwBufferWidth;
++this->formatVer;
}
frame->formatVer = this->formatVer;
frame->width = this->grabWidth;
frame->height = this->grabHeight;
frame->pitch = this->grabStride * 4;
frame->stride = this->grabStride;
#if 0
//NvFBC never sets bIsHDR so instead we check for any data in the alpha channel

View File

@ -188,12 +188,13 @@ static int frameThread(void * opaque)
continue;
}
fi->width = frame.width;
fi->height = frame.height;
fi->stride = frame.stride;
fi->pitch = frame.pitch;
fi->offset = pageSize - FrameBufferStructSize;
frameValid = true;
fi->formatVer = frame.formatVer;
fi->width = frame.width;
fi->height = frame.height;
fi->stride = frame.stride;
fi->pitch = frame.pitch;
fi->offset = pageSize - FrameBufferStructSize;
frameValid = true;
// put the framebuffer on the border of the next page
// this is to allow for aligned DMA transfers by the receiver

View File

@ -29,6 +29,7 @@ typedef struct
obs_source_t * context;
LGState state;
char * shmFile;
uint32_t formatVer;
uint32_t width, height;
FrameType type;
int bpp;
@ -452,20 +453,14 @@ static void lgVideoTick(void * data, float seconds)
return;
}
bool updateTexture = false;
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
if (this->width != frame->width ||
this->height != frame->height ||
this->type != frame->type)
if (!this->texture || this->formatVer != frame->formatVer)
{
updateTexture = true;
this->width = frame->width;
this->height = frame->height;
this->type = frame->type;
}
this->formatVer = frame->formatVer;
this->width = frame->width;
this->height = frame->height;
this->type = frame->type;
if (!this->texture || updateTexture)
{
obs_enter_graphics();
if (this->texture)
{
@ -509,24 +504,32 @@ static void lgVideoTick(void * data, float seconds)
obs_leave_graphics();
}
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
framebuffer_read(
fb,
this->texData, // dst
this->linesize, // dstpitch
frame->height, // height
frame->width, // width
this->bpp, // bpp
frame->pitch // linepitch
);
if (this->texture)
{
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
framebuffer_read(
fb,
this->texData, // dst
this->linesize, // dstpitch
frame->height, // height
frame->width, // width
this->bpp, // bpp
frame->pitch // linepitch
);
lgmpClientMessageDone(this->frameQueue);
os_sem_post(this->frameSem);
lgmpClientMessageDone(this->frameQueue);
os_sem_post(this->frameSem);
obs_enter_graphics();
gs_texture_unmap(this->texture);
gs_texture_map(this->texture, &this->texData, &this->linesize);
obs_leave_graphics();
obs_enter_graphics();
gs_texture_unmap(this->texture);
gs_texture_map(this->texture, &this->texData, &this->linesize);
obs_leave_graphics();
}
else
{
lgmpClientMessageDone(this->frameQueue);
os_sem_post(this->frameSem);
}
}
static void lgVideoRender(void * data, gs_effect_t * effect)