[c-host] app: inital capture is now working

This commit is contained in:
Geoffrey McRae 2019-03-04 09:37:50 +11:00
parent ff850c4251
commit fcc06dfad4
5 changed files with 76 additions and 4 deletions

View File

@ -24,6 +24,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include "debug.h" #include "debug.h"
#include "locking.h"
#include "capture/interfaces.h" #include "capture/interfaces.h"
#include "KVMFR.h" #include "KVMFR.h"
@ -81,7 +82,9 @@ static int frameThread(void * opaque)
{ {
DEBUG_INFO("Frame thread started"); DEBUG_INFO("Frame thread started");
int frameIndex = 0; int frameIndex = 0;
volatile KVMFRFrame * fi = &(app.shmHeader->frame);
while(app.running) while(app.running)
{ {
if (!os_waitEvent(app.frameEvent) || !app.running) if (!os_waitEvent(app.frameEvent) || !app.running)
@ -93,6 +96,32 @@ static int frameThread(void * opaque)
DEBUG_ERROR("Failed to get the frame"); DEBUG_ERROR("Failed to get the frame");
os_signalEvent(app.updateEvent); os_signalEvent(app.updateEvent);
// wait for the client to finish with the previous frame
while(fi->flags & KVMFR_FRAME_FLAG_UPDATE)
{
// this generally never happens
usleep(1000);
}
switch(frame.format)
{
case CAPTURE_FMT_BGRA : fi->type = FRAME_TYPE_BGRA ; break;
case CAPTURE_FMT_RGBA : fi->type = FRAME_TYPE_RGBA ; break;
case CAPTURE_FMT_RGBA10: fi->type = FRAME_TYPE_RGBA10; break;
case CAPTURE_FMT_YUV420: fi->type = FRAME_TYPE_YUV420; break;
default:
DEBUG_ERROR("Unsupported frame format %d, skipping frame", frame.format);
continue;
}
fi->width = frame.width;
fi->height = frame.height;
fi->stride = frame.stride;
fi->pitch = frame.pitch;
fi->dataPos = app.frameOffset[frameIndex];
INTERLOCKED_OR8(&fi->flags, KVMFR_FRAME_FLAG_UPDATE);
if (++frameIndex == MAX_FRAMES) if (++frameIndex == MAX_FRAMES)
frameIndex = 0; frameIndex = 0;
} }
@ -174,9 +203,9 @@ int app_main()
DEBUG_INFO("IVSHMEM Address : 0x%" PRIXPTR, (uintptr_t)shmemMap); DEBUG_INFO("IVSHMEM Address : 0x%" PRIXPTR, (uintptr_t)shmemMap);
app.shmHeader = (KVMFRHeader *)shmemMap; app.shmHeader = (KVMFRHeader *)shmemMap;
app.pointerData = (uint8_t *)ALIGN_UP(shmemMap + sizeof(KVMFRHeader)); app.pointerData = (uint8_t *)ALIGN_UP(shmemMap + sizeof(KVMFRHeader));
app.pointerDataSize = 1048576; // 1MB fixed for pointer size, should be more then enough app.pointerDataSize = 1048576; // 1MB fixed for pointer size, should be more then enough
app.pointerOffset = app.pointerData - shmemMap; app.pointerOffset = app.pointerData - shmemMap;
app.frames = (uint8_t *)ALIGN_UP(app.pointerData + app.pointerDataSize); app.frames = (uint8_t *)ALIGN_UP(app.pointerData + app.pointerDataSize);
app.frameSize = ALIGN_DN((shmemSize - (app.frames - shmemMap)) / MAX_FRAMES); app.frameSize = ALIGN_DN((shmemSize - (app.frames - shmemMap)) / MAX_FRAMES);
@ -242,6 +271,15 @@ int app_main()
goto exit; goto exit;
} }
// initialize the shared memory headers
memcpy(app.shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
app.shmHeader->version = KVMFR_HEADER_VERSION;
// zero and notify the client we are starting
memset(&(app.shmHeader->frame ), 0, sizeof(KVMFRFrame ));
memset(&(app.shmHeader->cursor), 0, sizeof(KVMFRCursor));
app.shmHeader->flags &= ~KVMFR_HEADER_FLAG_RESTART;
if (!captureStart()) if (!captureStart())
{ {
exitcode = -1; exitcode = -1;
@ -251,8 +289,12 @@ int app_main()
// start signalled // start signalled
os_signalEvent(app.updateEvent); os_signalEvent(app.updateEvent);
volatile char * flags = (volatile char *)&(app.shmHeader->flags);
while(app.running) while(app.running)
{ {
INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART));
// wait for one of the threads to flag an update // wait for one of the threads to flag an update
if (!os_waitEvent(app.updateEvent) || !app.running) if (!os_waitEvent(app.updateEvent) || !app.running)
break; break;

View File

@ -46,6 +46,7 @@ typedef struct CaptureFrame
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
unsigned int pitch; unsigned int pitch;
unsigned int stride;
CaptureFormat format; CaptureFormat format;
void * data; void * data;
} }

View File

@ -203,6 +203,7 @@ static bool xcb_getFrame(CaptureFrame * frame)
frame->width = this->width; frame->width = this->width;
frame->height = this->height; frame->height = this->height;
frame->pitch = this->width * 4; frame->pitch = this->width * 4;
frame->stride = this->width;
frame->format = CAPTURE_FMT_BGRA; frame->format = CAPTURE_FMT_BGRA;
memcpy(frame->data, this->data, this->width * this->height * 4); memcpy(frame->data, this->data, this->width * this->height * 4);

View File

@ -469,6 +469,7 @@ static bool dxgi_getFrame(CaptureFrame * frame)
frame->width = this->width; frame->width = this->width;
frame->height = this->height; frame->height = this->height;
frame->pitch = this->pitch; frame->pitch = this->pitch;
frame->stride = this->stride;
frame->format = this->format; frame->format = this->format;
HRESULT status; HRESULT status;

27
common/locking.h Normal file
View File

@ -0,0 +1,27 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
#if __MINGW32__
#define INTERLOCKED_AND8 __sync_and_and_fetch
#define INTERLOCKED_OR8 __sync_or_and_fetch
#else
#define INTERLOCKED_OR8 InterlockedOr8
#define INTERLOCKED_AND8 InterlockedAnd8
#endif