multitrack-video.hpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. {OBS_SCALE_DISABLE, "OBS_SCALE_DISABLE"},
  46. {OBS_SCALE_POINT, "OBS_SCALE_POINT"},
  47. {OBS_SCALE_BICUBIC, "OBS_SCALE_BICUBIC"},
  48. {OBS_SCALE_BILINEAR, "OBS_SCALE_BILINEAR"},
  49. {OBS_SCALE_LANCZOS, "OBS_SCALE_LANCZOS"},
  50. {OBS_SCALE_AREA, "OBS_SCALE_AREA"},
  51. })
  52. NLOHMANN_JSON_SERIALIZE_ENUM(video_colorspace, {
  53. {VIDEO_CS_DEFAULT, "VIDEO_CS_DEFAULT"},
  54. {VIDEO_CS_601, "VIDEO_CS_601"},
  55. {VIDEO_CS_709, "VIDEO_CS_709"},
  56. {VIDEO_CS_SRGB, "VIDEO_CS_SRGB"},
  57. {VIDEO_CS_2100_PQ, "VIDEO_CS_2100_PQ"},
  58. {VIDEO_CS_2100_HLG, "VIDEO_CS_2100_HLG"},
  59. })
  60. /* This only includes output formats selectable in advanced settings. */
  61. NLOHMANN_JSON_SERIALIZE_ENUM(video_format, {
  62. {VIDEO_FORMAT_NONE, "VIDEO_FORMAT_NONE"},
  63. {VIDEO_FORMAT_I420, "VIDEO_FORMAT_I420"},
  64. {VIDEO_FORMAT_NV12, "VIDEO_FORMAT_NV12"},
  65. {VIDEO_FORMAT_BGRA, "VIDEO_FORMAT_BGRA"},
  66. {VIDEO_FORMAT_I444, "VIDEO_FORMAT_I444"},
  67. {VIDEO_FORMAT_I010, "VIDEO_FORMAT_I010"},
  68. {VIDEO_FORMAT_P010, "VIDEO_FORMAT_P010"},
  69. {VIDEO_FORMAT_P216, "VIDEO_FORMAT_P216"},
  70. {VIDEO_FORMAT_P416, "VIDEO_FORMAT_P416"},
  71. })
  72. NLOHMANN_JSON_SERIALIZE_ENUM(video_range_type, {
  73. {VIDEO_RANGE_DEFAULT, "VIDEO_RANGE_DEFAULT"},
  74. {VIDEO_RANGE_PARTIAL, "VIDEO_RANGE_PARTIAL"},
  75. {VIDEO_RANGE_FULL, "VIDEO_RANGE_FULL"},
  76. })
  77. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(media_frames_per_second, numerator, denominator)
  78. namespace GoLiveApi {
  79. using std::string;
  80. using std::optional;
  81. using json = nlohmann::json;
  82. struct Client {
  83. string name = "obs-studio";
  84. string version;
  85. std::vector<string> supported_codecs;
  86. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Client, name, version, supported_codecs)
  87. };
  88. struct Cpu {
  89. int32_t physical_cores;
  90. int32_t logical_cores;
  91. optional<uint32_t> speed;
  92. optional<string> name;
  93. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Cpu, physical_cores, logical_cores, speed, name)
  94. };
  95. struct Memory {
  96. uint64_t total;
  97. uint64_t free;
  98. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Memory, total, free)
  99. };
  100. struct Gpu {
  101. string model;
  102. uint32_t vendor_id;
  103. uint32_t device_id;
  104. uint64_t dedicated_video_memory;
  105. uint64_t shared_system_memory;
  106. optional<string> driver_version;
  107. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Gpu, model, vendor_id, device_id, dedicated_video_memory, shared_system_memory,
  108. driver_version)
  109. };
  110. struct GamingFeatures {
  111. optional<bool> game_bar_enabled;
  112. optional<bool> game_dvr_allowed;
  113. optional<bool> game_dvr_enabled;
  114. optional<bool> game_dvr_bg_recording;
  115. optional<bool> game_mode_enabled;
  116. optional<bool> hags_enabled;
  117. NLOHMANN_DEFINE_TYPE_INTRUSIVE(GamingFeatures, game_bar_enabled, game_dvr_allowed, game_dvr_enabled,
  118. game_dvr_bg_recording, game_mode_enabled, hags_enabled)
  119. };
  120. struct System {
  121. string version;
  122. string name;
  123. int build;
  124. string release;
  125. int revision;
  126. int bits;
  127. bool arm;
  128. bool armEmulation;
  129. NLOHMANN_DEFINE_TYPE_INTRUSIVE(System, version, name, build, release, revision, bits, arm, armEmulation)
  130. };
  131. struct Capabilities {
  132. Cpu cpu;
  133. Memory memory;
  134. optional<GamingFeatures> gaming_features;
  135. System system;
  136. optional<std::vector<Gpu>> gpu;
  137. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Capabilities, cpu, memory, gaming_features, system, gpu)
  138. };
  139. struct Preferences {
  140. optional<uint64_t> maximum_aggregate_bitrate;
  141. optional<uint32_t> maximum_video_tracks;
  142. bool vod_track_audio;
  143. uint32_t width;
  144. uint32_t height;
  145. media_frames_per_second framerate;
  146. uint32_t canvas_width;
  147. uint32_t canvas_height;
  148. optional<uint32_t> composition_gpu_index;
  149. uint32_t audio_samples_per_sec;
  150. uint32_t audio_channels;
  151. uint32_t audio_max_buffering_ms;
  152. bool audio_fixed_buffering;
  153. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Preferences, maximum_aggregate_bitrate, maximum_video_tracks, vod_track_audio,
  154. width, height, framerate, canvas_width, canvas_height, composition_gpu_index,
  155. audio_samples_per_sec, audio_channels, audio_max_buffering_ms,
  156. audio_fixed_buffering)
  157. };
  158. struct PostData {
  159. string service;
  160. string schema_version;
  161. string authentication;
  162. Client client;
  163. Capabilities capabilities;
  164. Preferences preferences;
  165. NLOHMANN_DEFINE_TYPE_INTRUSIVE(PostData, service, schema_version, authentication, client, capabilities,
  166. preferences)
  167. };
  168. // Config Response
  169. struct Meta {
  170. string service;
  171. string schema_version;
  172. string config_id;
  173. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Meta, service, schema_version, config_id)
  174. };
  175. enum struct StatusResult {
  176. Unknown,
  177. Success,
  178. Warning,
  179. Error,
  180. };
  181. NLOHMANN_JSON_SERIALIZE_ENUM(StatusResult, {
  182. {StatusResult::Unknown, nullptr},
  183. {StatusResult::Success, "success"},
  184. {StatusResult::Warning, "warning"},
  185. {StatusResult::Error, "error"},
  186. })
  187. struct Status {
  188. StatusResult result = StatusResult::Unknown;
  189. optional<string> html_en_us;
  190. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Status, result, html_en_us)
  191. };
  192. struct IngestEndpoint {
  193. string protocol;
  194. string url_template;
  195. optional<string> authentication;
  196. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(IngestEndpoint, protocol, url_template, authentication)
  197. };
  198. struct VideoEncoderConfiguration {
  199. string type;
  200. uint32_t width;
  201. uint32_t height;
  202. optional<media_frames_per_second> framerate;
  203. optional<obs_scale_type> gpu_scale_type;
  204. optional<video_colorspace> colorspace;
  205. optional<video_range_type> range;
  206. optional<video_format> format;
  207. json settings;
  208. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(VideoEncoderConfiguration, type, width, height, framerate,
  209. gpu_scale_type, colorspace, range, format, settings)
  210. };
  211. struct AudioEncoderConfiguration {
  212. string codec;
  213. uint32_t track_id;
  214. uint32_t channels;
  215. json settings;
  216. NLOHMANN_DEFINE_TYPE_INTRUSIVE(AudioEncoderConfiguration, codec, track_id, channels, settings)
  217. };
  218. struct AudioConfigurations {
  219. std::vector<AudioEncoderConfiguration> live;
  220. optional<std::vector<AudioEncoderConfiguration>> vod;
  221. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(AudioConfigurations, live, vod)
  222. };
  223. struct Config {
  224. Meta meta;
  225. optional<Status> status;
  226. std::vector<IngestEndpoint> ingest_endpoints;
  227. std::vector<VideoEncoderConfiguration> encoder_configurations;
  228. AudioConfigurations audio_configurations;
  229. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, meta, status, ingest_endpoints, encoder_configurations,
  230. audio_configurations)
  231. };
  232. } // namespace GoLiveApi