#include"node.h" #include #include #include #include #include #include #include #include"img.h" #include"linearity.h" #include"minitrace.h" typedef struct { CHiPubNode pub; char* lastWindowString; std::shared_ptr config; std::mutex mut; std::vector 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{window}; } } return std::vector{}; })->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 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 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); }