2019-12-03 19:23:33 +00:00
|
|
|
//
|
|
|
|
// Created by loki on 6/21/19.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef SUNSHINE_COMMON_H
|
|
|
|
#define SUNSHINE_COMMON_H
|
|
|
|
|
2019-12-08 17:55:58 +00:00
|
|
|
#include "sunshine/utility.h"
|
2021-05-18 11:36:12 +00:00
|
|
|
#include <bitset>
|
2021-05-17 19:21:57 +00:00
|
|
|
#include <mutex>
|
|
|
|
#include <string>
|
2019-12-03 19:23:33 +00:00
|
|
|
|
2020-02-08 15:26:38 +00:00
|
|
|
struct sockaddr;
|
2021-06-04 19:12:06 +00:00
|
|
|
struct AVFrame;
|
|
|
|
|
2019-12-03 19:23:33 +00:00
|
|
|
namespace platf {
|
2020-03-15 20:22:42 +00:00
|
|
|
constexpr auto MAX_GAMEPADS = 32;
|
2020-01-25 00:05:43 +00:00
|
|
|
|
2020-01-18 22:52:22 +00:00
|
|
|
constexpr std::uint16_t DPAD_UP = 0x0001;
|
|
|
|
constexpr std::uint16_t DPAD_DOWN = 0x0002;
|
|
|
|
constexpr std::uint16_t DPAD_LEFT = 0x0004;
|
|
|
|
constexpr std::uint16_t DPAD_RIGHT = 0x0008;
|
|
|
|
constexpr std::uint16_t START = 0x0010;
|
|
|
|
constexpr std::uint16_t BACK = 0x0020;
|
|
|
|
constexpr std::uint16_t LEFT_STICK = 0x0040;
|
|
|
|
constexpr std::uint16_t RIGHT_STICK = 0x0080;
|
|
|
|
constexpr std::uint16_t LEFT_BUTTON = 0x0100;
|
|
|
|
constexpr std::uint16_t RIGHT_BUTTON = 0x0200;
|
|
|
|
constexpr std::uint16_t HOME = 0x0400;
|
|
|
|
constexpr std::uint16_t A = 0x1000;
|
|
|
|
constexpr std::uint16_t B = 0x2000;
|
|
|
|
constexpr std::uint16_t X = 0x4000;
|
|
|
|
constexpr std::uint16_t Y = 0x8000;
|
|
|
|
|
2021-05-19 16:11:06 +00:00
|
|
|
namespace speaker {
|
|
|
|
enum speaker_e {
|
|
|
|
FRONT_LEFT,
|
|
|
|
FRONT_RIGHT,
|
|
|
|
FRONT_CENTER,
|
|
|
|
LOW_FREQUENCY,
|
|
|
|
BACK_LEFT,
|
|
|
|
BACK_RIGHT,
|
|
|
|
SIDE_LEFT,
|
|
|
|
SIDE_RIGHT,
|
2021-05-25 16:55:29 +00:00
|
|
|
MAX_SPEAKERS,
|
2021-05-19 16:11:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
constexpr std::uint8_t map_stereo[] {
|
|
|
|
FRONT_LEFT, FRONT_RIGHT
|
|
|
|
};
|
|
|
|
constexpr std::uint8_t map_surround51[] {
|
2021-05-22 17:51:01 +00:00
|
|
|
FRONT_LEFT,
|
|
|
|
FRONT_RIGHT,
|
|
|
|
FRONT_CENTER,
|
|
|
|
LOW_FREQUENCY,
|
|
|
|
BACK_LEFT,
|
|
|
|
BACK_RIGHT,
|
2021-05-19 16:11:06 +00:00
|
|
|
};
|
|
|
|
constexpr std::uint8_t map_surround71[] {
|
|
|
|
FRONT_LEFT,
|
|
|
|
FRONT_RIGHT,
|
2021-05-22 17:51:01 +00:00
|
|
|
FRONT_CENTER,
|
|
|
|
LOW_FREQUENCY,
|
|
|
|
LOW_FREQUENCY,
|
|
|
|
BACK_LEFT,
|
2021-05-19 16:11:06 +00:00
|
|
|
BACK_RIGHT,
|
|
|
|
SIDE_LEFT,
|
|
|
|
SIDE_RIGHT,
|
|
|
|
};
|
|
|
|
} // namespace speaker
|
|
|
|
|
2021-05-29 14:25:37 +00:00
|
|
|
enum class mem_type_e {
|
|
|
|
system,
|
2021-06-04 19:12:06 +00:00
|
|
|
vaapi,
|
2020-04-11 23:33:17 +00:00
|
|
|
dxgi,
|
|
|
|
unknown
|
|
|
|
};
|
|
|
|
|
2020-04-02 18:13:44 +00:00
|
|
|
enum class pix_fmt_e {
|
|
|
|
yuv420p,
|
2020-04-11 23:33:17 +00:00
|
|
|
yuv420p10,
|
|
|
|
nv12,
|
2020-04-18 21:10:47 +00:00
|
|
|
p010,
|
2020-04-11 23:33:17 +00:00
|
|
|
unknown
|
2020-04-02 18:13:44 +00:00
|
|
|
};
|
|
|
|
|
2021-04-30 18:01:15 +00:00
|
|
|
inline std::string_view from_pix_fmt(pix_fmt_e pix_fmt) {
|
2021-05-17 19:21:57 +00:00
|
|
|
using namespace std::literals;
|
|
|
|
#define _CONVERT(x) \
|
|
|
|
case pix_fmt_e::x: \
|
|
|
|
return #x##sv
|
2021-04-30 18:01:15 +00:00
|
|
|
switch(pix_fmt) {
|
|
|
|
_CONVERT(yuv420p);
|
|
|
|
_CONVERT(yuv420p10);
|
|
|
|
_CONVERT(nv12);
|
|
|
|
_CONVERT(p010);
|
|
|
|
_CONVERT(unknown);
|
|
|
|
}
|
|
|
|
#undef _CONVERT
|
|
|
|
|
|
|
|
return "unknown"sv;
|
|
|
|
}
|
|
|
|
|
2021-05-11 21:30:56 +00:00
|
|
|
// Dimensions for touchscreen input
|
|
|
|
struct touch_port_t {
|
|
|
|
std::uint32_t offset_x, offset_y;
|
|
|
|
std::uint32_t width, height;
|
|
|
|
|
|
|
|
constexpr touch_port_t(
|
|
|
|
std::uint32_t offset_x, std::uint32_t offset_y,
|
2021-05-17 19:21:57 +00:00
|
|
|
std::uint32_t width, std::uint32_t height) noexcept : offset_x { offset_x }, offset_y { offset_y },
|
|
|
|
width { width }, height { height } {};
|
2021-05-11 21:30:56 +00:00
|
|
|
};
|
|
|
|
|
2020-01-18 22:52:22 +00:00
|
|
|
struct gamepad_state_t {
|
|
|
|
std::uint16_t buttonFlags;
|
|
|
|
std::uint8_t lt;
|
|
|
|
std::uint8_t rt;
|
|
|
|
std::int16_t lsX;
|
|
|
|
std::int16_t lsY;
|
|
|
|
std::int16_t rsX;
|
|
|
|
std::int16_t rsY;
|
|
|
|
};
|
2019-12-03 19:23:33 +00:00
|
|
|
|
2020-02-01 09:25:37 +00:00
|
|
|
class deinit_t {
|
|
|
|
public:
|
|
|
|
virtual ~deinit_t() = default;
|
|
|
|
};
|
|
|
|
|
2019-12-30 10:09:35 +00:00
|
|
|
struct img_t {
|
|
|
|
public:
|
2021-05-17 19:21:57 +00:00
|
|
|
std::uint8_t *data {};
|
|
|
|
std::int32_t width {};
|
2020-01-11 00:17:57 +00:00
|
|
|
std::int32_t height {};
|
2020-01-23 01:40:48 +00:00
|
|
|
std::int32_t pixel_pitch {};
|
|
|
|
std::int32_t row_pitch {};
|
2020-01-11 00:17:57 +00:00
|
|
|
|
2021-05-17 19:21:57 +00:00
|
|
|
img_t() = default;
|
|
|
|
img_t(const img_t &) = delete;
|
|
|
|
img_t(img_t &&) = delete;
|
2019-12-30 10:09:35 +00:00
|
|
|
|
2020-01-09 11:12:18 +00:00
|
|
|
virtual ~img_t() = default;
|
|
|
|
};
|
|
|
|
|
2021-05-19 16:11:06 +00:00
|
|
|
struct sink_t {
|
|
|
|
// Play on host PC
|
|
|
|
std::string host;
|
|
|
|
|
|
|
|
// On Windows, it is not possible to create a virtual sink
|
|
|
|
// Therefore, it is optional
|
|
|
|
struct null_t {
|
|
|
|
std::string stereo;
|
|
|
|
std::string surround51;
|
|
|
|
std::string surround71;
|
|
|
|
};
|
|
|
|
std::optional<null_t> null;
|
2021-05-18 11:36:12 +00:00
|
|
|
};
|
|
|
|
|
2020-04-15 17:16:20 +00:00
|
|
|
struct hwdevice_t {
|
|
|
|
void *data {};
|
2021-06-04 19:12:06 +00:00
|
|
|
AVFrame *frame {};
|
2020-04-02 18:13:44 +00:00
|
|
|
|
2020-04-15 17:16:20 +00:00
|
|
|
virtual int convert(platf::img_t &img) {
|
|
|
|
return -1;
|
2020-04-02 18:13:44 +00:00
|
|
|
}
|
2020-04-15 17:16:20 +00:00
|
|
|
|
2021-06-04 19:12:06 +00:00
|
|
|
/**
|
|
|
|
* implementations must take ownership of 'frame'
|
|
|
|
*/
|
|
|
|
virtual int set_frame(AVFrame *frame) {
|
|
|
|
std::abort(); // ^ This function must never be called
|
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
|
2020-04-10 12:39:50 +00:00
|
|
|
virtual void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {};
|
2020-04-02 18:13:44 +00:00
|
|
|
|
2020-04-15 17:16:20 +00:00
|
|
|
virtual ~hwdevice_t() = default;
|
2020-04-02 18:13:44 +00:00
|
|
|
};
|
|
|
|
|
2020-01-09 11:12:18 +00:00
|
|
|
enum class capture_e : int {
|
|
|
|
ok,
|
|
|
|
reinit,
|
|
|
|
timeout,
|
|
|
|
error
|
2019-12-30 10:09:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class display_t {
|
|
|
|
public:
|
2021-05-11 21:51:45 +00:00
|
|
|
display_t() noexcept : offset_x { 0 }, offset_y { 0 } {}
|
2020-04-10 12:39:50 +00:00
|
|
|
virtual capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) = 0;
|
2021-05-17 19:21:57 +00:00
|
|
|
virtual std::shared_ptr<img_t> alloc_img() = 0;
|
2020-01-09 11:12:18 +00:00
|
|
|
|
2020-04-10 12:39:50 +00:00
|
|
|
virtual int dummy_img(img_t *img) = 0;
|
2020-03-31 19:18:33 +00:00
|
|
|
|
2020-04-15 17:16:20 +00:00
|
|
|
virtual std::shared_ptr<hwdevice_t> make_hwdevice(int width, int height, pix_fmt_e pix_fmt) {
|
|
|
|
return std::make_shared<hwdevice_t>();
|
2020-03-31 19:18:33 +00:00
|
|
|
}
|
|
|
|
|
2019-12-30 10:49:45 +00:00
|
|
|
virtual ~display_t() = default;
|
2020-04-15 17:16:20 +00:00
|
|
|
|
2021-05-11 21:51:45 +00:00
|
|
|
// Offsets for when streaming a specific monitor. By default, they are 0.
|
|
|
|
int offset_x, offset_y;
|
|
|
|
|
2020-04-15 17:16:20 +00:00
|
|
|
int width, height;
|
2019-12-30 10:49:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class mic_t {
|
|
|
|
public:
|
2020-01-15 17:31:28 +00:00
|
|
|
virtual capture_e sample(std::vector<std::int16_t> &frame_buffer) = 0;
|
2019-12-30 10:49:45 +00:00
|
|
|
|
|
|
|
virtual ~mic_t() = default;
|
2019-12-30 10:09:35 +00:00
|
|
|
};
|
|
|
|
|
2021-05-18 11:36:12 +00:00
|
|
|
class audio_control_t {
|
|
|
|
public:
|
2021-05-19 16:11:06 +00:00
|
|
|
virtual int set_sink(const std::string &sink) = 0;
|
2021-05-18 11:36:12 +00:00
|
|
|
|
2021-05-19 16:11:06 +00:00
|
|
|
virtual std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) = 0;
|
2021-05-18 11:36:12 +00:00
|
|
|
|
2021-05-19 16:11:06 +00:00
|
|
|
virtual std::optional<sink_t> sink_info() = 0;
|
2021-05-18 11:36:12 +00:00
|
|
|
|
|
|
|
virtual ~audio_control_t() = default;
|
|
|
|
};
|
2020-01-19 23:22:13 +00:00
|
|
|
|
2021-05-17 19:21:57 +00:00
|
|
|
void freeInput(void *);
|
2019-12-03 19:23:33 +00:00
|
|
|
|
2020-01-09 11:12:18 +00:00
|
|
|
using input_t = util::safe_ptr<void, freeInput>;
|
2019-12-05 23:13:16 +00:00
|
|
|
|
2020-01-21 01:34:22 +00:00
|
|
|
std::string get_mac_address(const std::string_view &address);
|
2019-12-06 15:33:13 +00:00
|
|
|
|
2020-02-08 15:26:38 +00:00
|
|
|
std::string from_sockaddr(const sockaddr *const);
|
2020-02-12 10:28:27 +00:00
|
|
|
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const);
|
2020-02-08 15:26:38 +00:00
|
|
|
|
2021-05-18 11:36:12 +00:00
|
|
|
std::unique_ptr<audio_control_t> audio_control();
|
2021-05-29 14:25:37 +00:00
|
|
|
std::shared_ptr<display_t> display(mem_type_e hwdevice_type);
|
2019-12-03 19:23:33 +00:00
|
|
|
|
2019-12-06 15:33:13 +00:00
|
|
|
input_t input();
|
|
|
|
void move_mouse(input_t &input, int deltaX, int deltaY);
|
2021-05-11 21:30:56 +00:00
|
|
|
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
|
2019-12-06 15:33:13 +00:00
|
|
|
void button_mouse(input_t &input, int button, bool release);
|
|
|
|
void scroll(input_t &input, int distance);
|
|
|
|
void keyboard(input_t &input, uint16_t modcode, bool release);
|
2020-01-25 19:46:14 +00:00
|
|
|
void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state);
|
2020-01-31 19:57:34 +00:00
|
|
|
|
|
|
|
int alloc_gamepad(input_t &input, int nr);
|
|
|
|
void free_gamepad(input_t &input, int nr);
|
2020-02-01 09:25:37 +00:00
|
|
|
|
|
|
|
[[nodiscard]] std::unique_ptr<deinit_t> init();
|
2021-05-17 19:21:57 +00:00
|
|
|
} // namespace platf
|
2019-12-03 19:23:33 +00:00
|
|
|
|
|
|
|
#endif //SUNSHINE_COMMON_H
|