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

View File

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

View File

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

View File

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

View File

@ -42,8 +42,11 @@ struct iface
CapturePostPointerBuffer postPointerBufferFn; CapturePostPointerBuffer postPointerBufferFn;
LGThread * pointerThread; LGThread * pointerThread;
unsigned int maxWidth, maxHeight; unsigned int maxWidth , maxHeight;
unsigned int width , height; unsigned int width , height;
unsigned int formatVer;
unsigned int grabWidth, grabHeight, grabStride;
uint8_t * frameBuffer; uint8_t * frameBuffer;
uint8_t * diffMap; uint8_t * diffMap;
@ -195,6 +198,7 @@ static bool nvfbc_init()
return false; return false;
} }
++this->formatVer;
return true; return true;
} }
@ -284,10 +288,22 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame)
if (this->stop) if (this->stop)
return CAPTURE_RESULT_REINIT; return CAPTURE_RESULT_REINIT;
frame->width = this->grabInfo.dwWidth; if (
frame->height = this->grabInfo.dwHeight; this->grabInfo.dwWidth != this->grabWidth ||
frame->pitch = this->grabInfo.dwBufferWidth * 4; this->grabInfo.dwHeight != this->grabHeight ||
frame->stride = this->grabInfo.dwBufferWidth; 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 #if 0
//NvFBC never sets bIsHDR so instead we check for any data in the alpha channel //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; continue;
} }
fi->width = frame.width; fi->formatVer = frame.formatVer;
fi->height = frame.height; fi->width = frame.width;
fi->stride = frame.stride; fi->height = frame.height;
fi->pitch = frame.pitch; fi->stride = frame.stride;
fi->offset = pageSize - FrameBufferStructSize; fi->pitch = frame.pitch;
frameValid = true; fi->offset = pageSize - FrameBufferStructSize;
frameValid = true;
// put the framebuffer on the border of the next page // put the framebuffer on the border of the next page
// this is to allow for aligned DMA transfers by the receiver // this is to allow for aligned DMA transfers by the receiver

View File

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