Reimplement monitor capture
- Implement windows monitor capture (code is so much cleaner than in OBS1). Will implement duplication capture later - Add GDI texture support to d3d11 graphics library - Fix precision issue with sleep timing, you have to call timeBeginPeriod otherwise windows sleep will be totally erratic.master
parent
3415960d02
commit
4f7ab552df
|
@ -0,0 +1,35 @@
|
|||
uniform float4x4 ViewProj;
|
||||
uniform texture2d image;
|
||||
|
||||
sampler_state def_sampler {
|
||||
Filter = Linear;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
struct VertInOut {
|
||||
float4 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertInOut VSDefault(VertInOut vert_in)
|
||||
{
|
||||
VertInOut vert_out;
|
||||
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
|
||||
vert_out.uv = vert_in.uv;
|
||||
return vert_out;
|
||||
}
|
||||
|
||||
float4 PSDraw(VertInOut vert_in) : TARGET
|
||||
{
|
||||
return float4(image.Sample(def_sampler, vert_in.uv).rgb, 1.0);
|
||||
}
|
||||
|
||||
technique Draw
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vert_in);
|
||||
pixel_shader = PSDraw(vert_in);
|
||||
}
|
||||
}
|
|
@ -1662,3 +1662,64 @@ enum gs_index_type indexbuffer_gettype(indexbuffer_t indexbuffer)
|
|||
{
|
||||
return indexbuffer->type;
|
||||
}
|
||||
|
||||
extern "C" EXPORT bool gdi_texture_available(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" EXPORT texture_t device_create_gdi_texture(device_t device,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
gs_texture *texture = nullptr;
|
||||
try {
|
||||
texture = new gs_texture_2d(device, width, height, GS_BGRA,
|
||||
1, nullptr, GS_RENDERTARGET, GS_TEXTURE_2D,
|
||||
true, false);
|
||||
} catch (HRError error) {
|
||||
blog(LOG_ERROR, "device_create_gdi_texture (D3D11): %s (%08lX)",
|
||||
error.str, error.hr);
|
||||
} catch (const char *error) {
|
||||
blog(LOG_ERROR, "device_create_gdi_texture (D3D11): %s", error);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static inline bool TextureGDICompatible(gs_texture_2d *tex2d, const char *func)
|
||||
{
|
||||
if (!tex2d->isGDICompatible) {
|
||||
blog(LOG_ERROR, "%s (D3D11): Texture is not GDI compatible",
|
||||
func);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" EXPORT void *texture_get_dc(texture_t tex)
|
||||
{
|
||||
HDC hDC = nullptr;
|
||||
|
||||
if (tex->type != GS_TEXTURE_2D)
|
||||
return nullptr;
|
||||
|
||||
gs_texture_2d *tex2d = static_cast<gs_texture_2d*>(tex);
|
||||
if (!TextureGDICompatible(tex2d, "texture_get_dc"))
|
||||
return nullptr;
|
||||
|
||||
tex2d->gdiSurface->GetDC(true, &hDC);
|
||||
return hDC;
|
||||
}
|
||||
|
||||
extern "C" EXPORT void texture_release_dc(texture_t tex)
|
||||
{
|
||||
if (tex->type != GS_TEXTURE_2D)
|
||||
return;
|
||||
|
||||
gs_texture_2d *tex2d = static_cast<gs_texture_2d*>(tex);
|
||||
if (!TextureGDICompatible(tex2d, "texture_release_dc"))
|
||||
return;
|
||||
|
||||
tex2d->gdiSurface->ReleaseDC(nullptr);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,9 @@ void gs_texture_2d::InitTexture(const void **data)
|
|||
if (isRenderTarget || isGDICompatible)
|
||||
td.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
|
||||
if (isGDICompatible)
|
||||
td.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
|
||||
|
||||
if (data)
|
||||
InitSRD(srd, data);
|
||||
|
||||
|
@ -80,6 +83,13 @@ void gs_texture_2d::InitTexture(const void **data)
|
|||
texture.Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create 2D texture", hr);
|
||||
|
||||
if (isGDICompatible) {
|
||||
hr = texture->QueryInterface(__uuidof(IDXGISurface1),
|
||||
(void**)gdiSurface.Assign());
|
||||
if (FAILED(hr))
|
||||
throw HRError("Failed to create GDI surface", hr);
|
||||
}
|
||||
}
|
||||
|
||||
void gs_texture_2d::InitResourceView()
|
||||
|
|
|
@ -513,3 +513,8 @@ extern void gl_getclientsize(struct gs_swap_chain *swap,
|
|||
*width = rc.right;
|
||||
*height = rc.bottom;
|
||||
}
|
||||
|
||||
EXPORT bool gdi_texture_available(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ if(WIN32)
|
|||
util/threading-windows.c
|
||||
util/platform-windows.c)
|
||||
set(libobs_PLATFORM_DEPS
|
||||
w32-pthreads)
|
||||
w32-pthreads
|
||||
winmm.lib)
|
||||
elseif(APPLE)
|
||||
set(libobs_PLATFORM_SOURCES
|
||||
obs-cocoa.c
|
||||
|
|
|
@ -167,8 +167,17 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||
GRAPHICS_IMPORT(shader_setdefault);
|
||||
|
||||
/* OSX/Cocoa specific functions */
|
||||
#ifdef __APPLE__
|
||||
GRAPHICS_IMPORT_OPTIONAL(texture_create_from_iosurface);
|
||||
GRAPHICS_IMPORT_OPTIONAL(texture_rebind_iosurface);
|
||||
|
||||
/* win32 specific functions */
|
||||
#elif _WIN32
|
||||
GRAPHICS_IMPORT(gdi_texture_available);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_create_gdi_texture);
|
||||
GRAPHICS_IMPORT_OPTIONAL(texture_get_dc);
|
||||
GRAPHICS_IMPORT_OPTIONAL(texture_release_dc);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -202,9 +202,19 @@ struct gs_exports {
|
|||
size_t size);
|
||||
void (*shader_setdefault)(shader_t shader, sparam_t param);
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* OSX/Cocoa specific functions */
|
||||
texture_t (*texture_create_from_iosurface)(device_t dev, void *iosurf);
|
||||
bool (*texture_rebind_iosurface)(texture_t texture, void *iosurf);
|
||||
|
||||
#elif _WIN32
|
||||
bool (*gdi_texture_available)(void);
|
||||
texture_t (*device_create_gdi_texture)(device_t device,
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
void *(*texture_get_dc)(texture_t gdi_tex);
|
||||
void (*texture_release_dc)(texture_t gdi_tex);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct graphics_subsystem {
|
||||
|
|
|
@ -1894,6 +1894,8 @@ enum gs_index_type indexbuffer_gettype(indexbuffer_t indexbuffer)
|
|||
return thread_graphics->exports.indexbuffer_gettype(indexbuffer);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
/** Platform specific functions */
|
||||
texture_t gs_create_texture_from_iosurface(void *iosurf)
|
||||
{
|
||||
|
@ -1914,3 +1916,46 @@ bool texture_rebind_iosurface(texture_t texture, void *iosurf)
|
|||
|
||||
return graphics->exports.texture_rebind_iosurface(texture, iosurf);
|
||||
}
|
||||
|
||||
#elif _WIN32
|
||||
|
||||
bool gs_gdi_texture_available(void)
|
||||
{
|
||||
if (!thread_graphics)
|
||||
return false;
|
||||
|
||||
return thread_graphics->exports.gdi_texture_available();
|
||||
}
|
||||
|
||||
/** creates a windows GDI-lockable texture */
|
||||
texture_t gs_create_gdi_texture(uint32_t width, uint32_t height)
|
||||
{
|
||||
graphics_t graphics = thread_graphics;
|
||||
if (!graphics) return NULL;
|
||||
|
||||
if (graphics->exports.device_create_gdi_texture)
|
||||
return graphics->exports.device_create_gdi_texture(
|
||||
graphics->device, width, height);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *texture_get_dc(texture_t gdi_tex)
|
||||
{
|
||||
if (!thread_graphics || !gdi_tex)
|
||||
return NULL;
|
||||
|
||||
if (thread_graphics->exports.texture_get_dc)
|
||||
return thread_graphics->exports.texture_get_dc(gdi_tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void texture_release_dc(texture_t gdi_tex)
|
||||
{
|
||||
if (!thread_graphics || !gdi_tex)
|
||||
return;
|
||||
|
||||
if (thread_graphics->exports.texture_release_dc)
|
||||
thread_graphics->exports.texture_release_dc(gdi_tex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -677,11 +677,25 @@ EXPORT void *indexbuffer_getdata(indexbuffer_t indexbuffer);
|
|||
EXPORT size_t indexbuffer_numindices(indexbuffer_t indexbuffer);
|
||||
EXPORT enum gs_index_type indexbuffer_gettype(indexbuffer_t indexbuffer);
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
/** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures
|
||||
* from shared surface resources */
|
||||
EXPORT texture_t gs_create_texture_from_iosurface(void *iosurf);
|
||||
EXPORT bool texture_rebind_iosurface(texture_t texture, void *iosurf);
|
||||
|
||||
#elif _WIN32
|
||||
|
||||
EXPORT bool gs_gdi_texture_available(void);
|
||||
|
||||
/** creates a windows GDI-lockable texture */
|
||||
EXPORT texture_t gs_create_gdi_texture(uint32_t width, uint32_t height);
|
||||
|
||||
EXPORT void *texture_get_dc(texture_t gdi_tex);
|
||||
EXPORT void texture_release_dc(texture_t gdi_tex);
|
||||
|
||||
#endif
|
||||
|
||||
/* inline functions used by modules */
|
||||
|
||||
static inline uint32_t gs_get_format_bpp(enum gs_color_format format)
|
||||
|
|
|
@ -120,6 +120,8 @@ static inline void video_output_cur_frame(struct video_output *video)
|
|||
pthread_mutex_unlock(&video->input_mutex);
|
||||
}
|
||||
|
||||
static inline void nop() {int test = 0;}
|
||||
|
||||
static void *video_thread(void *param)
|
||||
{
|
||||
struct video_output *video = param;
|
||||
|
@ -127,12 +129,15 @@ static void *video_thread(void *param)
|
|||
|
||||
while (event_try(video->stop_event) == EAGAIN) {
|
||||
/* wait half a frame, update frame */
|
||||
os_sleepto_ns(cur_time += (video->frame_time/2));
|
||||
cur_time += (video->frame_time/2);
|
||||
os_sleepto_ns(cur_time);
|
||||
|
||||
video->cur_video_time = cur_time;
|
||||
event_signal(video->update_event);
|
||||
|
||||
/* wait another half a frame, swap and output frames */
|
||||
os_sleepto_ns(cur_time += (video->frame_time/2));
|
||||
cur_time += (video->frame_time/2);
|
||||
os_sleepto_ns(cur_time);
|
||||
|
||||
pthread_mutex_lock(&video->data_mutex);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
|
@ -95,7 +96,7 @@ bool os_sleepto_ns(uint64_t time_target)
|
|||
|
||||
milliseconds = (uint32_t)((time_target - t)/1000000);
|
||||
if (milliseconds > 1)
|
||||
os_sleep_ms(milliseconds);
|
||||
Sleep(milliseconds-1);
|
||||
|
||||
for (;;) {
|
||||
t = os_gettime_ns();
|
||||
|
@ -184,30 +185,38 @@ int os_mkdir(const char *path)
|
|||
return MKDIR_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst_dll, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
switch (reason) {
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
timeBeginPeriod(1);
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_process_attach_np();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
timeEndPeriod(1);
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_process_detach_np();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_thread_attach_np();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_thread_detach_np();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -194,7 +194,7 @@ void OBSApp::GetFPSCommon(uint32_t &num, uint32_t &den) const
|
|||
const char *val = config_get_string(globalConfig, "Video", "FPSCommon");
|
||||
|
||||
if (strcmp(val, "10") == 0) {
|
||||
num = 30;
|
||||
num = 10;
|
||||
den = 1;
|
||||
} else if (strcmp(val, "20") == 0) {
|
||||
num = 20;
|
||||
|
|
|
@ -71,6 +71,7 @@ void OBSBasic::OBSInit()
|
|||
obs_load_module("mac-capture");
|
||||
#elif _WIN32
|
||||
obs_load_module("win-wasapi");
|
||||
obs_load_module("win-capture");
|
||||
#endif
|
||||
|
||||
/* HACK: fixes a qt bug with native widgets with native repaint */
|
||||
|
|
|
@ -3,6 +3,7 @@ include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs")
|
|||
if(WIN32)
|
||||
add_subdirectory(dshow)
|
||||
add_subdirectory(win-wasapi)
|
||||
add_subdirectory(win-capture)
|
||||
elseif(APPLE)
|
||||
add_subdirectory(mac-capture)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
project(win-capture)
|
||||
|
||||
set(win-capture_HEADERS
|
||||
dc-capture.h)
|
||||
|
||||
set(win-capture_SOURCES
|
||||
dc-capture.c
|
||||
monitor-capture.c
|
||||
plugin-main.c)
|
||||
|
||||
add_library(win-capture MODULE
|
||||
${win-capture_SOURCES}
|
||||
${win-capture_HEADERS})
|
||||
target_link_libraries(win-capture
|
||||
libobs)
|
||||
|
||||
install_obs_plugin(win-capture)
|
||||
install_obs_plugin_data(win-capture ../../build/data/obs-plugins/win-capture)
|
|
@ -0,0 +1,239 @@
|
|||
#include "dc-capture.h"
|
||||
|
||||
#define WIN32_MEAN_AND_LEAN
|
||||
#include <windows.h>
|
||||
|
||||
static inline void init_textures(struct dc_capture *capture)
|
||||
{
|
||||
for (size_t i = 0; i < capture->num_textures; i++) {
|
||||
if (capture->compatibility)
|
||||
capture->textures[i] = gs_create_texture(
|
||||
capture->width, capture->height,
|
||||
GS_BGRA, 1, NULL, GS_DYNAMIC);
|
||||
else
|
||||
capture->textures[i] = gs_create_gdi_texture(
|
||||
capture->width, capture->height);
|
||||
|
||||
if (!capture->textures[i]) {
|
||||
blog(LOG_WARNING, "[dc_capture_init] Failed to "
|
||||
"create textures");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
capture->valid = true;
|
||||
}
|
||||
|
||||
void dc_capture_init(struct dc_capture *capture, int x, int y,
|
||||
uint32_t width, uint32_t height, bool cursor,
|
||||
bool compatibility)
|
||||
{
|
||||
capture->x = x;
|
||||
capture->y = y;
|
||||
capture->width = width;
|
||||
capture->height = height;
|
||||
capture->capture_cursor = cursor;
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
if (!gs_gdi_texture_available())
|
||||
compatibility = true;
|
||||
|
||||
capture->compatibility = compatibility;
|
||||
capture->num_textures = compatibility ? 1 : 2;
|
||||
|
||||
init_textures(capture);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
if (!capture->valid)
|
||||
return;
|
||||
|
||||
if (compatibility) {
|
||||
BITMAPINFO bi = {0};
|
||||
BITMAPINFOHEADER *bih = &bi.bmiHeader;
|
||||
bih->biSize = sizeof(BITMAPINFOHEADER);
|
||||
bih->biBitCount = 32;
|
||||
bih->biWidth = width;
|
||||
bih->biHeight = height;
|
||||
bih->biPlanes = 1;
|
||||
|
||||
capture->hdc = CreateCompatibleDC(NULL);
|
||||
capture->bmp = CreateDIBSection(capture->hdc, &bi,
|
||||
DIB_RGB_COLORS, (void**)&capture->bits,
|
||||
NULL, 0);
|
||||
capture->old_bmp = SelectObject(capture->hdc, capture->bmp);
|
||||
}
|
||||
}
|
||||
|
||||
void dc_capture_free(struct dc_capture *capture)
|
||||
{
|
||||
if (capture->hdc) {
|
||||
SelectObject(capture->hdc, capture->old_bmp);
|
||||
DeleteDC(capture->hdc);
|
||||
DeleteObject(capture->bmp);
|
||||
}
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
for (size_t i = 0; i < capture->num_textures; i++)
|
||||
texture_destroy(capture->textures[i]);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
memset(capture, 0, sizeof(struct dc_capture));
|
||||
}
|
||||
|
||||
static void draw_cursor(struct dc_capture *capture, HDC hdc)
|
||||
{
|
||||
HICON icon;
|
||||
ICONINFO ii;
|
||||
CURSORINFO *ci = &capture->ci;
|
||||
|
||||
if (!(capture->ci.flags & CURSOR_SHOWING))
|
||||
return;
|
||||
|
||||
icon = CopyIcon(capture->ci.hCursor);
|
||||
if (!icon)
|
||||
return;
|
||||
|
||||
if (GetIconInfo(icon, &ii)) {
|
||||
POINT pos;
|
||||
pos.x = ci->ptScreenPos.x - (int)ii.xHotspot - capture->x;
|
||||
pos.y = ci->ptScreenPos.y - (int)ii.yHotspot - capture->y;
|
||||
|
||||
DrawIcon(hdc, pos.x, pos.y, icon);
|
||||
|
||||
DeleteObject(ii.hbmColor);
|
||||
DeleteObject(ii.hbmMask);
|
||||
}
|
||||
|
||||
DestroyIcon(icon);
|
||||
}
|
||||
|
||||
static inline HDC dc_capture_get_dc(struct dc_capture *capture)
|
||||
{
|
||||
if (!capture->valid)
|
||||
return NULL;
|
||||
|
||||
if (capture->compatibility)
|
||||
return capture->hdc;
|
||||
else
|
||||
return texture_get_dc(capture->textures[capture->cur_tex]);
|
||||
}
|
||||
|
||||
static inline void dc_capture_release_dc(struct dc_capture *capture)
|
||||
{
|
||||
if (capture->compatibility) {
|
||||
texture_setimage(capture->textures[capture->cur_tex],
|
||||
capture->bits, capture->width*4, false);
|
||||
} else {
|
||||
texture_release_dc(capture->textures[capture->cur_tex]);
|
||||
}
|
||||
}
|
||||
|
||||
void dc_capture_capture(struct dc_capture *capture, HWND window)
|
||||
{
|
||||
HDC hdc_target;
|
||||
HDC hdc;
|
||||
|
||||
if (capture->capture_cursor) {
|
||||
memset(&capture->ci, 0, sizeof(CURSORINFO));
|
||||
capture->ci.cbSize = sizeof(CURSORINFO);
|
||||
capture->cursor_captured = GetCursorInfo(&capture->ci);
|
||||
}
|
||||
|
||||
if (++capture->cur_tex == capture->num_textures)
|
||||
capture->cur_tex = 0;
|
||||
|
||||
hdc = dc_capture_get_dc(capture);
|
||||
if (!hdc) {
|
||||
blog(LOG_WARNING, "[capture_screen] Failed to get "
|
||||
"texture DC");
|
||||
return;
|
||||
}
|
||||
|
||||
hdc_target = GetDC(window);
|
||||
|
||||
BitBlt(hdc, 0, 0, capture->width, capture->height,
|
||||
hdc_target, capture->x, capture->y, SRCCOPY);
|
||||
|
||||
ReleaseDC(NULL, hdc_target);
|
||||
|
||||
if (capture->cursor_captured)
|
||||
draw_cursor(capture, hdc);
|
||||
|
||||
dc_capture_release_dc(capture);
|
||||
|
||||
capture->textures_written[capture->cur_tex] = true;
|
||||
}
|
||||
|
||||
static void draw_texture(struct dc_capture *capture, int id, effect_t effect)
|
||||
{
|
||||
texture_t texture = capture->textures[id];
|
||||
technique_t tech = effect_gettechnique(effect, "Draw");
|
||||
eparam_t image = effect_getparambyname(effect, "image");
|
||||
size_t passes;
|
||||
|
||||
effect_settexture(effect, image, texture);
|
||||
|
||||
passes = technique_begin(tech);
|
||||
for (size_t i = 0; i < passes; i++) {
|
||||
if (technique_beginpass(tech, i)) {
|
||||
if (capture->compatibility)
|
||||
gs_draw_sprite(texture, GS_FLIP_V, 0, 0);
|
||||
else
|
||||
gs_draw_sprite(texture, 0, 0, 0);
|
||||
|
||||
technique_endpass(tech);
|
||||
}
|
||||
}
|
||||
technique_end(tech);
|
||||
}
|
||||
|
||||
void dc_capture_render(struct dc_capture *capture, effect_t effect)
|
||||
{
|
||||
int last_tex = (capture->cur_tex > 0) ?
|
||||
capture->cur_tex-1 : capture->num_textures-1;
|
||||
|
||||
if (!capture->valid)
|
||||
return;
|
||||
|
||||
if (capture->textures_written[last_tex])
|
||||
draw_texture(capture, last_tex, effect);
|
||||
}
|
||||
|
||||
effect_t create_opaque_effect(void)
|
||||
{
|
||||
effect_t opaque_effect;
|
||||
char *effect_file;
|
||||
char *error_string = NULL;
|
||||
|
||||
effect_file = obs_find_plugin_file("win-capture/opaque.effect");
|
||||
if (!effect_file) {
|
||||
blog(LOG_ERROR, "[create_opaque_effect] Could not find "
|
||||
"opaque effect file");
|
||||
return false;
|
||||
}
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
opaque_effect = gs_create_effect_from_file(effect_file, &error_string);
|
||||
|
||||
if (!opaque_effect) {
|
||||
if (error_string)
|
||||
blog(LOG_ERROR, "[create_opaque_effect] Failed to "
|
||||
"create opaque effect:\n%s",
|
||||
error_string);
|
||||
else
|
||||
blog(LOG_ERROR, "[create_opaque_effect] Failed to "
|
||||
"create opaque effect");
|
||||
}
|
||||
|
||||
bfree(effect_file);
|
||||
bfree(error_string);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
return opaque_effect;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <obs.h>
|
||||
|
||||
#define NUM_TEXTURES 2
|
||||
|
||||
struct dc_capture {
|
||||
int cur_tex;
|
||||
texture_t textures[NUM_TEXTURES];
|
||||
bool textures_written[NUM_TEXTURES];
|
||||
int x, y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
int num_textures;
|
||||
|
||||
bool compatibility;
|
||||
HDC hdc;
|
||||
HBITMAP bmp, old_bmp;
|
||||
BYTE *bits;
|
||||
|
||||
bool capture_cursor;
|
||||
bool cursor_captured;
|
||||
CURSORINFO ci;
|
||||
|
||||
bool valid;
|
||||
};
|
||||
|
||||
extern void dc_capture_init(struct dc_capture *capture, int x, int y,
|
||||
uint32_t width, uint32_t height, bool cursor,
|
||||
bool compatibility);
|
||||
extern void dc_capture_free(struct dc_capture *capture);
|
||||
|
||||
extern void dc_capture_capture(struct dc_capture *capture, HWND window);
|
||||
extern void dc_capture_render(struct dc_capture *capture, effect_t effect);
|
||||
|
||||
extern effect_t create_opaque_effect(void);
|
|
@ -0,0 +1,147 @@
|
|||
#include <util/dstr.h>
|
||||
#include "dc-capture.h"
|
||||
|
||||
struct monitor_capture {
|
||||
obs_source_t source;
|
||||
|
||||
int monitor;
|
||||
bool capture_cursor;
|
||||
bool compatibility;
|
||||
|
||||
struct dc_capture data;
|
||||
|
||||
effect_t opaque_effect;
|
||||
};
|
||||
|
||||
struct monitor_info {
|
||||
int cur_id;
|
||||
int desired_id;
|
||||
int id;
|
||||
RECT rect;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static inline void do_log(int level, const char *msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
struct dstr str = {0};
|
||||
|
||||
va_start(args, msg);
|
||||
|
||||
dstr_copy(&str, "[GDI monitor capture]: ");
|
||||
dstr_vcatf(&str, msg, args);
|
||||
blog(level, "%s", str.array);
|
||||
dstr_free(&str);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enum_monitor(HMONITOR handle, HDC hdc, LPRECT rect,
|
||||
LPARAM param)
|
||||
{
|
||||
struct monitor_info *monitor = (struct monitor_info *)param;
|
||||
|
||||
if (monitor->cur_id == 0 || monitor->desired_id == monitor->cur_id) {
|
||||
monitor->rect = *rect;
|
||||
monitor->id = monitor->cur_id;
|
||||
}
|
||||
|
||||
return (monitor->desired_id < monitor->cur_id++);
|
||||
}
|
||||
|
||||
static void update_monitor(struct monitor_capture *capture,
|
||||
obs_data_t settings)
|
||||
{
|
||||
struct monitor_info monitor = {0};
|
||||
uint32_t width, height;
|
||||
|
||||
monitor.desired_id = (int)obs_data_getint(settings, "monitor");
|
||||
EnumDisplayMonitors(NULL, NULL, enum_monitor, (LPARAM)&monitor);
|
||||
|
||||
capture->monitor = monitor.id;
|
||||
|
||||
width = monitor.rect.right - monitor.rect.left;
|
||||
height = monitor.rect.bottom - monitor.rect.top;
|
||||
|
||||
dc_capture_init(&capture->data, monitor.rect.left, monitor.rect.top,
|
||||
width, height, capture->capture_cursor,
|
||||
capture->compatibility);
|
||||
}
|
||||
|
||||
static inline void update_settings(struct monitor_capture *capture,
|
||||
obs_data_t settings)
|
||||
{
|
||||
capture->capture_cursor = obs_data_getbool(settings, "capture_cursor");
|
||||
capture->compatibility = obs_data_getbool(settings, "compatibility");
|
||||
|
||||
dc_capture_free(&capture->data);
|
||||
update_monitor(capture, settings);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static const char *monitor_capture_getname(const char *locale)
|
||||
{
|
||||
/* TODO: translate */
|
||||
return "Monitor Capture";
|
||||
}
|
||||
|
||||
static void monitor_capture_destroy(void *data)
|
||||
{
|
||||
struct monitor_capture *capture = data;
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
dc_capture_free(&capture->data);
|
||||
effect_destroy(capture->opaque_effect);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
bfree(capture);
|
||||
}
|
||||
|
||||
static void *monitor_capture_create(obs_data_t settings, obs_source_t source)
|
||||
{
|
||||
struct monitor_capture *capture;
|
||||
effect_t opaque_effect = create_opaque_effect();
|
||||
|
||||
if (!opaque_effect)
|
||||
return NULL;
|
||||
|
||||
capture = bzalloc(sizeof(struct monitor_capture));
|
||||
capture->opaque_effect = opaque_effect;
|
||||
|
||||
obs_data_set_default_int(settings, "monitor", 0);
|
||||
obs_data_set_default_bool(settings, "capture_cursor", true);
|
||||
obs_data_set_default_bool(settings, "compatibility", false);
|
||||
update_settings(capture, settings);
|
||||
|
||||
return capture;
|
||||
}
|
||||
|
||||
static void monitor_capture_tick(void *data, float seconds)
|
||||
{
|
||||
struct monitor_capture *capture = data;
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
dc_capture_capture(&capture->data, NULL);
|
||||
gs_leavecontext();
|
||||
}
|
||||
|
||||
static void monitor_capture_render(void *data, effect_t effect)
|
||||
{
|
||||
struct monitor_capture *capture = data;
|
||||
dc_capture_render(&capture->data, capture->opaque_effect);
|
||||
}
|
||||
|
||||
struct obs_source_info monitor_capture_info = {
|
||||
.id = "monitor_capture",
|
||||
.type = OBS_SOURCE_TYPE_INPUT,
|
||||
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW,
|
||||
.getname = monitor_capture_getname,
|
||||
.create = monitor_capture_create,
|
||||
.destroy = monitor_capture_destroy,
|
||||
.video_render = monitor_capture_render,
|
||||
.video_tick = monitor_capture_tick
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
#include <obs-module.h>
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
|
||||
extern struct obs_source_info monitor_capture_info;
|
||||
|
||||
bool obs_module_load(uint32_t libobs_ver)
|
||||
{
|
||||
obs_register_source(&monitor_capture_info);
|
||||
|
||||
UNUSED_PARAMETER(libobs_ver);
|
||||
return true;
|
||||
}
|
|
@ -41,6 +41,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "obs-studio", "obs-studio\ob
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win-wasapi", "win-wasapi\win-wasapi.vcxproj", "{A3D24C9D-669D-4DDF-91BA-152D7DDD7C04}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win-capture", "win-capture\win-capture.vcxproj", "{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -129,6 +131,14 @@ Global
|
|||
{A3D24C9D-669D-4DDF-91BA-152D7DDD7C04}.Release|Win32.Build.0 = Release|Win32
|
||||
{A3D24C9D-669D-4DDF-91BA-152D7DDD7C04}.Release|x64.ActiveCfg = Release|x64
|
||||
{A3D24C9D-669D-4DDF-91BA-152D7DDD7C04}.Release|x64.Build.0 = Release|x64
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Debug|x64.Build.0 = Debug|x64
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Release|Win32.Build.0 = Release|Win32
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Release|x64.ActiveCfg = Release|x64
|
||||
{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>winmm.lib;avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
|
@ -228,7 +228,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>winmm.lib;avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
|
@ -253,7 +253,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>winmm.lib;avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
|
@ -278,7 +278,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>winmm.lib;avutil.lib;swresample.lib;swscale.lib;pthreads.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{AB83E5F0-D76E-45AB-A4C9-4711B1BE6916}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>wincapture</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WINCAPTURE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/obs-plugins/32bit/$(TargetName)$(TargetExt)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WINCAPTURE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/obs-plugins/64bit/$(TargetName)$(TargetExt)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WINCAPTURE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/obs-plugins/32bit/$(TargetName)$(TargetExt)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WINCAPTURE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../../libobs</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libobs.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy "$(OutDir)$(TargetName)$(TargetExt)" "../../../build/obs-plugins/64bit/$(TargetName)$(TargetExt)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\plugins\win-capture\dc-capture.c" />
|
||||
<ClCompile Include="..\..\..\plugins\win-capture\monitor-capture.c" />
|
||||
<ClCompile Include="..\..\..\plugins\win-capture\plugin-main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\plugins\win-capture\dc-capture.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\plugins\win-capture\monitor-capture.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\plugins\win-capture\plugin-main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\plugins\win-capture\dc-capture.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\plugins\win-capture\dc-capture.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue