Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package live555 for openSUSE:Factory checked in at 2026-10-24 22:03:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/live555 (Old) and /work/SRC/openSUSE:Factory/.live555.new.2252680 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "live555" Sat Oct 24 22:03:58 2026 rev:51 rq:1392081 version:2026.10.23 Changes: -------- --- /work/SRC/openSUSE:Factory/live555/live555.changes 2026-10-20 12:34:45.137577233 +0200 +++ /work/SRC/openSUSE:Factory/.live555.new.2252680/live555.changes 2026-10-24 22:05:16.687236292 +0200 @@ -1,0 +2,33 @@ +Fri Oct 23 15:48:24 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 2026.10.23: + * The bug fix in version 2026.10.21 was not complete. This should fix it for + real. +- Bump lmdmaj define to 122 following upstream changes. + +------------------------------------------------------------------- +Fri Oct 23 09:18:19 UTC 2026 - Dirk Müller <[email protected]> + +- Fix typos in the description + +------------------------------------------------------------------- +Thu Oct 22 04:01:20 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 2026.10.22: + * Fixed a bug that had accidentally been introduced in version 2026.07.23: We + now correctly parse the "RTP/SAVP" and "RTP/SAVP/TCP" profile strings. + * When a RTSP server is asked to stream RTP/RTSP-over-TCP, we don't record + the TCP socket number to use when we're processing the "SETUP" command. + Instead, we have to wait until we're processing the "PLAY" command, because + the "PLAY" command might be using a different TCP connection (and thus a + different socket number). +- Bump lmdmaj define to 121 following upstream changes. + +------------------------------------------------------------------- +Wed Oct 21 17:06:10 UTC 2026 - Dominique Leuenberger <[email protected]> + +- Update to version 2026.10.21: + * Fixed a bug that could possibly allow a malicious client to cause a RTSP + server to crash when streaming from an AC-3 audio file. + +------------------------------------------------------------------- Old: ---- live.2026.10.17.tar.gz New: ---- live.2026.10.23.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ live555.spec ++++++ --- /var/tmp/diff_new_pack.FJSIL7/_old 2026-10-24 22:05:17.284261278 +0200 +++ /var/tmp/diff_new_pack.FJSIL7/_new 2026-10-24 22:05:17.286261362 +0200 @@ -17,9 +17,9 @@ # -%define lmdmaj 120 +%define lmdmaj 122 Name: live555 -Version: 2026.10.17 +Version: 2026.10.23 Release: 0 Summary: LIVE555 Streaming Media License: LGPL-2.1-only @@ -34,15 +34,15 @@ %description This code forms a set of C++ libraries for multimedia streaming, using open standard protocols (RTP/RTCP, RTSP, SIP). These libraries -can be used to build streaming applications +can be used to build streaming applications. %package -n libliveMedia%{lmdmaj} -Summary: Basic Usage Environment library of live555 streaming media +Summary: Live Media library of live555 streaming media %description -n libliveMedia%{lmdmaj} This code forms a set of C++ libraries for multimedia streaming, using open standard protocols (RTP/RTCP, RTSP, SIP). These libraries -can be used to build streaming applications +can be used to build streaming applications. %package -n libBasicUsageEnvironment2 Summary: Basic Usage Environment library of live555 streaming media @@ -50,7 +50,7 @@ %description -n libBasicUsageEnvironment2 This code forms a set of C++ libraries for multimedia streaming, using open standard protocols (RTP/RTCP, RTSP, SIP). These libraries -can be used to build streaming applications +can be used to build streaming applications. %package -n libgroupsock33 Summary: Group sock library of live555 streaming media @@ -58,7 +58,7 @@ %description -n libgroupsock33 This code forms a set of C++ libraries for multimedia streaming, using open standard protocols (RTP/RTCP, RTSP, SIP). These libraries -can be used to build streaming applications +can be used to build streaming applications. %package -n libUsageEnvironment3 Summary: Usage Environment library of live555 streaming media @@ -66,7 +66,7 @@ %description -n libUsageEnvironment3 This code forms a set of C++ libraries for multimedia streaming, using open standard protocols (RTP/RTCP, RTSP, SIP). These libraries -can be used to build streaming applications +can be used to build streaming applications. %package devel Summary: LIVE555 Streaming Media @@ -80,7 +80,7 @@ %description devel This code forms a set of C++ libraries for multimedia streaming, using open standard protocols (RTP/RTCP, RTSP, SIP). These libraries -can be used to build streaming applications +can be used to build streaming applications. %prep %autosetup -p1 -n live ++++++ live.2026.10.17.tar.gz -> live.2026.10.23.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh new/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh --- old/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh 2026-10-23 02:04:27.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _BASICUSAGEENVIRONMENT_VERSION_HH #define _BASICUSAGEENVIRONMENT_VERSION_HH -#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.10.17" -#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT 1792195200 +#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.10.23" +#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT 1792713600 extern char const* const BasicUsageEnvironmentLibraryVersionStr; extern int const BasicUsageEnvironmentLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/UsageEnvironment/include/UsageEnvironment_version.hh new/live/UsageEnvironment/include/UsageEnvironment_version.hh --- old/live/UsageEnvironment/include/UsageEnvironment_version.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/UsageEnvironment/include/UsageEnvironment_version.hh 2026-10-23 02:04:27.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _USAGEENVIRONMENT_VERSION_HH #define _USAGEENVIRONMENT_VERSION_HH -#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.10.17" -#define USAGEENVIRONMENT_LIBRARY_VERSION_INT 1792195200 +#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.10.23" +#define USAGEENVIRONMENT_LIBRARY_VERSION_INT 1792713600 extern char const* const UsageEnvironmentLibraryVersionStr; extern int const UsageEnvironmentLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/config.linux-with-shared-libraries new/live/config.linux-with-shared-libraries --- old/live/config.linux-with-shared-libraries 2026-10-17 14:48:45.000000000 +0200 +++ new/live/config.linux-with-shared-libraries 2026-10-23 02:04:48.000000000 +0200 @@ -3,8 +3,8 @@ # At least one interface changes, or is removed => CURRENT += 1; REVISION = 0; AGE = 0 # One or more interfaces were added, but no existing interfaces were changed or removed => CURRENT += 1; REVISION = 0; AGE += 1 -libliveMedia_VERSION_CURRENT=120 -libliveMedia_VERSION_REVISION=13 +libliveMedia_VERSION_CURRENT=122 +libliveMedia_VERSION_REVISION=0 libliveMedia_VERSION_AGE=0 libliveMedia_LIB_SUFFIX=so.$(shell expr $(libliveMedia_VERSION_CURRENT) - $(libliveMedia_VERSION_AGE)).$(libliveMedia_VERSION_AGE).$(libliveMedia_VERSION_REVISION) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/groupsock/include/groupsock_version.hh new/live/groupsock/include/groupsock_version.hh --- old/live/groupsock/include/groupsock_version.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/groupsock/include/groupsock_version.hh 2026-10-23 02:04:27.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _GROUPSOCK_VERSION_HH #define _GROUPSOCK_VERSION_HH -#define GROUPSOCK_LIBRARY_VERSION_STRING "2026.10.17" -#define GROUPSOCK_LIBRARY_VERSION_INT 1792195200 +#define GROUPSOCK_LIBRARY_VERSION_STRING "2026.10.23" +#define GROUPSOCK_LIBRARY_VERSION_INT 1792713600 extern char const* const groupsockLibraryVersionStr; extern int const groupsockLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/AC3AudioStreamFramer.cpp new/live/liveMedia/AC3AudioStreamFramer.cpp --- old/live/liveMedia/AC3AudioStreamFramer.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/AC3AudioStreamFramer.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -323,8 +323,7 @@ parser->afterGettingSavedFrame1(frameSize); } -void AC3AudioStreamParser -::afterGettingSavedFrame1(unsigned frameSize) { +void AC3AudioStreamParser::afterGettingSavedFrame1(unsigned frameSize) { fSavedFrameSize = frameSize; fSavedFrameFlag = ~0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/MPEG2TransportFileServerMediaSubsession.cpp new/live/liveMedia/MPEG2TransportFileServerMediaSubsession.cpp --- old/live/liveMedia/MPEG2TransportFileServerMediaSubsession.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/MPEG2TransportFileServerMediaSubsession.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -73,8 +73,9 @@ // The product of these two numbers must be enough to fit within a network packet void MPEG2TransportFileServerMediaSubsession -::startStream(unsigned clientSessionId, void* streamToken, TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, +::startStream(unsigned clientSessionId, void* streamToken, int tcpSocketNum, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, + unsigned short& rtpSeqNum, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, void* serverRequestAlternativeByteHandlerClientData) { @@ -91,7 +92,7 @@ } // Call the original, default version of this routine: - OnDemandServerMediaSubsession::startStream(clientSessionId, streamToken, + OnDemandServerMediaSubsession::startStream(clientSessionId, streamToken, tcpSocketNum, rtcpRRHandler, rtcpRRHandlerClientData, rtpSeqNum, rtpTimestamp, serverRequestAlternativeByteHandler, serverRequestAlternativeByteHandlerClientData); @@ -138,7 +139,7 @@ OnDemandServerMediaSubsession::setStreamScale(clientSessionId, streamToken, scale); } -void MPEG2TransportFileServerMediaSubsession +Boolean MPEG2TransportFileServerMediaSubsession ::deleteStream(unsigned clientSessionId, void*& streamToken) { if (fIndexFile != NULL) { // we support 'trick play' ClientTrickPlayState* client = lookupClient(clientSessionId); @@ -148,7 +149,7 @@ } // Call the original, default version of this routine: - OnDemandServerMediaSubsession::deleteStream(clientSessionId, streamToken); + return OnDemandServerMediaSubsession::deleteStream(clientSessionId, streamToken); } ClientTrickPlayState* MPEG2TransportFileServerMediaSubsession::newClientTrickPlayState() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/OnDemandServerMediaSubsession.cpp new/live/liveMedia/OnDemandServerMediaSubsession.cpp --- old/live/liveMedia/OnDemandServerMediaSubsession.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/OnDemandServerMediaSubsession.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -31,7 +31,7 @@ fSDPLines(NULL), fMIKEYStateMessage(NULL), fMIKEYStateMessageSize(0), fReuseFirstSource(reuseFirstSource), fMultiplexRTCPWithRTP(multiplexRTCPWithRTP), fLastStreamToken(NULL), - fAppHandlerTask(NULL), fAppHandlerClientData(NULL) { + fAppHandlerTask(NULL), fAppHandlerClientData(NULL), fDoNotDisturb(False) { fDestinationsHashTable = HashTable::create(ONE_WORD_HASH_KEYS); if (fMultiplexRTCPWithRTP) { fInitialPortNum = initialPortNum; @@ -115,7 +115,7 @@ struct sockaddr_storage const& clientAddress, Port const& clientRTPPort, Port const& clientRTCPPort, - int tcpSocketNum, + Boolean streamUsingTCP, unsigned char rtpChannelId, unsigned char rtcpChannelId, TLSState* tlsState, @@ -125,6 +125,8 @@ Port& serverRTPPort, Port& serverRTCPPort, void*& streamToken) { + fDoNotDisturb = True; // a hack to prevent a nested inner loop (if any) from deleting our state until we're done + if (addressIsNull(destinationAddress)) { // normal case - use the client address as the destination address: destinationAddress = clientAddress; @@ -151,7 +153,7 @@ Groupsock* rtpGroupsock = NULL; Groupsock* rtcpGroupsock = NULL; - if (clientRTPPort.num() != 0 || tcpSocketNum >= 0) { // Normal case: Create destinations + if (clientRTPPort.num() != 0 || streamUsingTCP) { // Normal case: Create destinations portNumBits serverPortNum; if (clientRTCPPort.num() == 0) { // We're streaming raw UDP (not RTP). Create a single groupsock: @@ -228,33 +230,37 @@ // Record these destinations as being for this client session id: Destinations* destinations; - if (tcpSocketNum < 0) { // UDP + if (streamUsingTCP) { + destinations = new Destinations(rtpChannelId, rtcpChannelId, tlsState); + } else { // UDP destinations = new Destinations(destinationAddress, clientRTPPort, clientRTCPPort); - } else { // TCP - destinations = new Destinations(tcpSocketNum, rtpChannelId, rtcpChannelId, tlsState); } fDestinationsHashTable->Add((char const*)clientSessionId, destinations); + + fDoNotDisturb = False; } -void OnDemandServerMediaSubsession::startStream(unsigned clientSessionId, - void* streamToken, - TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, - unsigned short& rtpSeqNum, - unsigned& rtpTimestamp, - ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, - void* serverRequestAlternativeByteHandlerClientData) { +void OnDemandServerMediaSubsession +::startStream(unsigned clientSessionId, void* streamToken, int tcpSocketNum, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, + unsigned short& rtpSeqNum, + unsigned& rtpTimestamp, + ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, + void* serverRequestAlternativeByteHandlerClientData) { StreamState* streamState = (StreamState*)streamToken; - Destinations* destinations - = (Destinations*)(fDestinationsHashTable->Lookup((char const*)clientSessionId)); if (streamState != NULL) { - streamState->startPlaying(destinations, clientSessionId, - rtcpRRHandler, rtcpRRHandlerClientData, - serverRequestAlternativeByteHandler, serverRequestAlternativeByteHandlerClientData); - RTPSink* rtpSink = streamState->rtpSink(); // alias - if (rtpSink != NULL) { - rtpSeqNum = rtpSink->currentSeqNo(); - rtpTimestamp = rtpSink->presetNextTimestamp(); + Destinations* destinations + = (Destinations*)(fDestinationsHashTable->Lookup((char const*)clientSessionId)); + if (destinations != NULL) { + destinations->tcpSocketNum = tcpSocketNum; + streamState->startPlaying(destinations, clientSessionId, + rtcpRRHandler, rtcpRRHandlerClientData, + serverRequestAlternativeByteHandler, serverRequestAlternativeByteHandlerClientData); + RTPSink* rtpSink = streamState->rtpSink(); // alias + if (rtpSink != NULL) { + rtpSeqNum = rtpSink->currentSeqNo(); + rtpTimestamp = rtpSink->presetNextTimestamp(); + } } } } @@ -364,8 +370,9 @@ rtcp = streamState->rtcpInstance(); } -void OnDemandServerMediaSubsession::deleteStream(unsigned clientSessionId, - void*& streamToken) { +Boolean OnDemandServerMediaSubsession::deleteStream(unsigned clientSessionId, void*& streamToken) { + if (fDoNotDisturb) return False; + StreamState* streamState = (StreamState*)streamToken; // Look up (and remove) the destinations for this client session: @@ -389,6 +396,8 @@ // Finally, delete the destinations themselves: delete destinations; + + return True; } char const* OnDemandServerMediaSubsession @@ -546,8 +555,6 @@ TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, void* serverRequestAlternativeByteHandlerClientData) { - if (dests == NULL) return; - if (fRTCPInstance == NULL && fRTPSink != NULL) { // Create (and start) a 'RTCP instance' for this RTP sink: fRTCPInstance = fMaster.createRTCP(fRTCPgs, fTotalBW, (unsigned char*)fMaster.fCNAME, fRTPSink); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/PassiveServerMediaSubsession.cpp new/live/liveMedia/PassiveServerMediaSubsession.cpp --- old/live/liveMedia/PassiveServerMediaSubsession.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/PassiveServerMediaSubsession.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -149,7 +149,7 @@ struct sockaddr_storage const& clientAddress, Port const& /*clientRTPPort*/, Port const& clientRTCPPort, - int /*tcpSocketNum*/, + Boolean /*streamUsingTCP*/, unsigned char /*rtpChannelId*/, unsigned char /*rtcpChannelId*/, TLSState* /*tlsState*/, @@ -185,14 +185,13 @@ fClientRTCPSourceRecords->Add((char const*)clientSessionId, source); } -void PassiveServerMediaSubsession::startStream(unsigned clientSessionId, - void* /*streamToken*/, - TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, - unsigned short& rtpSeqNum, - unsigned& rtpTimestamp, - ServerRequestAlternativeByteHandler* /*serverRequestAlternativeByteHandler*/, - void* /*serverRequestAlternativeByteHandlerClientData*/) { +void PassiveServerMediaSubsession +::startStream(unsigned clientSessionId, void* /*streamToken*/, int /*tcpSocketNum*/, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, + unsigned short& rtpSeqNum, + unsigned& rtpTimestamp, + ServerRequestAlternativeByteHandler* /*serverRequestAlternativeByteHandler*/, + void* /*serverRequestAlternativeByteHandlerClientData*/) { rtpSeqNum = fRTPSink.currentSeqNo(); rtpTimestamp = fRTPSink.presetNextTimestamp(); @@ -234,7 +233,7 @@ rtcp = fRTCPInstance; } -void PassiveServerMediaSubsession::deleteStream(unsigned clientSessionId, void*& /*streamToken*/) { +Boolean PassiveServerMediaSubsession::deleteStream(unsigned clientSessionId, void*& /*streamToken*/) { // Lookup and remove the 'RTCPSourceRecord' for this client. Also turn off RTCP "RR" handling: RTCPSourceRecord* source = (RTCPSourceRecord*)(fClientRTCPSourceRecords->Lookup((char const*)clientSessionId)); if (source != NULL) { @@ -245,4 +244,6 @@ fClientRTCPSourceRecords->Remove((char const*)clientSessionId); delete source; } + + return True; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/RTSPServer.cpp new/live/liveMedia/RTSPServer.cpp --- old/live/liveMedia/RTSPServer.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/RTSPServer.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -1284,9 +1284,12 @@ void RTSPServer::RTSPClientSession::deleteStreamByTrack(unsigned trackNum) { if (trackNum >= fNumStreamStates) return; // sanity check; shouldn't happen - if (fStreamStates[trackNum].subsession != NULL) { - fStreamStates[trackNum].subsession->deleteStream(fOurSessionId, fStreamStates[trackNum].streamToken); - fStreamStates[trackNum].subsession = NULL; + ServerMediaSubsession*& subsession = fStreamStates[trackNum].subsession; // alias + + if (subsession != NULL) { + if (subsession->deleteStream(fOurSessionId, fStreamStates[trackNum].streamToken)) { + subsession = NULL; + } } // Optimization: If all subsessions have now been deleted, then we can delete ourself now: @@ -1304,7 +1307,7 @@ for (unsigned i = 0; i < fNumStreamStates; ++i) { if (fStreamStates[i].subsession != NULL) { fOurRTSPServer.unnoteTCPStreamingOnSocket(fStreamStates[i].tcpSocketNum, this, i); - fStreamStates[i].subsession->deleteStream(fOurSessionId, fStreamStates[i].streamToken); + (void)fStreamStates[i].subsession->deleteStream(fOurSessionId, fStreamStates[i].streamToken); } } delete[] fStreamStates; fStreamStates = NULL; @@ -1356,11 +1359,11 @@ char* field = strDupSize(fields); while (sscanf(fields, "%[^;\r\n]", field) == 1) { badFieldSeen = True; // until we learn otherwise - if (strcmp(field, "RTP/AVP/TCP") == 0) { + if (strcmp(field, "RTP/AVP/TCP") == 0 || strcmp(field, "RTP/SAVP/TCP") == 0) { if (streamingMode != UNKNOWN) break; // more than one 'streaming mode' is not allowed streamingMode = RTP_TCP; - } else if (strcmp(field, "RTP/AVP") == 0 || strcmp(field, "RTP/AVP/SAVP") == 0) { + } else if (strcmp(field, "RTP/AVP") == 0 || strcmp(field, "RTP/SAVP") == 0) { if (streamingMode != UNKNOWN) break; // more than one 'streaming mode' is not allowed streamingMode = RTP_UDP; @@ -1572,6 +1575,7 @@ for (unsigned i = 0; i < fNumStreamStates; ++i) { subsession = iter.next(); fStreamStates[i].subsession = subsession; + fStreamStates[i].streamUsingTCP = False; // for now fStreamStates[i].tcpSocketNum = -1; // for now; may get set for RTP-over-TCP streaming fStreamStates[i].streamToken = NULL; // for now; it may be changed by the "getStreamParameters()" call that comes later } @@ -1658,14 +1662,13 @@ // so stop any existing streaming of it, before we set it up again: subsession->pauseStream(fOurSessionId, token); fOurRTSPServer.unnoteTCPStreamingOnSocket(fStreamStates[trackNum].tcpSocketNum, this, trackNum); - subsession->deleteStream(fOurSessionId, token); + fStreamStates[trackNum].streamUsingTCP = False; fStreamStates[trackNum].tcpSocketNum = -1; + (void)subsession->deleteStream(fOurSessionId, token); } // Then, get server parameters from the 'subsession': if (streamingMode == RTP_TCP) { - // Note that we'll be streaming over the RTSP TCP connection: - fStreamStates[trackNum].tcpSocketNum = ourClientConnection->fClientOutputSocket; - fOurRTSPServer.noteTCPStreamingOnSocket(fStreamStates[trackNum].tcpSocketNum, this, trackNum); + fStreamStates[trackNum].streamUsingTCP = True; } struct sockaddr_storage destinationAddress = nullAddress(); // used to indicate that the address is 'unassigned' @@ -1698,8 +1701,7 @@ subsession->getStreamParameters(fOurSessionId, ourClientConnection->fClientAddr, clientRTPPort, clientRTCPPort, - streamingMode == RTP_TCP - ? fStreamStates[trackNum].tcpSocketNum : -1, + streamingMode == RTP_TCP, rtpChannelId, rtcpChannelId, &ourClientConnection->fTLS, destinationAddress, destinationTTL, fIsMulticast, @@ -1878,12 +1880,13 @@ unsigned i; for (i = 0; i < fNumStreamStates; ++i) { - if (subsession == NULL /* means: aggregated operation */ - || subsession == fStreamStates[i].subsession) { - if (fStreamStates[i].subsession != NULL) { + ServerMediaSubsession*& ssss = fStreamStates[i].subsession; // alias + if (subsession == NULL /* means: aggregated operation */ || subsession == ssss) { + if (ssss != NULL) { fOurRTSPServer.unnoteTCPStreamingOnSocket(fStreamStates[i].tcpSocketNum, this, i); - fStreamStates[i].subsession->deleteStream(fOurSessionId, fStreamStates[i].streamToken); - fStreamStates[i].subsession = NULL; + if (ssss->deleteStream(fOurSessionId, fStreamStates[i].streamToken)) { + ssss = NULL; + } } } } @@ -2070,8 +2073,15 @@ unsigned short rtpSeqNum = 0; unsigned rtpTimestamp = 0; if (fStreamStates[i].subsession == NULL) continue; + + if (fStreamStates[i].streamUsingTCP) { + // Note that we'll be streaming over the RTSP TCP connection: + fStreamStates[i].tcpSocketNum = ourClientConnection->fClientOutputSocket; + fOurRTSPServer.noteTCPStreamingOnSocket(fStreamStates[i].tcpSocketNum, this, i); + } fStreamStates[i].subsession->startStream(fOurSessionId, fStreamStates[i].streamToken, + fStreamStates[i].tcpSocketNum, (TaskFunc*)noteClientLiveness, this, rtpSeqNum, rtpTimestamp, RTSPServer::RTSPClientConnection::handleAlternativeRequestByte, ourClientConnection); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/ServerMediaSession.cpp new/live/liveMedia/ServerMediaSession.cpp --- old/live/liveMedia/ServerMediaSession.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/ServerMediaSession.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -410,9 +410,10 @@ // default implementation: return NULL return NULL; } -void ServerMediaSubsession::deleteStream(unsigned /*clientSessionId*/, +Boolean ServerMediaSubsession::deleteStream(unsigned /*clientSessionId*/, void*& /*streamToken*/) { // default implementation: do nothing + return True; } void ServerMediaSubsession::testScaleFactor(float& scale) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/MPEG2TransportFileServerMediaSubsession.hh new/live/liveMedia/include/MPEG2TransportFileServerMediaSubsession.hh --- old/live/liveMedia/include/MPEG2TransportFileServerMediaSubsession.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/include/MPEG2TransportFileServerMediaSubsession.hh 2026-10-23 02:04:27.000000000 +0200 @@ -62,9 +62,8 @@ // more than just the input source, we reimplement some functions that are // already implemented in "OnDemandServerMediaSubsession", rather than // reimplementing "seekStreamSource()" and "setStreamSourceScale()": - virtual void startStream(unsigned clientSessionId, void* streamToken, - TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, + virtual void startStream(unsigned clientSessionId, void* streamToken, int tcpSocketNum, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, @@ -72,7 +71,7 @@ virtual void pauseStream(unsigned clientSessionId, void* streamToken); virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes); virtual void setStreamScale(unsigned clientSessionId, void* streamToken, float scale); - virtual void deleteStream(unsigned clientSessionId, void*& streamToken); + virtual Boolean deleteStream(unsigned clientSessionId, void*& streamToken); // The virtual functions that are usually implemented by "ServerMediaSubsession"s: virtual FramedSource* createNewStreamSource(unsigned clientSessionId, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/OnDemandServerMediaSubsession.hh new/live/liveMedia/include/OnDemandServerMediaSubsession.hh --- old/live/liveMedia/include/OnDemandServerMediaSubsession.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/include/OnDemandServerMediaSubsession.hh 2026-10-23 02:04:27.000000000 +0200 @@ -48,7 +48,7 @@ struct sockaddr_storage const& clientAddress, Port const& clientRTPPort, Port const& clientRTCPPort, - int tcpSocketNum, + Boolean streamUsingTCP, unsigned char rtpChannelId, unsigned char rtcpChannelId, TLSState* tlsState, @@ -58,9 +58,8 @@ Port& serverRTPPort, Port& serverRTCPPort, void*& streamToken); - virtual void startStream(unsigned clientSessionId, void* streamToken, - TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, + virtual void startStream(unsigned clientSessionId, void* streamToken, int tcpSocketNum, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, @@ -75,7 +74,7 @@ virtual FramedSource* getStreamSource(void* streamToken); virtual void getRTPSinkandRTCP(void* streamToken, RTPSink*& rtpSink, RTCPInstance*& rtcp); - virtual void deleteStream(unsigned clientSessionId, void*& streamToken); + virtual Boolean deleteStream(unsigned clientSessionId, void*& streamToken); protected: // new virtual functions, possibly redefined by subclasses virtual char const* getAuxSDPLine(RTPSink* rtpSink, @@ -145,6 +144,7 @@ char fCNAME[100]; // for RTCP RTCPAppHandlerFunc* fAppHandlerTask; void* fAppHandlerClientData; + Boolean fDoNotDisturb; friend class StreamState; }; @@ -158,12 +158,13 @@ Destinations(struct sockaddr_storage const& destAddr, Port const& rtpDestPort, Port const& rtcpDestPort) - : isTCP(False), addr(destAddr), rtpPort(rtpDestPort), rtcpPort(rtcpDestPort) { + : isTCP(False), addr(destAddr), rtpPort(rtpDestPort), rtcpPort(rtcpDestPort), + tcpSocketNum(-1), rtpChannelId(0 /*dummy*/), rtcpChannelId(1 /*dummy*/), + tlsState(NULL) { } - Destinations(int tcpSockNum, unsigned char rtpChanId, unsigned char rtcpChanId, - TLSState* tlsSt) + Destinations(unsigned char rtpChanId, unsigned char rtcpChanId, TLSState* tlsSt) : isTCP(True), rtpPort(0) /*dummy*/, rtcpPort(0) /*dummy*/, - tcpSocketNum(tcpSockNum), rtpChannelId(rtpChanId), rtcpChannelId(rtcpChanId), + tcpSocketNum(-1/*set later*/), rtpChannelId(rtpChanId), rtcpChannelId(rtcpChanId), tlsState(tlsSt) { } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/PassiveServerMediaSubsession.hh new/live/liveMedia/include/PassiveServerMediaSubsession.hh --- old/live/liveMedia/include/PassiveServerMediaSubsession.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/include/PassiveServerMediaSubsession.hh 2026-10-23 02:04:27.000000000 +0200 @@ -51,7 +51,7 @@ struct sockaddr_storage const& clientAddress, Port const& clientRTPPort, Port const& clientRTCPPort, - int tcpSocketNum, + Boolean streamUsingTCP, unsigned char rtpChannelId, unsigned char rtcpChannelId, TLSState* tlsSTate, @@ -61,9 +61,8 @@ Port& serverRTPPort, Port& serverRTCPPort, void*& streamToken); - virtual void startStream(unsigned clientSessionId, void* streamToken, - TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, + virtual void startStream(unsigned clientSessionId, void* streamToken, int tcpSocketNum, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, @@ -71,7 +70,7 @@ virtual float getCurrentNPT(void* streamToken); virtual void getRTPSinkandRTCP(void* streamToken, RTPSink*& rtpSink, RTCPInstance*& rtcp); - virtual void deleteStream(unsigned clientSessionId, void*& streamToken); + virtual Boolean deleteStream(unsigned clientSessionId, void*& streamToken); protected: char* fSDPLines; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/RTSPServer.hh new/live/liveMedia/include/RTSPServer.hh --- old/live/liveMedia/include/RTSPServer.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/include/RTSPServer.hh 2026-10-23 02:04:27.000000000 +0200 @@ -292,6 +292,7 @@ unsigned fNumStreamStates; struct streamState { ServerMediaSubsession* subsession; + Boolean streamUsingTCP; int tcpSocketNum; void* streamToken; } * fStreamStates; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/ServerMediaSession.hh new/live/liveMedia/include/ServerMediaSession.hh --- old/live/liveMedia/include/ServerMediaSession.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/include/ServerMediaSession.hh 2026-10-23 02:04:27.000000000 +0200 @@ -129,7 +129,7 @@ struct sockaddr_storage const& clientAddress, // in Port const& clientRTPPort, // in Port const& clientRTCPPort, // in - int tcpSocketNum, // in (-1 means use UDP, not TCP) + Boolean streamUsingTCP, // in unsigned char rtpChannelId, // in (used if TCP) unsigned char rtcpChannelId, // in (used if TCP) TLSState* tlsState, // in (used if TCP) @@ -140,9 +140,8 @@ Port& serverRTCPPort, // out void*& streamToken // out ) = 0; - virtual void startStream(unsigned clientSessionId, void* streamToken, - TaskFunc* rtcpRRHandler, - void* rtcpRRHandlerClientData, + virtual void startStream(unsigned clientSessionId, void* streamToken, int tcpSocketNum, + TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, @@ -170,7 +169,7 @@ // (This can be useful if you want to get the associated 'Groupsock' objects, for example.) // You must not delete these objects, or start/stop playing them; instead, that is done // using the "startStream()" and "deleteStream()" functions. - virtual void deleteStream(unsigned clientSessionId, void*& streamToken); + virtual Boolean deleteStream(unsigned clientSessionId, void*& streamToken); virtual void testScaleFactor(float& scale); // sets "scale" to the actual supported scale virtual float duration() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/liveMedia_version.hh new/live/liveMedia/include/liveMedia_version.hh --- old/live/liveMedia/include/liveMedia_version.hh 2026-10-17 14:48:11.000000000 +0200 +++ new/live/liveMedia/include/liveMedia_version.hh 2026-10-23 02:04:27.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _LIVEMEDIA_VERSION_HH #define _LIVEMEDIA_VERSION_HH -#define LIVEMEDIA_LIBRARY_VERSION_STRING "2026.10.17" -#define LIVEMEDIA_LIBRARY_VERSION_INT 1792195200 +#define LIVEMEDIA_LIBRARY_VERSION_STRING "2026.10.23" +#define LIVEMEDIA_LIBRARY_VERSION_INT 1792713600 extern char const* const liveMediaLibraryVersionStr; extern int const liveMediaLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/testProgs/testRTSPClient.cpp new/live/testProgs/testRTSPClient.cpp --- old/live/testProgs/testRTSPClient.cpp 2026-10-17 14:48:11.000000000 +0200 +++ new/live/testProgs/testRTSPClient.cpp 2026-10-23 02:04:27.000000000 +0200 @@ -170,7 +170,7 @@ void openURL(UsageEnvironment& env, char const* progName, char const* rtspURL) { // Begin by creating a "RTSPClient" object. Note that there is a separate "RTSPClient" object for each stream that we wish - // to receive (even if more than stream uses the same "rtsp://" URL). + // to receive (even if more than one stream uses the same "rtsp://" URL). RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, progName); if (rtspClient == NULL) { env << "Failed to create a RTSP client for URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n";
