From 0f281268d45109c8c9af242c73cc27b39245628d Mon Sep 17 00:00:00 2001 From: Jannis Pohl <838818+jannispl@users.noreply.github.com> Date: Sat, 9 Aug 2025 13:32:02 +0200 Subject: [PATCH 1/2] rtsp: reintroduce support for newer livemedia builds --- output/rtsp/rtsp.cc | 83 ++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/output/rtsp/rtsp.cc b/output/rtsp/rtsp.cc index 430247e..6164212 100644 --- a/output/rtsp/rtsp.cc +++ b/output/rtsp/rtsp.cc @@ -13,13 +13,6 @@ extern "C" { }; -#ifdef USE_RTSP -#if !__has_include() -#undef USE_RTSP -#warning "Missing RTSPServerSupportingHTTPStreaming.hh header. The RTSP support will be missing." -#endif // RTSPServerSupportingHTTPStreaming.hh -#endif // USE_RTSP - #ifdef USE_RTSP #include @@ -32,7 +25,7 @@ extern "C" { #include #include -#include +#include #include #include #include @@ -188,23 +181,24 @@ class DynamicH264VideoFileServerMediaSubsession : public OnDemandServerMediaSubs } }; -class DynamicRTSPServer: public RTSPServerSupportingHTTPStreaming +class DynamicRTSPServer: public RTSPServer { public: static DynamicRTSPServer* createNew(UsageEnvironment& env, Port ourPort, - UserAuthenticationDatabase* authDatabase, - unsigned reclamationTestSeconds = 65) + UserAuthenticationDatabase* authDatabase, + unsigned reclamationSeconds = 65) { - int ourSocket = setUpOurSocket(env, ourPort); - if (ourSocket == -1) return NULL; + int ourSocketIPv4 = setUpOurSocket(env, ourPort, AF_INET); + int ourSocketIPv6 = setUpOurSocket(env, ourPort, AF_INET6); + if (ourSocketIPv4 < 0 && ourSocketIPv6 < 0) return NULL; - return new DynamicRTSPServer(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds); + return new DynamicRTSPServer(env, ourSocketIPv4, ourSocketIPv6, ourPort, authDatabase, reclamationSeconds); } protected: - DynamicRTSPServer(UsageEnvironment& env, int ourSocket, Port ourPort, - UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds) - : RTSPServerSupportingHTTPStreaming(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds) + DynamicRTSPServer(UsageEnvironment& env, int ourSocketIPv4, int ourSocketIPv6, Port ourPort, + UserAuthenticationDatabase* authDatabase, unsigned reclamationSeconds) + : RTSPServer(env, ourSocketIPv4, ourSocketIPv6, ourPort, authDatabase, reclamationSeconds) { } @@ -214,31 +208,56 @@ class DynamicRTSPServer: public RTSPServerSupportingHTTPStreaming } protected: // redefined virtual functions - virtual ServerMediaSession* lookupServerMediaSession(char const* streamName, Boolean isFirstLookupInSession) + virtual void lookupServerMediaSession(char const* streamName, + lookupServerMediaSessionCompletionFunc* completionFunc, + void* completionClientData, + Boolean isFirstLookupInSession = True) { if (strcmp(streamName, stream_name) == 0) { LOG_INFO(NULL, "Requesting %s stream...", streamName); } else { LOG_INFO(NULL, "No stream available: '%s'", streamName); - return NULL; + (*completionFunc)(completionClientData, NULL); + return; } - auto sms = RTSPServer::lookupServerMediaSession(streamName); + struct Ctx { + DynamicRTSPServer* self; + char* name; + lookupServerMediaSessionCompletionFunc* cb; + void* cbData; + Boolean first; + }; + + auto* ctx = new Ctx{ this, strdup(streamName), completionFunc, completionClientData, isFirstLookupInSession }; + + auto thunk = [](void* cd, ServerMediaSession* sms) { + std::unique_ptr w{ static_cast(cd) }; + DynamicRTSPServer* self = w->self; + + if (sms && w->first) { + // Remove the existing "ServerMediaSession" and create a new one, in case the underlying + // file has changed in some way: + self->removeServerMediaSession(sms); + sms = NULL; + } - if (sms && isFirstLookupInSession) { - // Remove the existing "ServerMediaSession" and create a new one, in case the underlying - // file has changed in some way: - removeServerMediaSession(sms); - sms = NULL; - } + if (!sms) { + sms = ServerMediaSession::createNew(self->envir(), + w->name, w->name, + "streamed by the LIVE555 Media Server"); + OutPacketBuffer::maxSize = 2000000; // allow for some possibly large H.264 frames + + auto* subsession = + new DynamicH264VideoFileServerMediaSubsession(self->envir(), False); + sms->addSubsession(subsession); + self->addServerMediaSession(sms); + } - sms = ServerMediaSession::createNew(envir(), streamName, streamName, "streamed by the LIVE555 Media Server");; - OutPacketBuffer::maxSize = 2000000; // allow for some possibly large H.264 frames + (*w->cb)(w->cbData, sms); + }; - auto subsession = new DynamicH264VideoFileServerMediaSubsession(envir(), false); - sms->addSubsession(subsession); - addServerMediaSession(sms); - return sms; + RTSPServer::lookupServerMediaSession(streamName, thunk, ctx, isFirstLookupInSession); } }; From 2a3432fb3c49b49c52fc15f97270d9ce2f3dd836 Mon Sep 17 00:00:00 2001 From: Jannis Pohl <838818+jannispl@users.noreply.github.com> Date: Sat, 9 Aug 2025 13:38:09 +0200 Subject: [PATCH 2/2] rtsp: avoid copying stream name --- output/rtsp/rtsp.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/output/rtsp/rtsp.cc b/output/rtsp/rtsp.cc index 6164212..93748bb 100644 --- a/output/rtsp/rtsp.cc +++ b/output/rtsp/rtsp.cc @@ -223,13 +223,12 @@ class DynamicRTSPServer: public RTSPServer struct Ctx { DynamicRTSPServer* self; - char* name; lookupServerMediaSessionCompletionFunc* cb; void* cbData; Boolean first; }; - auto* ctx = new Ctx{ this, strdup(streamName), completionFunc, completionClientData, isFirstLookupInSession }; + auto* ctx = new Ctx{ this, completionFunc, completionClientData, isFirstLookupInSession }; auto thunk = [](void* cd, ServerMediaSession* sms) { std::unique_ptr w{ static_cast(cd) }; @@ -244,7 +243,7 @@ class DynamicRTSPServer: public RTSPServer if (!sms) { sms = ServerMediaSession::createNew(self->envir(), - w->name, w->name, + stream_name, stream_name, "streamed by the LIVE555 Media Server"); OutPacketBuffer::maxSize = 2000000; // allow for some possibly large H.264 frames