/
githubmirror
/
obs-studio
Обзор
Документация
Войти
/
githubmirror
/
obs-studio
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
plugins/win-dshow/virtualcam-module/placeholder.cpp
155 строк
3 KB
Warchamp7
Update C++ files with braces
09 июн 2026, 20:41
09 июн 2026, 20:41
30b63c6
Код
Авторство
О чём код?
#include <windows.h> #include <strsafe.h> #include <gdiplus.h> #include <stdint.h> #include <vector> using namespace Gdiplus; extern HINSTANCE dll_inst; static std::vector<uint8_t> placeholder; static bool initialized = false; int cx, cy; /* XXX: optimize this later. or don't, it's only called once. */ static void convert_placeholder(const uint8_t *rgb_in, int width, int height) { size_t size = width * height * 3; size_t linesize = width * 3; std::vector<uint8_t> yuv_out; yuv_out.resize(size); const uint8_t *in = rgb_in; const uint8_t *end = in + size; uint8_t *out = &yuv_out[0]; while (in < end) { const int16_t b = *(in++); const int16_t g = *(in++); const int16_t r = *(in++); *(out++) = (uint8_t)(((66 * r + 129 * g + 25 * b + 128) >> 8) + 16); *(out++) = (uint8_t)(((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128); *(out++) = (uint8_t)(((112 * r - 94 * g - 18 * b + 128) >> 8) + 128); } placeholder.resize(width * height * 3 / 2); in = &yuv_out[0]; end = in + size; out = &placeholder[0]; uint8_t *chroma = out + width * height; while (in < end) { const uint8_t *in2 = in + linesize; const uint8_t *end2 = in2; uint8_t *out2 = out + width; while (in < end2) { int16_t u; int16_t v; *(out++) = *(in++); u = *(in++); v = *(in++); *(out++) = *(in++); u += *(in++); v += *(in++); *(out2++) = *(in2++); u += *(in2++); v += *(in2++); *(out2++) = *(in2++); u += *(in2++); v += *(in2++); *(chroma++) = (uint8_t)(u / 4); *(chroma++) = (uint8_t)(v / 4); } in = in2; out = out2; } } static bool load_placeholder_internal() { Status s; wchar_t file[MAX_PATH]; if (!GetModuleFileNameW(dll_inst, file, MAX_PATH)) { return false; } wchar_t *slash = wcsrchr(file, '\\'); if (!slash) { return false; } slash[1] = 0; StringCbCat(file, sizeof(file), L"placeholder.png"); Bitmap bmp(file); if (bmp.GetLastStatus() != Status::Ok) { return false; } cx = bmp.GetWidth(); cy = bmp.GetHeight(); BitmapData bmd = {}; Rect r(0, 0, cx, cy); s = bmp.LockBits(&r, ImageLockModeRead, PixelFormat24bppRGB, &bmd); if (s != Status::Ok) { return false; } convert_placeholder((const uint8_t *)bmd.Scan0, cx, cy); bmp.UnlockBits(&bmd); return true; } bool initialize_placeholder() { if (initialized) { return true; } GdiplusStartupInput si; ULONG_PTR token; GdiplusStartup(&token, &si, nullptr); initialized = load_placeholder_internal(); GdiplusShutdown(token); return initialized; } const uint8_t *get_placeholder_ptr() { if (initialized) { return placeholder.data(); } return nullptr; } const bool get_placeholder_size(int *out_cx, int *out_cy) { if (initialized) { *out_cx = cx; *out_cy = cy; return true; } return false; }