diff --git a/sunshine/nvhttp.cpp b/sunshine/nvhttp.cpp index 3807a6fd..b7fffc1f 100644 --- a/sunshine/nvhttp.cpp +++ b/sunshine/nvhttp.cpp @@ -469,7 +469,7 @@ void serverinfo(std::shared_ptr::Response> res auto current_appid = proc::proc.running(); tree.put("root.PairStatus", pair_status); - tree.put("root.currentgame", current_appid >= 0 ? current_appid + 2 : 0); + tree.put("root.currentgame", current_appid >= 0 ? current_appid + 1 : 0); tree.put("root.state", "_SERVER_BUSY"); std::ostringstream data; @@ -502,8 +502,6 @@ void applist(resp_https_t response, req_https_t request) { auto &apps = tree.add_child("root", pt::ptree {}); - pt::ptree desktop; - apps.put(".status_code", 200); int x = 0; @@ -516,8 +514,6 @@ void applist(resp_https_t response, req_https_t request) { apps.push_back(std::make_pair("App", std::move(app))); } - - apps.push_back(std::make_pair("App", desktop)); } void launch(resp_https_t response, req_https_t request) { diff --git a/sunshine/rtsp.cpp b/sunshine/rtsp.cpp index 98135563..2b09d1e6 100644 --- a/sunshine/rtsp.cpp +++ b/sunshine/rtsp.cpp @@ -32,7 +32,7 @@ void free_msg(PRTSP_MESSAGE msg) { class rtsp_server_t; using msg_t = util::safe_ptr; -using cmd_func_t = std::function &, net::peer_t, msg_t&&)>; +using cmd_func_t = std::function; safe::event_t launch_event; @@ -90,7 +90,7 @@ public: msg_t resp; auto func = _map_cmd_cb.find(req->message.request.command); if (func != std::end(_map_cmd_cb)) { - func->second(this, nullptr, peer, std::move(req)); + func->second(this, peer, std::move(req)); } else { cmd_not_found(host(), peer, std::move(req)); @@ -219,7 +219,7 @@ void cmd_not_found(net::host_t::pointer host, net::peer_t peer, msg_t&& req) { respond(host, peer, nullptr, 404, "NOT FOUND", req->sequenceNumber, {}); } -void cmd_option(rtsp_server_t *server, const std::shared_ptr &session, net::peer_t peer, msg_t&& req) { +void cmd_option(rtsp_server_t *server, net::peer_t peer, msg_t&& req) { OPTION_ITEM option {}; // I know these string literals will not be modified @@ -231,7 +231,7 @@ void cmd_option(rtsp_server_t *server, const std::shared_ptr &session respond(server->host(), peer, &option, 200, "OK", req->sequenceNumber, {}); } -void cmd_describe(rtsp_server_t *server, const std::shared_ptr &session, net::peer_t peer, msg_t&& req) { +void cmd_describe(rtsp_server_t *server, net::peer_t peer, msg_t&& req) { OPTION_ITEM option {}; // I know these string literals will not be modified @@ -251,7 +251,7 @@ void cmd_describe(rtsp_server_t *server, const std::shared_ptr &sessi respond(server->host(), peer, &option, 200, "OK", req->sequenceNumber, payload); } -void cmd_setup(rtsp_server_t *server, const std::shared_ptr &session, net::peer_t peer, msg_t &&req) { +void cmd_setup(rtsp_server_t *server, net::peer_t peer, msg_t &&req) { OPTION_ITEM options[2] {}; auto &seqn = options[0]; @@ -262,13 +262,6 @@ void cmd_setup(rtsp_server_t *server, const std::shared_ptr &session, auto seqn_str = std::to_string(req->sequenceNumber); seqn.content = const_cast(seqn_str.c_str()); - if(session->idr_events) { - // already streaming - - respond(server->host(), peer, &seqn, 503, "Service Unavailable", req->sequenceNumber, {}); - return; - } - std::string_view target { req->message.request.target }; auto begin = std::find(std::begin(target), std::end(target), '=') + 1; auto end = std::find(begin, std::end(target), '/'); @@ -289,7 +282,7 @@ void cmd_setup(rtsp_server_t *server, const std::shared_ptr &session, respond(server->host(), peer, &seqn, 200, "OK", req->sequenceNumber, {}); } -void cmd_announce(rtsp_server_t *server, const std::shared_ptr &session, net::peer_t peer, msg_t &&req) { +void cmd_announce(rtsp_server_t *server, net::peer_t peer, msg_t &&req) { OPTION_ITEM option {}; // I know these string literals will not be modified @@ -298,15 +291,8 @@ void cmd_announce(rtsp_server_t *server, const std::shared_ptr &sessi auto seqn_str = std::to_string(req->sequenceNumber); option.content = const_cast(seqn_str.c_str()); - auto expected_state = state_e::STOPPED; - auto abort = session->state.compare_exchange_strong(expected_state, state_e::STARTING); - - if(abort || !launch_event.peek()) { - //Either already streaming or /launch has not been used - - if(!abort) { - session->state.store(state_e::STOPPED); - } + if(!launch_event.peek()) { + // /launch has not been used respond(server->host(), peer, &option, 503, "Service Unavailable", req->sequenceNumber, {}); return; @@ -361,6 +347,7 @@ void cmd_announce(rtsp_server_t *server, const std::shared_ptr &sessi args.try_emplace("x-nv-video[0].dynamicRangeMode"sv, "0"sv); args.try_emplace("x-nv-aqos.packetDuration"sv, "5"sv); + auto session = std::make_shared(); try { auto &config = session->config; @@ -393,6 +380,13 @@ void cmd_announce(rtsp_server_t *server, const std::shared_ptr &sessi return; } + if(!server->accept(session)) { + BOOST_LOG(info) << "Ran out of slots for client from ["sv << ']'; + + respond(server->host(), peer, &option, 503, "Service Unavailable", req->sequenceNumber, {}); + return; + } + auto &gcm_key = launch_session->gcm_key; auto &iv = launch_session->iv; @@ -410,7 +404,7 @@ void cmd_announce(rtsp_server_t *server, const std::shared_ptr &sessi respond(server->host(), peer, &option, 200, "OK", req->sequenceNumber, {}); } -void cmd_play(rtsp_server_t *server, const std::shared_ptr &session, net::peer_t peer, msg_t &&req) { +void cmd_play(rtsp_server_t *server, net::peer_t peer, msg_t &&req) { OPTION_ITEM option {}; // I know these string literals will not be modified diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index efde8b13..cdc78e25 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -72,8 +72,6 @@ using rh_t = util::safe_ptr; using video_packet_t = util::c_ptr; using audio_packet_t = util::c_ptr; -using session_queue_t = std::shared_ptr>>>; - int start_broadcast(broadcast_ctx_t &ctx); void end_broadcast(broadcast_ctx_t &ctx); @@ -92,7 +90,7 @@ public: control_server_t(control_server_t &&) noexcept = default; control_server_t &operator=(control_server_t &&) noexcept = default; - explicit control_server_t(std::uint16_t port) : _host { net::host_create(_addr, config::stream.channels, port) } {} + explicit control_server_t(session_queue_t session_queue, std::uint16_t port) : session_queue { session_queue }, _host { net::host_create(_addr, config::stream.channels, port) } {} template void iterate(std::chrono::duration timeout) { @@ -294,8 +292,8 @@ void control_server_t::send(const std::string_view & payload) { enet_host_flush(_host.get()); } -void controlBroadcastThread(safe::event_t *shutdown_event) { - control_server_t server { CONTROL_PORT }; +void controlBroadcastThread(safe::event_t *shutdown_event, session_queue_t session_queue) { + control_server_t server { session_queue, CONTROL_PORT }; server.map(packetTypes[IDX_START_A], [&](session_t *session, const std::string_view &payload) { BOOST_LOG(debug) << "type [IDX_START_A]"sv; @@ -395,7 +393,7 @@ void recvThread(broadcast_ctx_t &ctx) { auto &video_sock = ctx.video_sock; auto &audio_sock = ctx.audio_sock; - auto &session_queue = ctx.session_queue; + auto &session_queue = ctx.message_queue_queue; auto &io = ctx.io; udp::endpoint peer; @@ -585,10 +583,12 @@ void audioBroadcastThread(safe::event_t *shutdown_event, udp::socket &sock int start_broadcast(broadcast_ctx_t &ctx) { ctx.video_packets = std::make_shared(); ctx.audio_packets = std::make_shared(); + ctx.message_queue_queue = std::make_shared(); + ctx.session_queue = std::make_shared(); ctx.video_thread = std::thread { videoBroadcastThread, &ctx.shutdown_event, std::ref(ctx.video_sock), ctx.video_packets }; ctx.audio_thread = std::thread { audioBroadcastThread, &ctx.shutdown_event, std::ref(ctx.audio_sock), ctx.audio_packets }; - ctx.control_thread = std::thread { controlBroadcastThread, &ctx.shutdown_event }; + ctx.control_thread = std::thread { controlBroadcastThread, &ctx.shutdown_event, ctx.session_queue }; ctx.recv_thread = std::thread { recvThread, std::ref(ctx) }; @@ -600,7 +600,7 @@ void end_broadcast(broadcast_ctx_t &ctx) { ctx.video_packets->stop(); ctx.audio_packets->stop(); - ctx.session_queue->stop(); + ctx.message_queue_queue->stop(); ctx.video_sock.cancel(); ctx.audio_sock.cancel(); @@ -623,11 +623,11 @@ int recv_ping(decltype(broadcast)::ptr_t ref, socket_e type, asio::ip::address & }; auto messages = std::make_shared(); - ref->session_queue->raise(std::make_tuple(type, addr, messages)); + ref->message_queue_queue->raise(std::make_tuple(type, addr, messages)); auto fg = util::fail_guard([&]() { // remove message queue from session - ref->session_queue->raise(std::make_tuple(type, addr, nullptr)); + ref->message_queue_queue->raise(std::make_tuple(type, addr, nullptr)); }); auto msg_opt = messages->pop(config::stream.ping_timeout); diff --git a/sunshine/stream.h b/sunshine/stream.h index 0bc49409..45f3bb63 100644 --- a/sunshine/stream.h +++ b/sunshine/stream.h @@ -39,8 +39,10 @@ enum class state_e : int { RUNNING, }; +struct session_t; using message_queue_t = std::shared_ptr>>; using message_queue_queue_t = std::shared_ptr>>; +using session_queue_t = std::shared_ptr>>>; struct config_t { audio::config_t audio; @@ -57,7 +59,8 @@ struct broadcast_ctx_t { video::packet_queue_t video_packets; audio::packet_queue_t audio_packets; - message_queue_queue_t session_queue; + message_queue_queue_t message_queue_queue; + session_queue_t session_queue; std::thread video_thread; std::thread audio_thread; @@ -81,8 +84,6 @@ struct session_t { udp::endpoint video_peer; udp::endpoint audio_peer; - - video::idr_event_t idr_events; crypto::aes_t gcm_key;