obs-studio/test/osx/test.mm
Palana 44b5afbd07 (API Change) libobs: Add profile_name_store_t parameter to obs_startup
Due to all the threads in libobs it wouldn't be safe to make that
parameter reconfigurable after libobs is initialized without adding
even more synchronization. On the other hand, adding a function to set
the name store before calling obs_startup would solve the problem of
passing a name store into libobs, but it can lead to more complicated
semantics for obs_get_profiler_name_store (e.g., should it always return
the current name store even if libobs isn't initialized until someone
calls set_name_store(NULL)? should obs_shutdown call
set_name_store(NULL)? Passing it as obs_startup parameter avoids
these (and hopefully other) potential misunderstandings
2015-08-12 15:30:29 +02:00

193 lines
4.4 KiB
Plaintext

#include <stdio.h>
#include <time.h>
#include <functional>
#include <memory>
#import <Cocoa/Cocoa.h>
#import <AppKit/AppKit.h>
#import <OpenGL/OpenGL.h>
#include <util/base.h>
#include <obs.h>
static const int cx = 800;
static const int cy = 600;
/* --------------------------------------------------- */
template <typename T, typename D_T, D_T D>
struct OBSUniqueHandle : std::unique_ptr<T, std::function<D_T>>
{
using base = std::unique_ptr<T, std::function<D_T>>;
explicit OBSUniqueHandle(T *obj=nullptr) : base(obj, D) {}
operator T*() { return base::get(); }
};
#define DECLARE_DELETER(x) decltype(x), x
using SourceContext = OBSUniqueHandle<obs_source,
DECLARE_DELETER(obs_source_release)>;
using SceneContext = OBSUniqueHandle<obs_scene,
DECLARE_DELETER(obs_scene_release)>;
using DisplayContext = OBSUniqueHandle<obs_display,
DECLARE_DELETER(obs_display_destroy)>;
#undef DECLARE_DELETER
/* --------------------------------------------------- */
static void CreateOBS()
{
if (!obs_startup("en", nullptr))
throw "Couldn't create OBS";
struct obs_video_info ovi;
ovi.adapter = 0;
ovi.fps_num = 30000;
ovi.fps_den = 1001;
ovi.graphics_module = DL_OPENGL;
ovi.output_format = VIDEO_FORMAT_RGBA;
ovi.base_width = cx;
ovi.base_height = cy;
ovi.output_width = cx;
ovi.output_height = cy;
if (obs_reset_video(&ovi) != 0)
throw "Couldn't initialize video";
}
static DisplayContext CreateDisplay(NSView *view)
{
gs_init_data info = {};
info.cx = cx;
info.cy = cy;
info.format = GS_RGBA;
info.zsformat = GS_ZS_NONE;
info.window.view = view;
return DisplayContext{obs_display_create(&info)};
}
static SceneContext SetupScene()
{
/* ------------------------------------------------------ */
/* load modules */
obs_load_all_modules();
/* ------------------------------------------------------ */
/* create source */
SourceContext source{obs_source_create(OBS_SOURCE_TYPE_INPUT,
"random", "a test source", nullptr, nullptr)};
if (!source)
throw "Couldn't create random test source";
/* ------------------------------------------------------ */
/* create scene and add source to scene */
SceneContext scene{obs_scene_create("test scene")};
if (!scene)
throw "Couldn't create scene";
obs_scene_add(scene, source);
/* ------------------------------------------------------ */
/* set the scene as the primary draw source and go */
obs_set_output_source(0, obs_scene_get_source(scene));
return scene;
}
@interface OBSTest : NSObject<NSApplicationDelegate, NSWindowDelegate>
{
NSWindow *win;
NSView *view;
DisplayContext display;
SceneContext scene;
}
- (void)applicationDidFinishLaunching:(NSNotification*)notification;
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)app;
- (void)windowWillClose:(NSNotification*)notification;
@end
@implementation OBSTest
- (void)applicationDidFinishLaunching:(NSNotification*)notification
{
UNUSED_PARAMETER(notification);
try {
NSRect content_rect = NSMakeRect(0, 0, cx, cy);
win = [[NSWindow alloc]
initWithContentRect:content_rect
styleMask:NSTitledWindowMask | NSClosableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if (!win)
throw "Could not create window";
view = [[NSView alloc] initWithFrame:content_rect];
if (!view)
throw "Could not create view";
CreateOBS();
win.title = @"foo";
win.delegate = self;
win.contentView = view;
[win orderFrontRegardless];
[win center];
[win makeMainWindow];
display = CreateDisplay(view);
scene = SetupScene();
obs_display_add_draw_callback(display.get(),
[](void *, uint32_t, uint32_t) {
obs_render_main_view();
}, nullptr);
} catch (char const *error) {
NSLog(@"%s\n", error);
[NSApp terminate:nil];
}
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)app
{
UNUSED_PARAMETER(app);
return YES;
}
- (void)windowWillClose:(NSNotification*)notification
{
UNUSED_PARAMETER(notification);
obs_set_output_source(0, nullptr);
scene.reset();
display.reset();
obs_shutdown();
NSLog(@"Number of memory leaks: %lu", bnum_allocs());
}
@end
/* --------------------------------------------------- */
int main()
{
@autoreleasepool {
NSApplication *app = [NSApplication sharedApplication];
OBSTest *test = [[OBSTest alloc] init];
app.delegate = test;
[app run];
}
return 0;
}