
Unfortunately this brings back the C++ requirement, but later on this will happen anyway, what with me wanting some CV funsies.
131 lines
3.5 KiB
C++
131 lines
3.5 KiB
C++
#include"node.h"
|
|
|
|
#include<stdlib.h>
|
|
|
|
#include<ScreenCapture.h>
|
|
#include<mutex>
|
|
|
|
#include<tmmintrin.h>
|
|
#include<smmintrin.h>
|
|
|
|
#include<time.h>
|
|
|
|
#include<string.h>
|
|
|
|
#include"img.h"
|
|
|
|
#include"linearity.h"
|
|
|
|
#include"minitrace.h"
|
|
|
|
typedef struct {
|
|
CHiPubNode pub;
|
|
|
|
char* lastWindowString;
|
|
std::shared_ptr<SL::Screen_Capture::IScreenCaptureManager> config;
|
|
|
|
std::mutex mut;
|
|
std::vector<CHiImage*> images;
|
|
} CHiWindowNode;
|
|
|
|
static int window_perform(CHiPubNode *n) {
|
|
CHiWindowNode *w = (CHiWindowNode*) n;
|
|
|
|
MTR_BEGIN("CHi", "window_perform");
|
|
|
|
const char *expectedTitle = CHi_Crawl(&w->pub.sinks[0])->data.text;
|
|
|
|
if(w->lastWindowString == nullptr || strcmp(w->lastWindowString, expectedTitle)) {
|
|
if(w->lastWindowString) {
|
|
free(w->lastWindowString);
|
|
}
|
|
w->lastWindowString = strdup(expectedTitle);
|
|
|
|
w->config = SL::Screen_Capture::CreateCaptureConfiguration([=](){
|
|
for(SL::Screen_Capture::Window& window : SL::Screen_Capture::GetWindows()) {
|
|
if(!strcmp(window.Name, w->lastWindowString)) {
|
|
return std::vector<SL::Screen_Capture::Window>{window};
|
|
}
|
|
}
|
|
return std::vector<SL::Screen_Capture::Window>{};
|
|
})->onNewFrame([=](const SL::Screen_Capture::Image& img, const SL::Screen_Capture::Window& window){
|
|
CHiImage *new_image = CHi_Image_New(2, 4, (window.Size.x * 8 + 15) & ~15, window.Size.x, window.Size.y, nullptr);
|
|
memset(new_image->data8, 0, new_image->stride * new_image->height);
|
|
|
|
#pragma omp parallel for
|
|
for(size_t y = 0; y < new_image->height; y++) {
|
|
uint8_t buf[16] = {};
|
|
for(size_t x = 0; x < new_image->width; x += 2) {
|
|
memcpy(buf, &img.Data[y * new_image->width + x], 8);
|
|
|
|
__m128i c = _mm_loadu_si128((__m128i*) buf);
|
|
c = _mm_shuffle_epi8(c, _mm_set_epi8(7, -128, 6, -128, 5, -128, 4, -128, 3, -128, 2, -128, 1, -128, 0, -128));
|
|
c = apply_gamma_epi16(c, _mm_set_ps(1, 2.2f, 2.2f, 2.2f));
|
|
_mm_store_si128((__m128i*) ((uintptr_t) new_image->data8 + y * new_image->stride + x * 8), c);
|
|
}
|
|
}
|
|
|
|
std::unique_lock<std::mutex> lock{w->mut};
|
|
while(w->images.size() > 0) {
|
|
CHi_Image_Free(w->images.front());
|
|
w->images.erase(w->images.begin());
|
|
}
|
|
w->images.push_back(new_image);
|
|
})->start_capturing();
|
|
}
|
|
|
|
std::unique_lock<std::mutex> lock{w->mut};
|
|
if(w->images.size() > 0) {
|
|
if(n->sources[0].data.sample) {
|
|
CHi_Image_Free(n->sources[0].data.sample);
|
|
}
|
|
|
|
n->sources[0].type = CUTIHI_VAL_SAMPLE;
|
|
n->sources[0].data.sample = w->images.front();
|
|
|
|
w->images.erase(w->images.begin());
|
|
}
|
|
|
|
MTR_END("CHi", "window_perform");
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void window_destroy(CHiPubNode *pubn) {
|
|
CHiWindowNode *n = (CHiWindowNode*) pubn;
|
|
delete n;
|
|
}
|
|
|
|
CUTIVIS CHiPubNode *CHi_Window() {
|
|
auto *n = new CHiWindowNode();
|
|
n->pub.type = CUTIHI_T('CWin','dow ');
|
|
n->pub.Start = n->pub.Stop = NULL;
|
|
n->pub.Perform = window_perform;
|
|
n->pub.Destroy = window_destroy;
|
|
n->pub.sinkCount = 1;
|
|
n->pub.sinks = (CHiValue*) calloc(sizeof(*n->pub.sinks), 1);
|
|
n->pub.sourceCount = 1;
|
|
n->pub.sources = (CHiValue*) calloc(sizeof(*n->pub.sources), 1);
|
|
|
|
return &n->pub;
|
|
}
|
|
|
|
CUTIVIS size_t CHi_Window_GetList(void **buf) {
|
|
auto vec = SL::Screen_Capture::GetWindows();
|
|
|
|
*buf = calloc(vec.size(), sizeof(vec[0]));
|
|
memcpy(*buf, &vec[0], sizeof(vec[0]) * vec.size());
|
|
|
|
return vec.size();
|
|
}
|
|
|
|
CUTIVIS const char *CHi_Window_GetName(void *buf, size_t i) {
|
|
return ((SL::Screen_Capture::Window*) buf)[i].Name;
|
|
}
|
|
CUTIVIS size_t CHi_Window_GetHandle(void *buf, size_t i) {
|
|
return ((SL::Screen_Capture::Window*) buf)[i].Handle;
|
|
}
|
|
CUTIVIS void CHi_Window_FreeList(void *buf) {
|
|
free(buf);
|
|
}
|