mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-03 00:38:14 -07:00
api: h.264 video stream (#876)
## Link to GitHub Issue or related Pull Request, if one exists fixes #875 ## Description of change Adds `-apistream`, an optional HTTP video stream of the mirrored screen. It listens on the API port +2. Two endpoints, sharing the same `screen`, `fps` and `q` parameters: /stream.mjpg JPEG frames, for clients with no container support /stream.h264 H.264 annex-b, for an app driving MediaCodec or VideoToolbox itself One encoder per connection, fed by a per-screen pump that always hands over the newest frame, so a slow reader drops frames instead of building a backlog. `capture.get_jpg` behaviour is unchanged. Additional documentation for developers: https://github.com/spice2x/spice2x.github.io/wiki/Video-Stream ## Testing
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "acio/icca/icca.h"
|
||||
#include "acio/mdxf/mdxf.h"
|
||||
#include "api/controller.h"
|
||||
#include "api/stream_server.h"
|
||||
#include "avs/automap.h"
|
||||
#include "avs/core.h"
|
||||
#include "avs/ea3.h"
|
||||
@@ -150,6 +151,7 @@ std::string CARD_OVERRIDES[2];
|
||||
|
||||
// sub-systems
|
||||
std::unique_ptr<api::Controller> API_CONTROLLER;
|
||||
std::unique_ptr<api::StreamServer> API_STREAM_SERVER;
|
||||
std::unique_ptr<rawinput::RawInputManager> RI_MGR;
|
||||
|
||||
// trigger NVIDIA Optimus & AMD Enduro High Performance Graphics
|
||||
@@ -198,6 +200,7 @@ int main_implementation(int argc, char *argv[]) {
|
||||
bool api_pretty = false;
|
||||
bool api_debug = false;
|
||||
unsigned short api_port = 1337;
|
||||
bool api_stream_enable = false;
|
||||
std::string api_pass = "";
|
||||
std::vector<std::string> api_serial_port;
|
||||
std::vector<DWORD> api_serial_baud;
|
||||
@@ -1032,6 +1035,9 @@ int main_implementation(int argc, char *argv[]) {
|
||||
if (options[launcher::Options::APIScreenMirrorDivide].is_active()) {
|
||||
api::modules::CAPTURE_DIVIDE = options[launcher::Options::APIScreenMirrorDivide].value_uint32();
|
||||
}
|
||||
if (options[launcher::Options::APIStreamEnable].value_bool() && !cfg::CONFIGURATOR_STANDALONE) {
|
||||
api_stream_enable = true;
|
||||
}
|
||||
|
||||
if (options[launcher::Options::DisableDebugHooks].value_bool()) {
|
||||
debughook::DEBUGHOOK_LOGGING = false;
|
||||
@@ -2731,6 +2737,20 @@ int main_implementation(int argc, char *argv[]) {
|
||||
for (size_t i = 0; i < std::min(api_serial_port.size(), api_serial_baud.size()); i++) {
|
||||
API_CONTROLLER->listen_serial(api_serial_port[i], api_serial_baud[i]);
|
||||
}
|
||||
// the websocket already sits on the API port plus one, so the stream takes plus two
|
||||
if (api_stream_enable) {
|
||||
if (!api_enable) {
|
||||
log_fatal("launcher", "video stream requires API port to be set (-api)");
|
||||
} else if (api_port + 2 > 65535) {
|
||||
log_fatal(
|
||||
"launcher",
|
||||
"ignoring the video stream, API port {} leaves no room for port plus two",
|
||||
api_port);
|
||||
} else {
|
||||
API_STREAM_SERVER = std::make_unique<api::StreamServer>(
|
||||
static_cast<unsigned short>(api_port + 2));
|
||||
}
|
||||
}
|
||||
|
||||
// pin macro
|
||||
if (!cfg::CONFIGURATOR_STANDALONE && PIN_MACRO_ENABLED) {
|
||||
@@ -2819,6 +2839,7 @@ int main_implementation(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
// free api controller
|
||||
API_STREAM_SERVER.reset();
|
||||
API_CONTROLLER.reset();
|
||||
|
||||
eamuse_pin_macro_stop_thread();
|
||||
|
||||
Reference in New Issue
Block a user