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
jp9000 2014-03-05 10:43:14 -07:00
parent 3415960d02
commit 4f7ab552df
23 changed files with 892 additions and 11 deletions

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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()

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 {

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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()

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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
};

View File

@ -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;
}

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>