obs-studio/UI/models/multitrack-video.hpp

303 lines
8.4 KiB
C++

/*
* Copyright (c) 2024 Ruwen Hahn <haruwenz@twitch.tv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <string>
#include <optional>
#include <obs.h>
#include <nlohmann/json.hpp>
/* From whatsnew.hpp */
#ifndef NLOHMANN_DEFINE_TYPE_INTRUSIVE
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
friend void to_json(nlohmann::json &nlohmann_json_j, \
const Type &nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND( \
NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
} \
friend void from_json(const nlohmann::json &nlohmann_json_j, \
Type &nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND( \
NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \
}
#endif
#ifndef NLOHMANN_JSON_FROM_WITH_DEFAULT
#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) \
nlohmann_json_t.v1 = \
nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
#endif
#ifndef NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json &nlohmann_json_j, \
const Type &nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND( \
NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
} \
friend void from_json(const nlohmann::json &nlohmann_json_j, \
Type &nlohmann_json_t) \
{ \
Type nlohmann_json_default_obj; \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE( \
NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) \
}
#endif
/*
* Support for (de-)serialising std::optional
* From https://github.com/nlohmann/json/issues/1749#issuecomment-1731266676
* whatsnew.hpp's version doesn't seem to work here
*/
template<typename T> struct nlohmann::adl_serializer<std::optional<T>> {
static void from_json(const json &j, std::optional<T> &opt)
{
if (j.is_null()) {
opt = std::nullopt;
} else {
opt = j.get<T>();
}
}
static void to_json(json &json, std::optional<T> t)
{
if (t) {
json = *t;
} else {
json = nullptr;
}
}
};
NLOHMANN_JSON_SERIALIZE_ENUM(obs_scale_type,
{
{OBS_SCALE_DISABLE, "OBS_SCALE_DISABLE"},
{OBS_SCALE_POINT, "OBS_SCALE_POINT"},
{OBS_SCALE_BICUBIC, "OBS_SCALE_BICUBIC"},
{OBS_SCALE_BILINEAR, "OBS_SCALE_BILINEAR"},
{OBS_SCALE_LANCZOS, "OBS_SCALE_LANCZOS"},
{OBS_SCALE_AREA, "OBS_SCALE_AREA"},
})
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(media_frames_per_second, numerator,
denominator)
namespace GoLiveApi {
using std::string;
using std::optional;
using json = nlohmann::json;
struct Client {
string name = "obs-studio";
string version;
std::vector<string> supported_codecs;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Client, name, version, supported_codecs)
};
struct Cpu {
int32_t physical_cores;
int32_t logical_cores;
optional<uint32_t> speed;
optional<string> name;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Cpu, physical_cores, logical_cores,
speed, name)
};
struct Memory {
uint64_t total;
uint64_t free;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Memory, total, free)
};
struct Gpu {
string model;
uint32_t vendor_id;
uint32_t device_id;
uint64_t dedicated_video_memory;
uint64_t shared_system_memory;
optional<string> driver_version;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Gpu, model, vendor_id, device_id,
dedicated_video_memory,
shared_system_memory, driver_version)
};
struct GamingFeatures {
optional<bool> game_bar_enabled;
optional<bool> game_dvr_allowed;
optional<bool> game_dvr_enabled;
optional<bool> game_dvr_bg_recording;
optional<bool> game_mode_enabled;
optional<bool> hags_enabled;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(GamingFeatures, game_bar_enabled,
game_dvr_allowed, game_dvr_enabled,
game_dvr_bg_recording, game_mode_enabled,
hags_enabled)
};
struct System {
string version;
string name;
int build;
string release;
int revision;
int bits;
bool arm;
bool armEmulation;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(System, version, name, build, release,
revision, bits, arm, armEmulation)
};
struct Capabilities {
Cpu cpu;
Memory memory;
optional<GamingFeatures> gaming_features;
System system;
optional<std::vector<Gpu>> gpu;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Capabilities, cpu, memory,
gaming_features, system, gpu)
};
struct Preferences {
optional<uint64_t> maximum_aggregate_bitrate;
optional<uint32_t> maximum_video_tracks;
bool vod_track_audio;
uint32_t width;
uint32_t height;
media_frames_per_second framerate;
uint32_t canvas_width;
uint32_t canvas_height;
optional<uint32_t> composition_gpu_index;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Preferences, maximum_aggregate_bitrate,
maximum_video_tracks, vod_track_audio,
width, height, framerate, canvas_width,
canvas_height, composition_gpu_index)
};
struct PostData {
string service;
string schema_version;
string authentication;
Client client;
Capabilities capabilities;
Preferences preferences;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(PostData, service, schema_version,
authentication, client, capabilities,
preferences)
};
// Config Response
struct Meta {
string service;
string schema_version;
string config_id;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Meta, service, schema_version, config_id)
};
enum struct StatusResult {
Unknown,
Success,
Warning,
Error,
};
NLOHMANN_JSON_SERIALIZE_ENUM(StatusResult,
{
{StatusResult::Unknown, nullptr},
{StatusResult::Success, "success"},
{StatusResult::Warning, "warning"},
{StatusResult::Error, "error"},
})
struct Status {
StatusResult result = StatusResult::Unknown;
optional<string> html_en_us;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Status, result, html_en_us)
};
struct IngestEndpoint {
string protocol;
string url_template;
optional<string> authentication;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(IngestEndpoint, protocol,
url_template,
authentication)
};
struct VideoEncoderConfiguration {
string type;
uint32_t width;
uint32_t height;
optional<media_frames_per_second> framerate;
optional<obs_scale_type> gpu_scale_type;
json settings;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(VideoEncoderConfiguration,
type, width, height,
framerate, gpu_scale_type,
settings)
};
struct AudioEncoderConfiguration {
string codec;
uint32_t track_id;
uint32_t channels;
json settings;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(AudioEncoderConfiguration, codec,
track_id, channels, settings)
};
struct AudioConfigurations {
std::vector<AudioEncoderConfiguration> live;
optional<std::vector<AudioEncoderConfiguration>> vod;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(AudioConfigurations, live,
vod)
};
struct Config {
Meta meta;
optional<Status> status;
std::vector<IngestEndpoint> ingest_endpoints;
std::vector<VideoEncoderConfiguration> encoder_configurations;
AudioConfigurations audio_configurations;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Config, meta, status,
ingest_endpoints,
encoder_configurations,
audio_configurations)
};
} // namespace GoLiveApi