docs: add doxygen (#1004)
This commit is contained in:
@@ -838,45 +838,45 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
||||
int_f(vars, "qp", video.qp);
|
||||
int_f(vars, "min_threads", video.min_threads);
|
||||
int_between_f(vars, "hevc_mode", video.hevc_mode, { 0, 3 });
|
||||
string_f(vars, "sw_preset", video.sw.preset);
|
||||
string_f(vars, "sw_tune", video.sw.tune);
|
||||
int_f(vars, "nv_preset", video.nv.preset, nv::preset_from_view);
|
||||
int_f(vars, "nv_tune", video.nv.tune, nv::tune_from_view);
|
||||
int_f(vars, "nv_rc", video.nv.rc, nv::rc_from_view);
|
||||
int_f(vars, "nv_coder", video.nv.coder, nv::coder_from_view);
|
||||
string_f(vars, "sw_preset", video.sw.sw_preset);
|
||||
string_f(vars, "sw_tune", video.sw.sw_tune);
|
||||
int_f(vars, "nv_preset", video.nv.nv_preset, nv::preset_from_view);
|
||||
int_f(vars, "nv_tune", video.nv.nv_tune, nv::tune_from_view);
|
||||
int_f(vars, "nv_rc", video.nv.nv_rc, nv::rc_from_view);
|
||||
int_f(vars, "nv_coder", video.nv.nv_coder, nv::coder_from_view);
|
||||
|
||||
int_f(vars, "qsv_preset", video.qsv.preset, qsv::preset_from_view);
|
||||
int_f(vars, "qsv_coder", video.qsv.cavlc, qsv::coder_from_view);
|
||||
int_f(vars, "qsv_preset", video.qsv.qsv_preset, qsv::preset_from_view);
|
||||
int_f(vars, "qsv_coder", video.qsv.qsv_cavlc, qsv::coder_from_view);
|
||||
|
||||
std::string quality;
|
||||
string_f(vars, "amd_quality", quality);
|
||||
if(!quality.empty()) {
|
||||
video.amd.quality_h264 = amd::quality_from_view(quality, 1);
|
||||
video.amd.quality_hevc = amd::quality_from_view(quality, 0);
|
||||
video.amd.amd_quality_h264 = amd::quality_from_view(quality, 1);
|
||||
video.amd.amd_quality_hevc = amd::quality_from_view(quality, 0);
|
||||
}
|
||||
|
||||
std::string rc;
|
||||
string_f(vars, "amd_rc", rc);
|
||||
int_f(vars, "amd_coder", video.amd.coder, amd::coder_from_view);
|
||||
int_f(vars, "amd_coder", video.amd.amd_coder, amd::coder_from_view);
|
||||
if(!rc.empty()) {
|
||||
video.amd.rc_h264 = amd::rc_from_view(rc, 1);
|
||||
video.amd.rc_hevc = amd::rc_from_view(rc, 0);
|
||||
video.amd.amd_rc_h264 = amd::rc_from_view(rc, 1);
|
||||
video.amd.amd_rc_hevc = amd::rc_from_view(rc, 0);
|
||||
}
|
||||
|
||||
std::string usage;
|
||||
string_f(vars, "amd_usage", usage);
|
||||
if(!usage.empty()) {
|
||||
video.amd.usage_h264 = amd::usage_from_view(rc, 1);
|
||||
video.amd.usage_hevc = amd::usage_from_view(rc, 0);
|
||||
video.amd.amd_usage_h264 = amd::usage_from_view(rc, 1);
|
||||
video.amd.amd_usage_hevc = amd::usage_from_view(rc, 0);
|
||||
}
|
||||
|
||||
bool_f(vars, "amd_preanalysis", (bool &)video.amd.preanalysis);
|
||||
bool_f(vars, "amd_vbaq", (bool &)video.amd.vbaq);
|
||||
bool_f(vars, "amd_preanalysis", (bool &)video.amd.amd_preanalysis);
|
||||
bool_f(vars, "amd_vbaq", (bool &)video.amd.amd_vbaq);
|
||||
|
||||
int_f(vars, "vt_coder", video.vt.coder, vt::coder_from_view);
|
||||
int_f(vars, "vt_software", video.vt.allow_sw, vt::allow_software_from_view);
|
||||
int_f(vars, "vt_software", video.vt.require_sw, vt::force_software_from_view);
|
||||
int_f(vars, "vt_realtime", video.vt.realtime, vt::rt_from_view);
|
||||
int_f(vars, "vt_coder", video.vt.vt_coder, vt::coder_from_view);
|
||||
int_f(vars, "vt_software", video.vt.vt_allow_sw, vt::allow_software_from_view);
|
||||
int_f(vars, "vt_software", video.vt.vt_require_sw, vt::force_software_from_view);
|
||||
int_f(vars, "vt_realtime", video.vt.vt_realtime, vt::rt_from_view);
|
||||
|
||||
string_f(vars, "encoder", video.encoder);
|
||||
string_f(vars, "adapter_name", video.adapter_name);
|
||||
|
||||
42
src/config.h
42
src/config.h
@@ -17,39 +17,39 @@ struct video_t {
|
||||
|
||||
int min_threads; // Minimum number of threads/slices for CPU encoding
|
||||
struct {
|
||||
std::string preset;
|
||||
std::string tune;
|
||||
std::string sw_preset;
|
||||
std::string sw_tune;
|
||||
} sw;
|
||||
|
||||
struct {
|
||||
std::optional<int> preset;
|
||||
std::optional<int> tune;
|
||||
std::optional<int> rc;
|
||||
int coder;
|
||||
std::optional<int> nv_preset;
|
||||
std::optional<int> nv_tune;
|
||||
std::optional<int> nv_rc;
|
||||
int nv_coder;
|
||||
} nv;
|
||||
|
||||
struct {
|
||||
std::optional<int> preset;
|
||||
std::optional<int> cavlc;
|
||||
std::optional<int> qsv_preset;
|
||||
std::optional<int> qsv_cavlc;
|
||||
} qsv;
|
||||
|
||||
struct {
|
||||
std::optional<int> quality_h264;
|
||||
std::optional<int> quality_hevc;
|
||||
std::optional<int> rc_h264;
|
||||
std::optional<int> rc_hevc;
|
||||
std::optional<int> usage_h264;
|
||||
std::optional<int> usage_hevc;
|
||||
std::optional<int> preanalysis;
|
||||
std::optional<int> vbaq;
|
||||
int coder;
|
||||
std::optional<int> amd_quality_h264;
|
||||
std::optional<int> amd_quality_hevc;
|
||||
std::optional<int> amd_rc_h264;
|
||||
std::optional<int> amd_rc_hevc;
|
||||
std::optional<int> amd_usage_h264;
|
||||
std::optional<int> amd_usage_hevc;
|
||||
std::optional<int> amd_preanalysis;
|
||||
std::optional<int> amd_vbaq;
|
||||
int amd_coder;
|
||||
} amd;
|
||||
|
||||
struct {
|
||||
int allow_sw;
|
||||
int require_sw;
|
||||
int realtime;
|
||||
int coder;
|
||||
int vt_allow_sw;
|
||||
int vt_require_sw;
|
||||
int vt_realtime;
|
||||
int vt_coder;
|
||||
} vt;
|
||||
|
||||
std::string encoder;
|
||||
|
||||
@@ -18,13 +18,11 @@ static int openssl_verify_cb(int ok, X509_STORE_CTX *ctx) {
|
||||
int err_code = X509_STORE_CTX_get_error(ctx);
|
||||
|
||||
switch(err_code) {
|
||||
// FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
return 1;
|
||||
|
||||
// Expired or not-yet-valid certificates are fine. Sometimes Moonlight is running on embedded devices
|
||||
// that don't have accurate clocks (or haven't yet synchronized by the time Moonlight first runs).
|
||||
// This behavior also matches what GeForce Experience does.
|
||||
// FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get moonlight-embedded to work on the raspberry pi
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
return 1;
|
||||
|
||||
@@ -44,7 +44,7 @@ int init() {
|
||||
origin_web_ui_allowed = net::from_enum_string(config::nvhttp.origin_web_ui_allowed);
|
||||
|
||||
if(clean_slate) {
|
||||
unique_id = util::uuid_t::generate().string();
|
||||
unique_id = uuid_util::uuid_t::generate().string();
|
||||
auto dir = std::filesystem::temp_directory_path() / "Sunshine"sv;
|
||||
config::nvhttp.cert = (dir / ("cert-"s + unique_id)).string();
|
||||
config::nvhttp.pkey = (dir / ("pkey-"s + unique_id)).string();
|
||||
|
||||
@@ -21,7 +21,7 @@ using namespace std::literals;
|
||||
namespace input {
|
||||
|
||||
constexpr auto MAX_GAMEPADS = std::min((std::size_t)platf::MAX_GAMEPADS, sizeof(std::int16_t) * 8);
|
||||
#define DISABLE_LEFT_BUTTON_DELAY ((util::ThreadPool::task_id_t)0x01)
|
||||
#define DISABLE_LEFT_BUTTON_DELAY ((thread_pool_util::ThreadPool::task_id_t)0x01)
|
||||
#define ENABLE_LEFT_BUTTON_DELAY nullptr
|
||||
|
||||
constexpr auto VKEY_SHIFT = 0x10;
|
||||
@@ -57,7 +57,7 @@ void free_id(std::bitset<N> &gamepad_mask, int id) {
|
||||
gamepad_mask[id] = false;
|
||||
}
|
||||
|
||||
static util::TaskPool::task_id_t key_press_repeat_id {};
|
||||
static task_pool_util::TaskPool::task_id_t key_press_repeat_id {};
|
||||
static std::unordered_map<short, bool> key_press {};
|
||||
static std::array<std::uint8_t, 5> mouse_press {};
|
||||
|
||||
@@ -82,7 +82,7 @@ struct gamepad_t {
|
||||
|
||||
platf::gamepad_state_t gamepad_state;
|
||||
|
||||
util::ThreadPool::task_id_t back_timeout_id;
|
||||
thread_pool_util::ThreadPool::task_id_t back_timeout_id;
|
||||
|
||||
int id;
|
||||
|
||||
@@ -123,7 +123,7 @@ struct input_t {
|
||||
safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event;
|
||||
platf::rumble_queue_t rumble_queue;
|
||||
|
||||
util::ThreadPool::task_id_t mouse_left_button_timeout;
|
||||
thread_pool_util::ThreadPool::task_id_t mouse_left_button_timeout;
|
||||
|
||||
input::touch_port_t touch_port;
|
||||
};
|
||||
@@ -653,7 +653,7 @@ void passthrough_helper(std::shared_ptr<input_t> input, std::vector<std::uint8_t
|
||||
}
|
||||
|
||||
void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data) {
|
||||
task_pool.push(passthrough_helper, input, util::cmove(input_data));
|
||||
task_pool.push(passthrough_helper, input, move_by_copy_util::cmove(input_data));
|
||||
}
|
||||
|
||||
void reset(std::shared_ptr<input_t> &input) {
|
||||
|
||||
90
src/main.cpp
90
src/main.cpp
@@ -1,31 +1,35 @@
|
||||
// Created by loki on 5/30/19.
|
||||
|
||||
#include "process.h"
|
||||
/**
|
||||
* @file main.cpp
|
||||
*/
|
||||
|
||||
// standard includes
|
||||
#include <csignal>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
// lib includes
|
||||
#include <boost/log/attributes/clock.hpp>
|
||||
#include <boost/log/common.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sinks.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
|
||||
// local includes
|
||||
#include "config.h"
|
||||
#include "confighttp.h"
|
||||
#include "httpcommon.h"
|
||||
#include "main.h"
|
||||
#include "nvhttp.h"
|
||||
#include "platform/common.h"
|
||||
#include "process.h"
|
||||
#include "rtsp.h"
|
||||
#include "thread_pool.h"
|
||||
#include "upnp.h"
|
||||
#include "version.h"
|
||||
#include "video.h"
|
||||
|
||||
#include "platform/common.h"
|
||||
extern "C" {
|
||||
#include <libavutil/log.h>
|
||||
#include <rs.h>
|
||||
@@ -36,7 +40,7 @@ safe::mail_t mail::man;
|
||||
using namespace std::literals;
|
||||
namespace bl = boost::log;
|
||||
|
||||
util::ThreadPool task_pool;
|
||||
thread_pool_util::ThreadPool task_pool;
|
||||
bl::sources::severity_logger<int> verbose(0); // Dominating output
|
||||
bl::sources::severity_logger<int> debug(1); // Follow what is happening
|
||||
bl::sources::severity_logger<int> info(2); // Should be informed about
|
||||
@@ -55,10 +59,15 @@ struct NoDelete {
|
||||
|
||||
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
|
||||
|
||||
/** Print the help to stdout.
|
||||
|
||||
This function prints output to stdout.
|
||||
*/
|
||||
/**
|
||||
* @brief Print help to stdout.
|
||||
* @param name The name of the program.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* print_help("sunshine");
|
||||
* ```
|
||||
*/
|
||||
void print_help(const char *name) {
|
||||
std::cout
|
||||
<< "Usage: "sv << name << " [options] [/path/to/configuration_file] [--cmd]"sv << std::endl
|
||||
@@ -79,10 +88,6 @@ void print_help(const char *name) {
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/** Call the print_help function.
|
||||
|
||||
Calls the print_help function and then exits.
|
||||
*/
|
||||
namespace help {
|
||||
int entry(const char *name, int argc, char *argv[]) {
|
||||
print_help(name);
|
||||
@@ -90,10 +95,6 @@ int entry(const char *name, int argc, char *argv[]) {
|
||||
}
|
||||
} // namespace help
|
||||
|
||||
/** Print the version details to stdout.
|
||||
|
||||
This function prints the version details to stdout and then exits.
|
||||
*/
|
||||
namespace version {
|
||||
int entry(const char *name, int argc, char *argv[]) {
|
||||
std::cout << PROJECT_NAME << " version: v" << PROJECT_VER << std::endl;
|
||||
@@ -102,6 +103,14 @@ int entry(const char *name, int argc, char *argv[]) {
|
||||
} // namespace version
|
||||
|
||||
|
||||
/**
|
||||
* @brief Flush the log.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* log_flush();
|
||||
* ```
|
||||
*/
|
||||
void log_flush() {
|
||||
sink->flush();
|
||||
}
|
||||
@@ -156,8 +165,18 @@ LRESULT CALLBACK SessionMonitorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Main application entry point.
|
||||
* @param argc The number of arguments.
|
||||
* @param argv The arguments.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* main(1, const char* args[] = {"sunshine", nullptr});
|
||||
* ```
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
util::TaskPool::task_id_t force_shutdown = nullptr;
|
||||
task_pool_util::TaskPool::task_id_t force_shutdown = nullptr;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Wait as long as possible to terminate Sunshine.exe during logoff/shutdown
|
||||
@@ -344,7 +363,7 @@ int main(int argc, char *argv[]) {
|
||||
std::thread httpThread { nvhttp::start };
|
||||
std::thread configThread { confighttp::start };
|
||||
|
||||
stream::rtpThread();
|
||||
rtsp_stream::rtpThread();
|
||||
|
||||
httpThread.join();
|
||||
configThread.join();
|
||||
@@ -355,6 +374,16 @@ int main(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a file to string.
|
||||
* @param path The path of the file.
|
||||
* @return `std::string` : The contents of the file.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* std::string contents = read_file("path/to/file");
|
||||
* ```
|
||||
*/
|
||||
std::string read_file(const char *path) {
|
||||
if(!std::filesystem::exists(path)) {
|
||||
BOOST_LOG(debug) << "Missing file: " << path;
|
||||
@@ -374,6 +403,17 @@ std::string read_file(const char *path) {
|
||||
return base64_cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a file.
|
||||
* @param path The path of the file.
|
||||
* @param contents The contents to write.
|
||||
* @return `int` : `0` on success, `-1` on failure.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* int write_status = write_file("path/to/file", "file contents");
|
||||
* ```
|
||||
*/
|
||||
int write_file(const char *path, const std::string_view &contents) {
|
||||
std::ofstream out(path);
|
||||
|
||||
@@ -386,6 +426,18 @@ int write_file(const char *path, const std::string_view &contents) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Map a specified port based on the base port.
|
||||
* @param port The port to map as a difference from the base port.
|
||||
* @return `std:uint16_t` : The mapped port number.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* std::uint16_t mapped_port = map_port(1);
|
||||
* ```
|
||||
*/
|
||||
std::uint16_t map_port(int port) {
|
||||
// TODO: Ensure port is in the range of 21-65535
|
||||
// TODO: Ensure port is not already in use by another application
|
||||
return (std::uint16_t)((int)config::sunshine.port + port);
|
||||
}
|
||||
|
||||
23
src/main.h
23
src/main.h
@@ -1,17 +1,23 @@
|
||||
// Created by loki on 12/22/19.
|
||||
/**
|
||||
* @file main.h
|
||||
*/
|
||||
|
||||
// macros
|
||||
#ifndef SUNSHINE_MAIN_H
|
||||
#define SUNSHINE_MAIN_H
|
||||
|
||||
// standard includes
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
|
||||
// lib includes
|
||||
#include <boost/log/common.hpp>
|
||||
|
||||
// local includes
|
||||
#include "thread_pool.h"
|
||||
#include "thread_safe.h"
|
||||
|
||||
#include <boost/log/common.hpp>
|
||||
|
||||
extern util::ThreadPool task_pool;
|
||||
extern thread_pool_util::ThreadPool task_pool;
|
||||
extern bool display_cursor;
|
||||
|
||||
extern boost::log::sources::severity_logger<int> verbose;
|
||||
@@ -21,15 +27,15 @@ extern boost::log::sources::severity_logger<int> warning;
|
||||
extern boost::log::sources::severity_logger<int> error;
|
||||
extern boost::log::sources::severity_logger<int> fatal;
|
||||
|
||||
// functions
|
||||
int main(int argc, char *argv[]);
|
||||
void log_flush();
|
||||
|
||||
void print_help(const char *name);
|
||||
|
||||
std::string read_file(const char *path);
|
||||
int write_file(const char *path, const std::string_view &contents);
|
||||
|
||||
std::uint16_t map_port(int port);
|
||||
|
||||
// namespaces
|
||||
namespace mail {
|
||||
#define MAIL(x) \
|
||||
constexpr auto x = std::string_view { \
|
||||
@@ -41,10 +47,8 @@ extern safe::mail_t man;
|
||||
// Global mail
|
||||
MAIL(shutdown);
|
||||
MAIL(broadcast_shutdown);
|
||||
|
||||
MAIL(video_packets);
|
||||
MAIL(audio_packets);
|
||||
|
||||
MAIL(switch_display);
|
||||
|
||||
// Local mail
|
||||
@@ -53,5 +57,6 @@ MAIL(idr);
|
||||
MAIL(rumble);
|
||||
MAIL(hdr);
|
||||
#undef MAIL
|
||||
|
||||
} // namespace mail
|
||||
#endif // SUNSHINE_MAIN_H
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define DOSSIER_MOVE_BY_COPY_H
|
||||
|
||||
#include <utility>
|
||||
namespace util {
|
||||
namespace move_by_copy_util {
|
||||
/*
|
||||
* When a copy is made, it moves the object
|
||||
* This allows you to move an object when a move can't be done.
|
||||
@@ -47,5 +47,5 @@ template<class T>
|
||||
MoveByCopy<T> const_cmove(const T &movable) {
|
||||
return MoveByCopy<T>(std::move(const_cast<T &>(movable)));
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace move_by_copy_util
|
||||
#endif
|
||||
|
||||
@@ -202,7 +202,7 @@ void save_state() {
|
||||
void load_state() {
|
||||
if(!fs::exists(config::nvhttp.file_state)) {
|
||||
BOOST_LOG(info) << "File "sv << config::nvhttp.file_state << " doesn't exist"sv;
|
||||
http::unique_id = util::uuid_t::generate().string();
|
||||
http::unique_id = uuid_util::uuid_t::generate().string();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ void load_state() {
|
||||
auto unique_id_p = root.get_optional<std::string>("root.uniqueid");
|
||||
if(!unique_id_p) {
|
||||
// This file doesn't contain moonlight credentials
|
||||
http::unique_id = util::uuid_t::generate().string();
|
||||
http::unique_id = uuid_util::uuid_t::generate().string();
|
||||
return;
|
||||
}
|
||||
http::unique_id = std::move(*unique_id_p);
|
||||
@@ -255,8 +255,8 @@ void update_id_client(const std::string &uniqueID, std::string &&cert, op_e op)
|
||||
}
|
||||
}
|
||||
|
||||
stream::launch_session_t make_launch_session(bool host_audio, const args_t &args) {
|
||||
stream::launch_session_t launch_session;
|
||||
rtsp_stream::launch_session_t make_launch_session(bool host_audio, const args_t &args) {
|
||||
rtsp_stream::launch_session_t launch_session;
|
||||
|
||||
launch_session.host_audio = host_audio;
|
||||
launch_session.gcm_key = util::from_hex<crypto::aes_t>(get_arg(args, "rikey"), true);
|
||||
@@ -707,7 +707,7 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
response->close_connection_after_response = true;
|
||||
});
|
||||
|
||||
if(stream::session_count() == config::stream.channels) {
|
||||
if(rtsp_stream::session_count() == config::stream.channels) {
|
||||
tree.put("root.resume", 0);
|
||||
tree.put("root.<xmlattr>.status_code", 503);
|
||||
|
||||
@@ -748,10 +748,10 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
}
|
||||
|
||||
host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
|
||||
stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||
rtsp_stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint().address().to_string() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint().address().to_string() + ':' + std::to_string(map_port(rtsp_stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.gamesession", 1);
|
||||
}
|
||||
|
||||
@@ -769,7 +769,7 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
|
||||
// It is possible that due a race condition that this if-statement gives a false negative,
|
||||
// that is automatically resolved in rtsp_server_t
|
||||
if(stream::session_count() == config::stream.channels) {
|
||||
if(rtsp_stream::session_count() == config::stream.channels) {
|
||||
tree.put("root.resume", 0);
|
||||
tree.put("root.<xmlattr>.status_code", 503);
|
||||
|
||||
@@ -795,10 +795,10 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
|
||||
return;
|
||||
}
|
||||
|
||||
stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||
rtsp_stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||
|
||||
tree.put("root.<xmlattr>.status_code", 200);
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint().address().to_string() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint().address().to_string() + ':' + std::to_string(map_port(rtsp_stream::RTSP_SETUP_PORT)));
|
||||
tree.put("root.resume", 1);
|
||||
}
|
||||
|
||||
@@ -816,7 +816,7 @@ void cancel(resp_https_t response, req_https_t request) {
|
||||
|
||||
// It is possible that due a race condition that this if-statement gives a false positive,
|
||||
// the client should try again
|
||||
if(stream::session_count() != 0) {
|
||||
if(rtsp_stream::session_count() != 0) {
|
||||
tree.put("root.resume", 0);
|
||||
tree.put("root.<xmlattr>.status_code", 503);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ typedef basic_environment<char> environment;
|
||||
} // namespace boost
|
||||
namespace video {
|
||||
struct config_t;
|
||||
}
|
||||
} // namespace video
|
||||
|
||||
namespace platf {
|
||||
constexpr auto MAX_GAMEPADS = 32;
|
||||
|
||||
@@ -52,7 +52,7 @@ using __float4 = float[4];
|
||||
using __float3 = float[3];
|
||||
using __float2 = float[2];
|
||||
|
||||
struct __attribute__((__aligned__(16))) color_t {
|
||||
struct alignas(16) color_t {
|
||||
float4 color_vec_y;
|
||||
float4 color_vec_u;
|
||||
float4 color_vec_v;
|
||||
@@ -60,7 +60,7 @@ struct __attribute__((__aligned__(16))) color_t {
|
||||
float2 range_uv;
|
||||
};
|
||||
|
||||
struct __attribute__((__aligned__(16))) color_extern_t {
|
||||
struct alignas(16) color_extern_t {
|
||||
__float4 color_vec_y;
|
||||
__float4 color_vec_u;
|
||||
__float4 color_vec_v;
|
||||
|
||||
@@ -172,7 +172,7 @@ static std::uint32_t from_view(const std::string_view &string) {
|
||||
return DRM_MODE_CONNECTOR_Unknown;
|
||||
}
|
||||
|
||||
class plane_it_t : public util::it_wrap_t<plane_t::element_type, plane_it_t> {
|
||||
class plane_it_t : public round_robin_util::it_wrap_t<plane_t::element_type, plane_it_t> {
|
||||
public:
|
||||
plane_it_t(int fd, std::uint32_t *plane_p, std::uint32_t *end)
|
||||
: fd { fd }, plane_p { plane_p }, end { end } {
|
||||
|
||||
@@ -494,7 +494,7 @@ struct x11_attr_t : public display_t {
|
||||
capture_e snapshot(img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
|
||||
refresh();
|
||||
|
||||
//The whole X server changed, so we gotta reinit everything
|
||||
//The whole X server changed, so we must reinit everything
|
||||
if(xattr.width != env_width || xattr.height != env_height) {
|
||||
BOOST_LOG(warning) << "X dimensions changed in non-SHM mode, request reinit"sv;
|
||||
return capture_e::reinit;
|
||||
@@ -550,7 +550,7 @@ struct shm_attr_t : public x11_attr_t {
|
||||
|
||||
shm_data_t data;
|
||||
|
||||
util::TaskPool::task_id_t refresh_task_id;
|
||||
task_pool_util::TaskPool::task_id_t refresh_task_id;
|
||||
|
||||
void delayed_refresh() {
|
||||
refresh();
|
||||
@@ -603,7 +603,7 @@ struct shm_attr_t : public x11_attr_t {
|
||||
}
|
||||
|
||||
capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) {
|
||||
//The whole X server changed, so we gotta reinit everything
|
||||
//The whole X server changed, so we must reinit everything
|
||||
if(xattr.width != env_width || xattr.height != env_height) {
|
||||
BOOST_LOG(warning) << "X dimensions changed in SHM mode, request reinit"sv;
|
||||
return capture_e::reinit;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace util {
|
||||
namespace round_robin_util {
|
||||
template<class V, class T>
|
||||
class it_wrap_t : public std::iterator<std::random_access_iterator_tag, V> {
|
||||
public:
|
||||
@@ -151,6 +151,6 @@ template<class V, class It>
|
||||
round_robin_t<V, It> make_round_robin(It begin, It end) {
|
||||
return round_robin_t<V, It>(begin, end);
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace round_robin_util
|
||||
|
||||
#endif
|
||||
|
||||
32
src/rtsp.cpp
32
src/rtsp.cpp
@@ -29,7 +29,7 @@ using asio::ip::udp;
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace stream {
|
||||
namespace rtsp_stream {
|
||||
void free_msg(PRTSP_MESSAGE msg) {
|
||||
freeMessage(msg);
|
||||
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
_map_cmd_cb.emplace(type, std::move(cb));
|
||||
}
|
||||
|
||||
void session_raise(launch_session_t launch_session) {
|
||||
void session_raise(rtsp_stream::launch_session_t launch_session) {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
// If a launch event is still pending, don't overwrite it.
|
||||
@@ -307,7 +307,7 @@ public:
|
||||
return config::stream.channels - _slot_count;
|
||||
}
|
||||
|
||||
safe::event_t<launch_session_t> launch_event;
|
||||
safe::event_t<rtsp_stream::launch_session_t> launch_event;
|
||||
|
||||
void clear(bool all = true) {
|
||||
// if a launch event timed out --> Remove it.
|
||||
@@ -321,9 +321,9 @@ public:
|
||||
auto lg = _session_slots.lock();
|
||||
|
||||
for(auto &slot : *_session_slots) {
|
||||
if(slot && (all || session::state(*slot) == session::state_e::STOPPING)) {
|
||||
session::stop(*slot);
|
||||
session::join(*slot);
|
||||
if(slot && (all || stream::session::state(*slot) == stream::session::state_e::STOPPING)) {
|
||||
stream::session::stop(*slot);
|
||||
stream::session::join(*slot);
|
||||
|
||||
slot.reset();
|
||||
|
||||
@@ -336,7 +336,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void clear(std::shared_ptr<session_t> *session_p) {
|
||||
void clear(std::shared_ptr<stream::session_t> *session_p) {
|
||||
auto lg = _session_slots.lock();
|
||||
|
||||
session_p->reset();
|
||||
@@ -344,7 +344,7 @@ public:
|
||||
++_slot_count;
|
||||
}
|
||||
|
||||
std::shared_ptr<session_t> *accept(std::shared_ptr<session_t> &session) {
|
||||
std::shared_ptr<stream::session_t> *accept(std::shared_ptr<stream::session_t> &session) {
|
||||
auto lg = _session_slots.lock();
|
||||
|
||||
for(auto &slot : *_session_slots) {
|
||||
@@ -360,7 +360,7 @@ public:
|
||||
private:
|
||||
std::unordered_map<std::string_view, cmd_func_t> _map_cmd_cb;
|
||||
|
||||
util::sync_t<std::vector<std::shared_ptr<session_t>>> _session_slots;
|
||||
sync_util::sync_t<std::vector<std::shared_ptr<stream::session_t>>> _session_slots;
|
||||
|
||||
std::chrono::steady_clock::time_point raised_timeout;
|
||||
int _slot_count;
|
||||
@@ -373,7 +373,7 @@ private:
|
||||
|
||||
rtsp_server_t server {};
|
||||
|
||||
void launch_session_raise(launch_session_t launch_session) {
|
||||
void launch_session_raise(rtsp_stream::launch_session_t launch_session) {
|
||||
server.session_raise(launch_session);
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
|
||||
args.try_emplace("x-nv-vqos[0].qosTrafficType"sv, "5"sv);
|
||||
args.try_emplace("x-nv-aqos.qosTrafficType"sv, "4"sv);
|
||||
|
||||
config_t config;
|
||||
stream::config_t config;
|
||||
|
||||
config.audio.flags[audio::config_t::HOST_AUDIO] = launch_session->host_audio;
|
||||
try {
|
||||
@@ -670,7 +670,7 @@ void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto session = session::alloc(config, launch_session->gcm_key, launch_session->iv);
|
||||
auto session = stream::session::alloc(config, launch_session->gcm_key, launch_session->iv);
|
||||
|
||||
auto slot = server->accept(session);
|
||||
if(!slot) {
|
||||
@@ -680,7 +680,7 @@ void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(session::start(*session, sock.remote_endpoint().address().to_string())) {
|
||||
if(stream::session::start(*session, sock.remote_endpoint().address().to_string())) {
|
||||
BOOST_LOG(error) << "Failed to start a streaming session"sv;
|
||||
|
||||
server->clear(slot);
|
||||
@@ -715,8 +715,8 @@ void rtpThread() {
|
||||
server.map("PLAY"sv, &cmd_play);
|
||||
|
||||
boost::system::error_code ec;
|
||||
if(server.bind(map_port(RTSP_SETUP_PORT), ec)) {
|
||||
BOOST_LOG(fatal) << "Couldn't bind RTSP server to port ["sv << map_port(RTSP_SETUP_PORT) << "], " << ec.message();
|
||||
if(server.bind(map_port(rtsp_stream::RTSP_SETUP_PORT), ec)) {
|
||||
BOOST_LOG(fatal) << "Couldn't bind RTSP server to port ["sv << map_port(rtsp_stream::RTSP_SETUP_PORT) << "], " << ec.message();
|
||||
shutdown_event->raise(true);
|
||||
|
||||
return;
|
||||
@@ -780,4 +780,4 @@ void print_msg(PRTSP_MESSAGE msg) {
|
||||
<< messageBuffer << std::endl
|
||||
<< "---End MessageBuffer---"sv << std::endl;
|
||||
}
|
||||
} // namespace stream
|
||||
} // namespace rtsp_stream
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "crypto.h"
|
||||
#include "thread_safe.h"
|
||||
|
||||
namespace stream {
|
||||
namespace rtsp_stream {
|
||||
constexpr auto RTSP_SETUP_PORT = 21;
|
||||
|
||||
struct launch_session_t {
|
||||
@@ -23,6 +23,6 @@ int session_count();
|
||||
|
||||
void rtpThread();
|
||||
|
||||
} // namespace stream
|
||||
} // namespace rtsp_stream
|
||||
|
||||
#endif // SUNSHINE_RTSP_H
|
||||
|
||||
@@ -252,7 +252,7 @@ public:
|
||||
std::unordered_map<std::uint16_t, std::function<void(session_t *, const std::string_view &)>> _map_type_cb;
|
||||
|
||||
// Mapping ip:port to session
|
||||
util::sync_t<std::unordered_multimap<std::string, std::pair<std::uint16_t, session_t *>>> _map_addr_session;
|
||||
sync_util::sync_t<std::unordered_multimap<std::string, std::pair<std::uint16_t, session_t *>>> _map_addr_session;
|
||||
|
||||
ENetAddress _addr;
|
||||
net::host_t _host;
|
||||
@@ -275,7 +275,7 @@ struct broadcast_ctx_t {
|
||||
// It's possible two instances of Moonlight are behind a NAT.
|
||||
// From Sunshine's point of view, the ip addresses are identical
|
||||
// We need some way to know what ports are already used for different streams
|
||||
util::sync_t<std::vector<std::pair<std::string, std::uint16_t>>> audio_video_connections;
|
||||
sync_util::sync_t<std::vector<std::pair<std::string, std::uint16_t>>> audio_video_connections;
|
||||
|
||||
control_server_t control_server;
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
namespace util {
|
||||
namespace sync_util {
|
||||
|
||||
template<class T, class M = std::mutex>
|
||||
class sync_t {
|
||||
@@ -87,7 +87,7 @@ private:
|
||||
mutex_t _lock;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace sync_util
|
||||
|
||||
|
||||
#endif // SUNSHINE_SYNC_H
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "move_by_copy.h"
|
||||
#include "utility.h"
|
||||
namespace util {
|
||||
namespace task_pool_util {
|
||||
|
||||
class _ImplBase {
|
||||
public:
|
||||
@@ -241,5 +241,5 @@ private:
|
||||
return std::make_unique<_Impl<Function>>(std::forward<Function &&>(f));
|
||||
}
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace task_pool_util
|
||||
#endif
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "task_pool.h"
|
||||
#include <thread>
|
||||
|
||||
namespace util {
|
||||
namespace thread_pool_util {
|
||||
/*
|
||||
* Allow threads to execute unhindered
|
||||
* while keeping full control over the threads.
|
||||
*/
|
||||
class ThreadPool : public TaskPool {
|
||||
class ThreadPool : public task_pool_util::TaskPool {
|
||||
public:
|
||||
typedef TaskPool::__task __task;
|
||||
|
||||
@@ -117,5 +117,5 @@ public:
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace thread_pool_util
|
||||
#endif
|
||||
|
||||
@@ -132,7 +132,7 @@ std::unique_ptr<platf::deinit_t> start() {
|
||||
}
|
||||
}
|
||||
|
||||
auto rtsp = std::to_string(map_port(stream::RTSP_SETUP_PORT));
|
||||
auto rtsp = std::to_string(map_port(rtsp_stream::RTSP_SETUP_PORT));
|
||||
auto video = std::to_string(map_port(stream::VIDEO_STREAM_PORT));
|
||||
auto audio = std::to_string(map_port(stream::AUDIO_STREAM_PORT));
|
||||
auto control = std::to_string(map_port(stream::CONTROL_PORT));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace util {
|
||||
namespace uuid_util {
|
||||
union uuid_t {
|
||||
std::uint8_t b8[16];
|
||||
std::uint16_t b16[8];
|
||||
@@ -73,5 +73,5 @@ union uuid_t {
|
||||
return (b64[0] > other.b64[0] || (b64[0] == other.b64[0] && b64[1] > other.b64[1]));
|
||||
}
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace uuid_util
|
||||
#endif // T_MAN_UUID_H
|
||||
|
||||
@@ -402,7 +402,7 @@ struct capture_thread_async_ctx_t {
|
||||
|
||||
safe::signal_t reinit_event;
|
||||
const encoder_t *encoder_p;
|
||||
util::sync_t<std::weak_ptr<platf::display_t>> display_wp;
|
||||
sync_util::sync_t<std::weak_ptr<platf::display_t>> display_wp;
|
||||
};
|
||||
|
||||
struct capture_thread_sync_ctx_t {
|
||||
@@ -434,9 +434,9 @@ static encoder_t nvenc {
|
||||
{ "delay"s, 0 },
|
||||
{ "forced-idr"s, 1 },
|
||||
{ "zerolatency"s, 1 },
|
||||
{ "preset"s, &config::video.nv.preset },
|
||||
{ "tune"s, &config::video.nv.tune },
|
||||
{ "rc"s, &config::video.nv.rc },
|
||||
{ "preset"s, &config::video.nv.nv_preset },
|
||||
{ "tune"s, &config::video.nv.nv_tune },
|
||||
{ "rc"s, &config::video.nv.nv_rc },
|
||||
},
|
||||
// SDR-specific options
|
||||
{
|
||||
@@ -454,10 +454,10 @@ static encoder_t nvenc {
|
||||
{ "delay"s, 0 },
|
||||
{ "forced-idr"s, 1 },
|
||||
{ "zerolatency"s, 1 },
|
||||
{ "preset"s, &config::video.nv.preset },
|
||||
{ "tune"s, &config::video.nv.tune },
|
||||
{ "rc"s, &config::video.nv.rc },
|
||||
{ "coder"s, &config::video.nv.coder },
|
||||
{ "preset"s, &config::video.nv.nv_preset },
|
||||
{ "tune"s, &config::video.nv.nv_tune },
|
||||
{ "rc"s, &config::video.nv.nv_rc },
|
||||
{ "coder"s, &config::video.nv.nv_coder },
|
||||
},
|
||||
// SDR-specific options
|
||||
{
|
||||
@@ -486,7 +486,7 @@ static encoder_t quicksync {
|
||||
{
|
||||
// Common options
|
||||
{
|
||||
{ "preset"s, &config::video.qsv.preset },
|
||||
{ "preset"s, &config::video.qsv.qsv_preset },
|
||||
{ "forced_idr"s, 1 },
|
||||
{ "async_depth"s, 1 },
|
||||
{ "low_delay_brc"s, 1 },
|
||||
@@ -508,8 +508,8 @@ static encoder_t quicksync {
|
||||
{
|
||||
// Common options
|
||||
{
|
||||
{ "preset"s, &config::video.qsv.preset },
|
||||
{ "cavlc"s, &config::video.qsv.cavlc },
|
||||
{ "preset"s, &config::video.qsv.qsv_preset },
|
||||
{ "cavlc"s, &config::video.qsv.qsv_cavlc },
|
||||
{ "forced_idr"s, 1 },
|
||||
{ "async_depth"s, 1 },
|
||||
{ "low_delay_brc"s, 1 },
|
||||
@@ -542,13 +542,13 @@ static encoder_t amdvce {
|
||||
{ "filler_data"s, true },
|
||||
{ "gops_per_idr"s, 1 },
|
||||
{ "header_insertion_mode"s, "idr"s },
|
||||
{ "preanalysis"s, &config::video.amd.preanalysis },
|
||||
{ "preanalysis"s, &config::video.amd.amd_preanalysis },
|
||||
{ "qmax"s, 51 },
|
||||
{ "qmin"s, 0 },
|
||||
{ "quality"s, &config::video.amd.quality_hevc },
|
||||
{ "rc"s, &config::video.amd.rc_hevc },
|
||||
{ "usage"s, &config::video.amd.usage_hevc },
|
||||
{ "vbaq"s, &config::video.amd.vbaq },
|
||||
{ "quality"s, &config::video.amd.amd_quality_hevc },
|
||||
{ "rc"s, &config::video.amd.amd_rc_hevc },
|
||||
{ "usage"s, &config::video.amd.amd_usage_hevc },
|
||||
{ "vbaq"s, &config::video.amd.amd_vbaq },
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -560,13 +560,13 @@ static encoder_t amdvce {
|
||||
{
|
||||
{ "filler_data"s, true },
|
||||
{ "log_to_dbg"s, "1"s },
|
||||
{ "preanalysis"s, &config::video.amd.preanalysis },
|
||||
{ "preanalysis"s, &config::video.amd.amd_preanalysis },
|
||||
{ "qmax"s, 51 },
|
||||
{ "qmin"s, 0 },
|
||||
{ "quality"s, &config::video.amd.quality_h264 },
|
||||
{ "rc"s, &config::video.amd.rc_h264 },
|
||||
{ "usage"s, &config::video.amd.usage_h264 },
|
||||
{ "vbaq"s, &config::video.amd.vbaq },
|
||||
{ "quality"s, &config::video.amd.amd_quality_h264 },
|
||||
{ "rc"s, &config::video.amd.amd_rc_h264 },
|
||||
{ "usage"s, &config::video.amd.amd_usage_h264 },
|
||||
{ "vbaq"s, &config::video.amd.amd_vbaq },
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -591,8 +591,8 @@ static encoder_t software {
|
||||
{
|
||||
{ "forced-idr"s, 1 },
|
||||
{ "x265-params"s, "info=0:keyint=-1"s },
|
||||
{ "preset"s, &config::video.sw.preset },
|
||||
{ "tune"s, &config::video.sw.tune },
|
||||
{ "preset"s, &config::video.sw.sw_preset },
|
||||
{ "tune"s, &config::video.sw.sw_tune },
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -602,8 +602,8 @@ static encoder_t software {
|
||||
{
|
||||
// Common options
|
||||
{
|
||||
{ "preset"s, &config::video.sw.preset },
|
||||
{ "tune"s, &config::video.sw.tune },
|
||||
{ "preset"s, &config::video.sw.sw_preset },
|
||||
{ "tune"s, &config::video.sw.sw_tune },
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -660,9 +660,9 @@ static encoder_t videotoolbox {
|
||||
{
|
||||
// Common options
|
||||
{
|
||||
{ "allow_sw"s, &config::video.vt.allow_sw },
|
||||
{ "require_sw"s, &config::video.vt.require_sw },
|
||||
{ "realtime"s, &config::video.vt.realtime },
|
||||
{ "allow_sw"s, &config::video.vt.vt_allow_sw },
|
||||
{ "require_sw"s, &config::video.vt.vt_require_sw },
|
||||
{ "realtime"s, &config::video.vt.vt_realtime },
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -672,9 +672,9 @@ static encoder_t videotoolbox {
|
||||
{
|
||||
// Common options
|
||||
{
|
||||
{ "allow_sw"s, &config::video.vt.allow_sw },
|
||||
{ "require_sw"s, &config::video.vt.require_sw },
|
||||
{ "realtime"s, &config::video.vt.realtime },
|
||||
{ "allow_sw"s, &config::video.vt.vt_allow_sw },
|
||||
{ "require_sw"s, &config::video.vt.vt_require_sw },
|
||||
{ "realtime"s, &config::video.vt.vt_realtime },
|
||||
},
|
||||
{}, // SDR-specific options
|
||||
{}, // HDR-specific options
|
||||
@@ -720,7 +720,7 @@ void reset_display(std::shared_ptr<platf::display_t> &disp, AVHWDeviceType type,
|
||||
|
||||
void captureThread(
|
||||
std::shared_ptr<safe::queue_t<capture_ctx_t>> capture_ctx_queue,
|
||||
util::sync_t<std::weak_ptr<platf::display_t>> &display_wp,
|
||||
sync_util::sync_t<std::weak_ptr<platf::display_t>> &display_wp,
|
||||
safe::signal_t &reinit_event,
|
||||
const encoder_t &encoder) {
|
||||
std::vector<capture_ctx_t> capture_ctxs;
|
||||
@@ -767,7 +767,7 @@ void captureThread(
|
||||
display_wp = disp;
|
||||
|
||||
std::vector<std::shared_ptr<platf::img_t>> imgs(12);
|
||||
auto round_robin = util::make_round_robin<std::shared_ptr<platf::img_t>>(std::begin(imgs), std::end(imgs));
|
||||
auto round_robin = round_robin_util::make_round_robin<std::shared_ptr<platf::img_t>>(std::begin(imgs), std::end(imgs));
|
||||
|
||||
for(auto &img : imgs) {
|
||||
img = disp->alloc_img();
|
||||
@@ -1293,7 +1293,7 @@ void encode_run(
|
||||
auto idr_events = mail->event<bool>(mail::idr);
|
||||
|
||||
// Load a dummy image into the AVFrame to ensure we have something to encode
|
||||
// even if we time out waiting on the first frame.
|
||||
// even if we timeout waiting on the first frame.
|
||||
auto dummy_img = disp->alloc_img();
|
||||
if(!dummy_img || disp->dummy_img(dummy_img.get()) || session->device->convert(*dummy_img)) {
|
||||
return;
|
||||
@@ -1905,7 +1905,7 @@ int init() {
|
||||
|
||||
BOOST_LOG(info) << "// Testing for available encoders, this may generate errors. You can safely ignore those errors. //"sv;
|
||||
|
||||
// If we haven't found an encoder yet but we want one with HDR support, search for that now.
|
||||
// If we haven't found an encoder yet, but we want one with HDR support, search for that now.
|
||||
if(!encoder_found && config::video.hevc_mode == 3) {
|
||||
KITTY_WHILE_LOOP(auto pos = std::begin(encoders), pos != std::end(encoders), {
|
||||
auto encoder = *pos;
|
||||
|
||||
@@ -74,7 +74,7 @@ using float4 = float[4];
|
||||
using float3 = float[3];
|
||||
using float2 = float[2];
|
||||
|
||||
struct __attribute__((__aligned__(16))) color_t {
|
||||
struct alignas(16) color_t {
|
||||
float4 color_vec_y;
|
||||
float4 color_vec_u;
|
||||
float4 color_vec_v;
|
||||
|
||||
Reference in New Issue
Block a user