multitrack-video.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * Copyright (c) 2024 Ruwen Hahn <haruwenz@twitch.tv>
  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_DEFINE_TYPE_NON_INTRUSIVE(media_frames_per_second, numerator, denominator)
  53. namespace GoLiveApi {
  54. using std::string;
  55. using std::optional;
  56. using json = nlohmann::json;
  57. struct Client {
  58. string name = "obs-studio";
  59. string version;
  60. std::vector<string> supported_codecs;
  61. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Client, name, version, supported_codecs)
  62. };
  63. struct Cpu {
  64. int32_t physical_cores;
  65. int32_t logical_cores;
  66. optional<uint32_t> speed;
  67. optional<string> name;
  68. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Cpu, physical_cores, logical_cores, speed, name)
  69. };
  70. struct Memory {
  71. uint64_t total;
  72. uint64_t free;
  73. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Memory, total, free)
  74. };
  75. struct Gpu {
  76. string model;
  77. uint32_t vendor_id;
  78. uint32_t device_id;
  79. uint64_t dedicated_video_memory;
  80. uint64_t shared_system_memory;
  81. optional<string> driver_version;
  82. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Gpu, model, vendor_id, device_id, dedicated_video_memory, shared_system_memory,
  83. driver_version)
  84. };
  85. struct GamingFeatures {
  86. optional<bool> game_bar_enabled;
  87. optional<bool> game_dvr_allowed;
  88. optional<bool> game_dvr_enabled;
  89. optional<bool> game_dvr_bg_recording;
  90. optional<bool> game_mode_enabled;
  91. optional<bool> hags_enabled;
  92. NLOHMANN_DEFINE_TYPE_INTRUSIVE(GamingFeatures, game_bar_enabled, game_dvr_allowed, game_dvr_enabled,
  93. game_dvr_bg_recording, game_mode_enabled, hags_enabled)
  94. };
  95. struct System {
  96. string version;
  97. string name;
  98. int build;
  99. string release;
  100. int revision;
  101. int bits;
  102. bool arm;
  103. bool armEmulation;
  104. NLOHMANN_DEFINE_TYPE_INTRUSIVE(System, version, name, build, release, revision, bits, arm, armEmulation)
  105. };
  106. struct Capabilities {
  107. Cpu cpu;
  108. Memory memory;
  109. optional<GamingFeatures> gaming_features;
  110. System system;
  111. optional<std::vector<Gpu>> gpu;
  112. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Capabilities, cpu, memory, gaming_features, system, gpu)
  113. };
  114. struct Preferences {
  115. optional<uint64_t> maximum_aggregate_bitrate;
  116. optional<uint32_t> maximum_video_tracks;
  117. bool vod_track_audio;
  118. uint32_t width;
  119. uint32_t height;
  120. media_frames_per_second framerate;
  121. uint32_t canvas_width;
  122. uint32_t canvas_height;
  123. optional<uint32_t> composition_gpu_index;
  124. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Preferences, maximum_aggregate_bitrate, maximum_video_tracks, vod_track_audio,
  125. width, height, framerate, canvas_width, canvas_height, composition_gpu_index)
  126. };
  127. struct PostData {
  128. string service;
  129. string schema_version;
  130. string authentication;
  131. Client client;
  132. Capabilities capabilities;
  133. Preferences preferences;
  134. NLOHMANN_DEFINE_TYPE_INTRUSIVE(PostData, service, schema_version, authentication, client, capabilities,
  135. preferences)
  136. };
  137. // Config Response
  138. struct Meta {
  139. string service;
  140. string schema_version;
  141. string config_id;
  142. NLOHMANN_DEFINE_TYPE_INTRUSIVE(Meta, service, schema_version, config_id)
  143. };
  144. enum struct StatusResult {
  145. Unknown,
  146. Success,
  147. Warning,
  148. Error,
  149. };
  150. NLOHMANN_JSON_SERIALIZE_ENUM(StatusResult, {
  151. {StatusResult::Unknown, nullptr},
  152. {StatusResult::Success, "success"},
  153. {StatusResult::Warning, "warning"},
  154. {StatusResult::Error, "error"},
  155. })
  156. struct Status {
  157. StatusResult result = StatusResult::Unknown;
  158. optional<string> html_en_us;
  159. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Status, result, html_en_us)
  160. };
  161. struct IngestEndpoint {
  162. string protocol;
  163. string url_template;
  164. optional<string> authentication;
  165. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(IngestEndpoint, protocol, url_template, authentication)
  166. };
  167. struct VideoEncoderConfiguration {
  168. string type;
  169. uint32_t width;
  170. uint32_t height;
  171. optional<media_frames_per_second> framerate;
  172. optional<obs_scale_type> gpu_scale_type;
  173. json settings;
  174. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(VideoEncoderConfiguration, type, width, height, framerate,
  175. gpu_scale_type, settings)
  176. };
  177. struct AudioEncoderConfiguration {
  178. string codec;
  179. uint32_t track_id;
  180. uint32_t channels;
  181. json settings;
  182. NLOHMANN_DEFINE_TYPE_INTRUSIVE(AudioEncoderConfiguration, codec, track_id, channels, settings)
  183. };
  184. struct AudioConfigurations {
  185. std::vector<AudioEncoderConfiguration> live;
  186. optional<std::vector<AudioEncoderConfiguration>> vod;
  187. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(AudioConfigurations, live, vod)
  188. };
  189. struct Config {
  190. Meta meta;
  191. optional<Status> status;
  192. std::vector<IngestEndpoint> ingest_endpoints;
  193. std::vector<VideoEncoderConfiguration> encoder_configurations;
  194. AudioConfigurations audio_configurations;
  195. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, meta, status, ingest_endpoints, encoder_configurations,
  196. audio_configurations)
  197. };
  198. } // namespace GoLiveApi