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

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