test.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <windows.h>
  4. #include <util/base.h>
  5. #include <graphics/vec2.h>
  6. #include <media-io/audio-resampler.h>
  7. #include <obs.h>
  8. #include <intrin.h>
  9. static const int cx = 800;
  10. static const int cy = 600;
  11. /* --------------------------------------------------- */
  12. class SourceContext {
  13. obs_source_t *source;
  14. public:
  15. inline SourceContext(obs_source_t *source) : source(source) {}
  16. inline ~SourceContext() { obs_source_release(source); }
  17. inline operator obs_source_t *() { return source; }
  18. };
  19. /* --------------------------------------------------- */
  20. class SceneContext {
  21. obs_scene_t *scene;
  22. public:
  23. inline SceneContext(obs_scene_t *scene) : scene(scene) {}
  24. inline ~SceneContext() { obs_scene_release(scene); }
  25. inline operator obs_scene_t *() { return scene; }
  26. };
  27. /* --------------------------------------------------- */
  28. class DisplayContext {
  29. obs_display_t *display;
  30. public:
  31. inline DisplayContext(obs_display_t *display) : display(display) {}
  32. inline ~DisplayContext() { obs_display_destroy(display); }
  33. inline operator obs_display_t *() { return display; }
  34. };
  35. /* --------------------------------------------------- */
  36. static LRESULT CALLBACK sceneProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  37. {
  38. switch (message) {
  39. case WM_CLOSE:
  40. PostQuitMessage(0);
  41. break;
  42. default:
  43. return DefWindowProc(hwnd, message, wParam, lParam);
  44. }
  45. return 0;
  46. }
  47. static void do_log(int log_level, const char *msg, va_list args, void *param)
  48. {
  49. char bla[4096];
  50. vsnprintf(bla, 4095, msg, args);
  51. OutputDebugStringA(bla);
  52. OutputDebugStringA("\n");
  53. if (log_level < LOG_WARNING)
  54. __debugbreak();
  55. UNUSED_PARAMETER(param);
  56. }
  57. static void CreateOBS(HWND hwnd)
  58. {
  59. RECT rc;
  60. GetClientRect(hwnd, &rc);
  61. if (!obs_startup("en-US", nullptr, nullptr))
  62. throw "Couldn't create OBS";
  63. struct obs_video_info ovi;
  64. ovi.adapter = 0;
  65. ovi.base_width = rc.right;
  66. ovi.base_height = rc.bottom;
  67. ovi.fps_num = 30000;
  68. ovi.fps_den = 1001;
  69. ovi.graphics_module = DL_OPENGL;
  70. ovi.output_format = VIDEO_FORMAT_RGBA;
  71. ovi.output_width = rc.right;
  72. ovi.output_height = rc.bottom;
  73. if (obs_reset_video(&ovi) != 0)
  74. throw "Couldn't initialize video";
  75. }
  76. static DisplayContext CreateDisplay(HWND hwnd)
  77. {
  78. RECT rc;
  79. GetClientRect(hwnd, &rc);
  80. gs_init_data info = {};
  81. info.cx = rc.right;
  82. info.cy = rc.bottom;
  83. info.format = GS_RGBA;
  84. info.zsformat = GS_ZS_NONE;
  85. info.window.hwnd = hwnd;
  86. return obs_display_create(&info, 0);
  87. }
  88. static void AddTestItems(obs_scene_t *scene, obs_source_t *source)
  89. {
  90. obs_sceneitem_t *item = NULL;
  91. struct vec2 scale;
  92. vec2_set(&scale, 20.0f, 20.0f);
  93. item = obs_scene_add(scene, source);
  94. obs_sceneitem_set_scale(item, &scale);
  95. }
  96. static HWND CreateTestWindow(HINSTANCE instance)
  97. {
  98. WNDCLASS wc;
  99. memset(&wc, 0, sizeof(wc));
  100. wc.lpszClassName = TEXT("bla");
  101. wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  102. wc.hInstance = instance;
  103. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  104. wc.lpfnWndProc = (WNDPROC)sceneProc;
  105. if (!RegisterClass(&wc))
  106. return 0;
  107. return CreateWindow(TEXT("bla"), TEXT("bla"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 1920 / 2 - cx / 2,
  108. 1080 / 2 - cy / 2, cx, cy, NULL, NULL, instance, NULL);
  109. }
  110. /* --------------------------------------------------- */
  111. static void RenderWindow(void *data, uint32_t cx, uint32_t cy)
  112. {
  113. obs_render_main_texture();
  114. UNUSED_PARAMETER(data);
  115. UNUSED_PARAMETER(cx);
  116. UNUSED_PARAMETER(cy);
  117. }
  118. /* --------------------------------------------------- */
  119. int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int numCmd)
  120. {
  121. HWND hwnd = NULL;
  122. base_set_log_handler(do_log, nullptr);
  123. try {
  124. hwnd = CreateTestWindow(instance);
  125. if (!hwnd)
  126. throw "Couldn't create main window";
  127. /* ------------------------------------------------------ */
  128. /* create OBS */
  129. CreateOBS(hwnd);
  130. /* ------------------------------------------------------ */
  131. /* load modules */
  132. obs_load_all_modules();
  133. /* ------------------------------------------------------ */
  134. /* create source */
  135. SourceContext source = obs_source_create("random", "some randon source", NULL, nullptr);
  136. if (!source)
  137. throw "Couldn't create random test source";
  138. /* ------------------------------------------------------ */
  139. /* create filter */
  140. SourceContext filter = obs_source_create("test_filter", "a nice green filter", NULL, nullptr);
  141. if (!filter)
  142. throw "Couldn't create test filter";
  143. obs_source_filter_add(source, filter);
  144. /* ------------------------------------------------------ */
  145. /* create scene and add source to scene (twice) */
  146. SceneContext scene = obs_scene_create("test scene");
  147. if (!scene)
  148. throw "Couldn't create scene";
  149. AddTestItems(scene, source);
  150. /* ------------------------------------------------------ */
  151. /* set the scene as the primary draw source and go */
  152. obs_set_output_source(0, obs_scene_get_source(scene));
  153. /* ------------------------------------------------------ */
  154. /* create display for output and set the output render callback */
  155. DisplayContext display = CreateDisplay(hwnd);
  156. obs_display_add_draw_callback(display, RenderWindow, nullptr);
  157. MSG msg;
  158. while (GetMessage(&msg, NULL, 0, 0)) {
  159. TranslateMessage(&msg);
  160. DispatchMessage(&msg);
  161. }
  162. } catch (char *error) {
  163. MessageBoxA(NULL, error, NULL, 0);
  164. }
  165. obs_shutdown();
  166. blog(LOG_INFO, "Number of memory leaks: %ld", bnum_allocs());
  167. DestroyWindow(hwnd);
  168. UNUSED_PARAMETER(prevInstance);
  169. UNUSED_PARAMETER(cmdLine);
  170. UNUSED_PARAMETER(numCmd);
  171. return 0;
  172. }