multitrack-video.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright (c) 2024 Ruwen Hahn <[email protected]>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #pragma once
  17. #include <string>
  18. #include <optional>
  19. #include <obs.h>
  20. #include <nlohmann/json.hpp>
  21. /*
  22. * Support for (de-)serialising std::optional
  23. * From https://github.com/nlohmann/json/issues/1749#issuecomment-1731266676
  24. * whatsnew.hpp's version doesn't seem to work here
  25. */
  26. template<typename T> struct nlohmann::adl_serializer<std::optional<T>> {
  27. static void from_json(const json &j, std::optional<T> &opt)
  28. {
  29. if (j.is_null()) {
  30. opt = std::nullopt;
  31. } else {
  32. opt = j.get<T>();
  33. }
  34. }
  35. static void to_json(json &json, std::optional<T> t)
  36. {
  37. if (t) {
  38. json = *t;
  39. } else {
  40. json = nullptr;
  41. }
  42. }
  43. };
  44. NLOHMANN_JSON_SERIALIZE_ENUM(obs_scale_type,
  45. {
  46. {OBS_SCALE_DISABLE, "OBS_SCALE_DISABLE"},
  47. {OBS_SCALE_POINT, "OBS_SCALE_POINT"},
  48. {OBS_SCALE_BICUBIC, "OBS_SCALE_BICUBIC"},
  49. {OBS_SCALE_BILINEAR, "OBS_SCALE_BILINEAR"},
  50. {OBS_SCALE_LANCZOS, "OBS_SCALE_LANCZOS"},
  51. {OBS_SCALE_AREA, "OBS_SCALE_AREA"},
  52. })
  53. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(media_frames_per_second, numerator,
  54. denominator)
  55. namespace GoLiveApi {
  56. using std::string;
  57. using std::optional;
  58. using json = nlohmann::json;
  59. struct Client {
  60. string name = "obs-studio";
  61. string version;
  62. std::vector<string> supported_codecs;
  63. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Client, name, version, supported_codecs)
  64. };
  65. struct Cpu {
  66. int32_t physical_cores;
  67. int32_t logical_cores;
  68. optional<uint32_t> speed;
  69. optional<string> name;
  70. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Cpu, physical_cores, logical_cores,
  71. speed, name)
  72. };
  73. struct Memory {
  74. uint64_t total;
  75. uint64_t free;
  76. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Memory, total, free)
  77. };
  78. struct Gpu {
  79. string model;
  80. uint32_t vendor_id;
  81. uint32_t device_id;
  82. uint64_t dedicated_video_memory;
  83. uint64_t shared_system_memory;
  84. optional<string> driver_version;
  85. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Gpu, model, vendor_id, device_id,
  86. dedicated_video_memory,
  87. shared_system_memory, driver_version)
  88. };
  89. struct GamingFeatures {
  90. optional<bool> game_bar_enabled;
  91. optional<bool> game_dvr_allowed;
  92. optional<bool> game_dvr_enabled;
  93. optional<bool> game_dvr_bg_recording;
  94. optional<bool> game_mode_enabled;
  95. optional<bool> hags_enabled;
  96. NLOHMANN_DEFINE_TYPE_INTRUSIVE(GamingFeatures, game_bar_enabled,
  97. game_dvr_allowed, game_dvr_enabled,
  98. game_dvr_bg_recording, game_mode_enabled,
  99. hags_enabled)
  100. };
  101. struct System {
  102. string version;
  103. string name;
  104. int build;
  105. string release;
  106. int revision;
  107. int bits;
  108. bool arm;
  109. bool armEmulation;
  110. NLOHMANN_DEFINE_TYPE_INTRUSIVE(System, version, name, build, release,
  111. revision, bits, arm, armEmulation)
  112. };
  113. struct Capabilities {
  114. Cpu cpu;
  115. Memory memory;
  116. optional<GamingFeatures> gaming_features;
  117. System system;
  118. optional<std::vector<Gpu>> gpu;
  119. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Capabilities, cpu, memory,
  120. gaming_features, system, gpu)
  121. };
  122. struct Preferences {
  123. optional<uint64_t> maximum_aggregate_bitrate;
  124. optional<uint32_t> maximum_video_tracks;
  125. bool vod_track_audio;
  126. uint32_t width;
  127. uint32_t height;
  128. media_frames_per_second framerate;
  129. uint32_t canvas_width;
  130. uint32_t canvas_height;
  131. optional<uint32_t> composition_gpu_index;
  132. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Preferences, maximum_aggregate_bitrate,
  133. maximum_video_tracks, vod_track_audio,
  134. width, height, framerate, canvas_width,
  135. canvas_height, composition_gpu_index)
  136. };
  137. struct PostData {
  138. string service;
  139. string schema_version;
  140. string authentication;
  141. Client client;
  142. Capabilities capabilities;
  143. Preferences preferences;
  144. NLOHMANN_DEFINE_TYPE_INTRUSIVE(PostData, service, schema_version,
  145. authentication, client, capabilities,
  146. preferences)
  147. };
  148. // Config Response
  149. struct Meta {
  150. string service;
  151. string schema_version;
  152. string config_id;
  153. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Meta, service, schema_version, config_id)
  154. };
  155. enum struct StatusResult {
  156. Unknown,
  157. Success,
  158. Warning,
  159. Error,
  160. };
  161. NLOHMANN_JSON_SERIALIZE_ENUM(StatusResult,
  162. {
  163. {StatusResult::Unknown, nullptr},
  164. {StatusResult::Success, "success"},
  165. {StatusResult::Warning, "warning"},
  166. {StatusResult::Error, "error"},
  167. })
  168. struct Status {
  169. StatusResult result = StatusResult::Unknown;
  170. optional<string> html_en_us;
  171. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Status, result, html_en_us)
  172. };
  173. struct IngestEndpoint {
  174. string protocol;
  175. string url_template;
  176. optional<string> authentication;
  177. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(IngestEndpoint, protocol,
  178. url_template,
  179. authentication)
  180. };
  181. struct VideoEncoderConfiguration {
  182. string type;
  183. uint32_t width;
  184. uint32_t height;
  185. optional<media_frames_per_second> framerate;
  186. optional<obs_scale_type> gpu_scale_type;
  187. json settings;
  188. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(VideoEncoderConfiguration,
  189. type, width, height,
  190. framerate, gpu_scale_type,
  191. settings)
  192. };
  193. struct AudioEncoderConfiguration {
  194. string codec;
  195. uint32_t track_id;
  196. uint32_t channels;
  197. json settings;
  198. NLOHMANN_DEFINE_TYPE_INTRUSIVE(AudioEncoderConfiguration, codec,
  199. track_id, channels, settings)
  200. };
  201. struct AudioConfigurations {
  202. std::vector<AudioEncoderConfiguration> live;
  203. optional<std::vector<AudioEncoderConfiguration>> vod;
  204. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(AudioConfigurations, live,
  205. vod)
  206. };
  207. struct Config {
  208. Meta meta;
  209. optional<Status> status;
  210. std::vector<IngestEndpoint> ingest_endpoints;
  211. std::vector<VideoEncoderConfiguration> encoder_configurations;
  212. AudioConfigurations audio_configurations;
  213. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, meta, status,
  214. ingest_endpoints,
  215. encoder_configurations,
  216. audio_configurations)
  217. };
  218. } // namespace GoLiveApi