server/src/stream.h
Rama main · réplica de lectura del repositorio original.
/**
* @file src/stream.h
* @brief Declarations for the streaming protocols.
*/
#pragma once
// standard includes
#include <array>
#include <atomic>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
// lib includes
#include <boost/asio.hpp>
// local includes
#include "audio.h"
#include "crypto.h"
#include "thread_safe.h"
#include "video.h"
#include "stream_protocol.h"
#include "remote_session.h"
namespace rtsp_stream {
struct launch_session_t;
}
namespace input::usbip {
class session_holder_t;
}
namespace stream {
constexpr auto VIDEO_STREAM_PORT = 9;
constexpr auto CONTROL_PORT = 10;
constexpr auto AUDIO_STREAM_PORT = 11;
constexpr std::string_view video_format_name(int video_format) {
switch (video_format) {
case 0:
return "H.264";
case 1:
return "HEVC";
case 2:
return "AV1";
case 3:
return "PyroWave";
default:
return "Unknown";
}
}
struct session_t;
struct config_t {
audio::config_t audio;
video::config_t monitor;
int packetsize;
int minRequiredFecPackets;
int mlFeatureFlags;
int controlProtocolType;
int audioQosType;
int videoQosType;
uint32_t encryptionFlagsEnabled;
std::optional<int> gcmap;
bool gen1_framegen_fix;
bool gen2_framegen_fix;
bool frame_generation_enabled;
bool lossless_scaling_framegen;
std::string frame_generation_provider;
std::optional<double> lossless_scaling_target_fps;
std::optional<int> lossless_scaling_rtss_limit;
};
namespace session {
extern std::atomic_uint running_sessions;
// Counts RTSP joins through their complete post-session cleanup tail.
// Observers use this instead of entering blocking session cleanup.
extern std::atomic_uint teardown_sessions;
extern std::atomic_uint cleanup_reservations;
class cleanup_reservation_t {
public:
cleanup_reservation_t();
~cleanup_reservation_t();
cleanup_reservation_t(const cleanup_reservation_t &) = delete;
cleanup_reservation_t &operator=(const cleanup_reservation_t &) = delete;
};
struct shared_runtime_finalize_context_t {
bool ignore_current_rtsp_teardown {false};
bool ignore_current_webrtc_teardown {false};
bool apply_deferred_config {true};
bool force_display_revert_when_idle {false};
std::optional<std::array<std::uint8_t, 16>> virtual_display_guid_bytes;
};
/**
* These helpers require nvhttp::stream_lifecycle_mutex() to be held.
*/
bool has_capture_runtime_owner(const shared_runtime_finalize_context_t &context = {});
bool has_shared_runtime_owner(const shared_runtime_finalize_context_t &context = {});
void arm_shared_runtime_cleanup(
std::optional<std::array<std::uint8_t, 16>> virtual_display_guid_bytes = std::nullopt
);
void start_shared_platform_if_needed();
// Called after all game transports stop, while the lifecycle mutex is held.
// Remote Monitor and Remote Input ownership survives this terminal action.
void release_terminated_game_displays();
bool finalize_shared_runtime_if_idle(
std::string_view reason,
const shared_runtime_finalize_context_t &context = {}
);
enum class state_e : int {
STOPPED, ///< The session is stopped
STOPPING, ///< The session is stopping
STARTING, ///< The session is starting
RUNNING, ///< The session is running
};
/**
* @brief Hand this session the USB devices it holds, so the session's own death gives them back.
*
* Called once, right after start() succeeded and before the session is published. It is a plain
* assignment and it deliberately owns the ONLY reference: the devices are released when this
* session's last reference goes, which is the end of the stream by every path there is.
*/
void adopt_usbip_holder(session_t &session, std::shared_ptr<input::usbip::session_holder_t> holder);
/**
* @brief Whether this session is holding imported USB devices right now.
*
* The holder is owned by the session and destroyed with it, so this is the session's own
* answer to "is a keyboard away from the machine it belongs to because of me". That is the
* fact the quit combo needs: a client whose devices are being held is the client somebody is
* sitting at, and therefore the one that pressed the combo.
*/
bool holding_usbip_devices(const session_t &session);
std::shared_ptr<session_t> alloc(config_t &config, rtsp_stream::launch_session_t &launch_session);
std::string uuid(const session_t &session);
bool uuid_match(const session_t &session, const std::string_view &uuid);
bool update_device_info(session_t &session, const std::string &name, const crypto::PERM &newPerm);
bool remote_role_match(const session_t &session, remote_session::role_e role, std::optional<std::uint64_t> generation = std::nullopt);
void mark_client_disconnected(session_t &session);
int start(session_t &session, const std::string &addr_string);
void stop(session_t &session);
void graceful_stop(session_t &session);
void join(session_t &session, bool lifecycle_lock_held = false);
state_e state(session_t &session);
inline bool send(session_t &session, const std::string_view &payload);
} // namespace session
void cancel_paused_display_cleanup();
struct session_info_t {
std::string uuid;
std::string device_name;
int width;
int height;
int fps;
int encoder_bitrate_kbps;
int requested_bitrate_kbps; // Original client-requested wire bitrate (== encoder_bitrate_kbps for clients that don't send maximumBitrateKbps)
int video_format; // 0=H.264, 1=HEVC, 2=AV1
int dynamic_range; // Encoder bit depth: 0=8-bit, 1=10-bit
bool hdr;
bool yuv444;
int audio_channels;
std::string stream_gpu_model;
std::string state;
// Real-time performance counters
std::uint64_t frames_sent;
std::uint64_t packets_sent;
std::uint64_t bytes_sent;
std::uint32_t idr_requests;
std::uint32_t invalidate_ref_count;
std::int64_t client_reported_losses;
double encode_latency_ms; // last frame encode latency in ms
std::int64_t last_frame_index;
double uptime_seconds;
};
std::vector<session_info_t> get_all_session_info();
void request_idr_for_all_sessions();
/**
* @brief Apply a new encoder bitrate to active streaming sessions at runtime.
* @param client_uuid Target client UUID; when empty, applies to every active session.
* @param bitrate_kbps New encoder bitrate in kbps (already clamped by the caller).
* @return Number of sessions updated.
*/
int set_bitrate_for_sessions(const std::string &client_uuid, int bitrate_kbps);
} // namespace stream