Skip to content

Commit

Permalink
Updated to live555 2021.11.01
Browse files Browse the repository at this point in the history
  • Loading branch information
greenjava committed Nov 1, 2021
1 parent 7be67f6 commit d54836b
Show file tree
Hide file tree
Showing 19 changed files with 217 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ along with this library; if not, write to the Free Software Foundation, Inc.,
#ifndef _BASICUSAGEENVIRONMENT_VERSION_HH
#define _BASICUSAGEENVIRONMENT_VERSION_HH

#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING "2021.08.24"
#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT 1629763200
#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING "2021.11.01"
#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT 1635724800

#endif
4 changes: 2 additions & 2 deletions UsageEnvironment/include/UsageEnvironment_version.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ along with this library; if not, write to the Free Software Foundation, Inc.,
#ifndef _USAGEENVIRONMENT_VERSION_HH
#define _USAGEENVIRONMENT_VERSION_HH

#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING "2021.08.24"
#define USAGEENVIRONMENT_LIBRARY_VERSION_INT 1629763200
#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING "2021.11.01"
#define USAGEENVIRONMENT_LIBRARY_VERSION_INT 1635724800

#endif
4 changes: 2 additions & 2 deletions config.linux-with-shared-libraries
Original file line number Diff line number Diff line change
Expand Up @@ -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=97
libliveMedia_VERSION_REVISION=3
libliveMedia_VERSION_CURRENT=99
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)

Expand Down
4 changes: 2 additions & 2 deletions groupsock/include/groupsock_version.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ along with this library; if not, write to the Free Software Foundation, Inc.,
#ifndef _GROUPSOCK_VERSION_HH
#define _GROUPSOCK_VERSION_HH

#define GROUPSOCK_LIBRARY_VERSION_STRING "2021.08.24"
#define GROUPSOCK_LIBRARY_VERSION_INT 1629763200
#define GROUPSOCK_LIBRARY_VERSION_STRING "2021.11.01"
#define GROUPSOCK_LIBRARY_VERSION_INT 1635724800

#endif
2 changes: 1 addition & 1 deletion liveMedia/Makefile.tail
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ FramedFilter.$(CPP): include/FramedFilter.hh
include/FramedFilter.hh: include/FramedSource.hh
RTPSource.$(CPP): include/RTPSource.hh
include/RTPSource.hh: include/FramedSource.hh include/RTPInterface.hh include/SRTPCryptographicContext.hh
include/RTPInterface.hh: include/Media.hh
include/RTPInterface.hh: include/Media.hh include/TLSState.hh
MultiFramedRTPSource.$(CPP): include/MultiFramedRTPSource.hh include/RTCP.hh
include/MultiFramedRTPSource.hh: include/RTPSource.hh
SimpleRTPSource.$(CPP): include/SimpleRTPSource.hh
Expand Down
1 change: 1 addition & 0 deletions liveMedia/MatroskaFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@ void MatroskaFileParser::deliverFrameBytes() {

MatroskaDemuxedTrack* demuxedTrack = fOurDemux->lookupDemuxedTrack(fBlockTrackNumber);
if (demuxedTrack == NULL) break; // shouldn't happen
if (!demuxedTrack->isCurrentlyAwaitingData()) return; // wait until we're asked for data

unsigned const BANK_SIZE = bankSize();
while (fCurFrameNumBytesToGet > 0) {
Expand Down
12 changes: 6 additions & 6 deletions liveMedia/RTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,27 +379,27 @@ void RTCPInstance::sendAppPacket(u_int8_t subtype, char const* name,
sendBuiltPacket();
}

void RTCPInstance::setStreamSocket(int sockNum,
unsigned char streamChannelId) {
void RTCPInstance::setStreamSocket(int sockNum, unsigned char streamChannelId,
TLSState* tlsState) {
// Turn off background read handling:
fRTCPInterface.stopNetworkReading();

// Switch to RTCP-over-TCP:
fRTCPInterface.setStreamSocket(sockNum, streamChannelId);
fRTCPInterface.setStreamSocket(sockNum, streamChannelId, tlsState);

// Turn background reading back on:
TaskScheduler::BackgroundHandlerProc* handler
= (TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;
fRTCPInterface.startNetworkReading(handler);
}

void RTCPInstance::addStreamSocket(int sockNum,
unsigned char streamChannelId) {
void RTCPInstance::addStreamSocket(int sockNum, unsigned char streamChannelId,
TLSState* tlsState) {
// First, turn off background read handling for the default (UDP) socket:
envir().taskScheduler().turnOffBackgroundReadHandling(fRTCPInterface.gs()->socketNum());

// Add the RTCP-over-TCP interface:
fRTCPInterface.addStreamSocket(sockNum, streamChannelId);
fRTCPInterface.addStreamSocket(sockNum, streamChannelId, tlsState);

// Turn on background reading for this socket (in case it's not on already):
TaskScheduler::BackgroundHandlerProc* handler
Expand Down
78 changes: 50 additions & 28 deletions liveMedia/RTPInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ along with this library; if not, write to the Free Software Foundation, Inc.,
class tcpStreamRecord {
public:
tcpStreamRecord(int streamSocketNum, unsigned char streamChannelId,
TLSState* tlsState,
tcpStreamRecord* next);
virtual ~tcpStreamRecord();

public:
tcpStreamRecord* fNext;
int fStreamSocketNum;
unsigned char fStreamChannelId;
TLSState* fTLSState;
};

// Reading RTP-over-TCP is implemented using two levels of hash tables.
Expand All @@ -59,7 +61,7 @@ static HashTable* socketHashTable(UsageEnvironment& env, Boolean createIfNotPres

class SocketDescriptor {
public:
SocketDescriptor(UsageEnvironment& env, int socketNum);
SocketDescriptor(UsageEnvironment& env, int socketNum, TLSState* tlsState);
virtual ~SocketDescriptor();

void registerRTPInterface(unsigned char streamChannelId,
Expand All @@ -79,6 +81,7 @@ class SocketDescriptor {
private:
UsageEnvironment& fEnv;
int fOurSocketNum;
TLSState* fTLSState;
HashTable* fSubChannelHashTable;
ServerRequestAlternativeByteHandler* fServerRequestAlternativeByteHandler;
void* fServerRequestAlternativeByteHandlerClientData;
Expand All @@ -87,15 +90,17 @@ class SocketDescriptor {
enum { AWAITING_DOLLAR, AWAITING_STREAM_CHANNEL_ID, AWAITING_SIZE1, AWAITING_SIZE2, AWAITING_PACKET_DATA } fTCPReadingState;
};

static SocketDescriptor* lookupSocketDescriptor(UsageEnvironment& env, int sockNum, Boolean createIfNotFound = True) {
static SocketDescriptor*
lookupSocketDescriptor(UsageEnvironment& env, int sockNum, TLSState* tlsState = NULL,
Boolean createIfNotFound = True) {
HashTable* table = socketHashTable(env, createIfNotFound);
if (table == NULL) return NULL;

char const* key = (char const*)(long)sockNum;
SocketDescriptor* socketDescriptor = (SocketDescriptor*)(table->Lookup(key));
if (socketDescriptor == NULL) {
if (createIfNotFound) {
socketDescriptor = new SocketDescriptor(env, sockNum);
socketDescriptor = new SocketDescriptor(env, sockNum, tlsState);
table->Add((char const*)(long)(sockNum), socketDescriptor);
} else if (table->IsEmpty()) {
// We can also delete the table (to reclaim space):
Expand Down Expand Up @@ -130,7 +135,7 @@ RTPInterface::RTPInterface(Medium* owner, Groupsock* gs)
: fOwner(owner), fGS(gs),
fTCPStreams(NULL),
fNextTCPReadSize(0), fNextTCPReadStreamSocketNum(-1),
fNextTCPReadStreamChannelId(0xFF), fReadHandlerProc(NULL),
fNextTCPReadStreamChannelId(0xFF), fNextTCPReadTLSState(NULL), fReadHandlerProc(NULL),
fAuxReadHandlerFunc(NULL), fAuxReadHandlerClientData(NULL) {
// Make the socket non-blocking, even though it will be read from only asynchronously, when packets arrive.
// The reason for this is that, in some OSs, reads on a blocking socket can (allegedly) sometimes block,
Expand All @@ -145,17 +150,17 @@ RTPInterface::~RTPInterface() {
delete fTCPStreams;
}

void RTPInterface::setStreamSocket(int sockNum,
unsigned char streamChannelId) {
void RTPInterface::setStreamSocket(int sockNum, unsigned char streamChannelId,
TLSState* tlsState) {
fGS->removeAllDestinations();
envir().taskScheduler().disableBackgroundHandling(fGS->socketNum()); // turn off any reading on our datagram socket
fGS->reset(); // and close our datagram socket, because we won't be using it anymore

addStreamSocket(sockNum, streamChannelId);
addStreamSocket(sockNum, streamChannelId, tlsState);
}

void RTPInterface::addStreamSocket(int sockNum,
unsigned char streamChannelId) {
void RTPInterface::addStreamSocket(int sockNum, unsigned char streamChannelId,
TLSState* tlsState) {
if (sockNum < 0) return;

for (tcpStreamRecord* streams = fTCPStreams; streams != NULL;
Expand All @@ -166,15 +171,15 @@ void RTPInterface::addStreamSocket(int sockNum,
}
}

fTCPStreams = new tcpStreamRecord(sockNum, streamChannelId, fTCPStreams);
fTCPStreams = new tcpStreamRecord(sockNum, streamChannelId, tlsState, fTCPStreams);

// Also, make sure this new socket is set up for receiving RTP/RTCP-over-TCP:
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(envir(), sockNum);
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(envir(), sockNum, tlsState);
socketDescriptor->registerRTPInterface(streamChannelId, this);
}

static void deregisterSocket(UsageEnvironment& env, int sockNum, unsigned char streamChannelId) {
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(env, sockNum, False);
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(env, sockNum, NULL, False);
if (socketDescriptor != NULL) {
socketDescriptor->deregisterRTPInterface(streamChannelId);
// Note: This may delete "socketDescriptor",
Expand Down Expand Up @@ -216,7 +221,7 @@ void RTPInterface::removeStreamSocket(int sockNum,

void RTPInterface::setServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum,
ServerRequestAlternativeByteHandler* handler, void* clientData) {
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(env, socketNum, False);
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(env, socketNum, NULL, False);

if (socketDescriptor != NULL) socketDescriptor->setServerRequestAlternativeByteHandler(handler, clientData);
}
Expand All @@ -236,7 +241,8 @@ Boolean RTPInterface::sendPacket(unsigned char* packet, unsigned packetSize) {
for (tcpStreamRecord* stream = fTCPStreams; stream != NULL; stream = nextStream) {
nextStream = stream->fNext; // Set this now, in case the following deletes "stream":
if (!sendRTPorRTCPPacketOverTCP(packet, packetSize,
stream->fStreamSocketNum, stream->fStreamChannelId)) {
stream->fStreamSocketNum, stream->fStreamChannelId,
stream->fTLSState)) {
success = False;
}
}
Expand Down Expand Up @@ -288,9 +294,11 @@ Boolean RTPInterface::handleRead(unsigned char* buffer, unsigned bufferMaxSize,
((sockaddr_in&)fromAddress).sin_addr.s_addr = 0;
((sockaddr_in&)fromAddress).sin_port = 0;

while ((curBytesRead = readSocket(envir(), fNextTCPReadStreamSocketNum,
&buffer[bytesRead], curBytesToRead,
fromAddress)) > 0) {
while ((curBytesRead = (fNextTCPReadTLSState != NULL && fNextTCPReadTLSState->isNeeded)
? fNextTCPReadTLSState->read(&buffer[bytesRead], curBytesToRead)
: readSocket(envir(), fNextTCPReadStreamSocketNum,
&buffer[bytesRead], curBytesToRead,
fromAddress)) > 0) {
bytesRead += curBytesRead;
if (bytesRead >= totBytesToRead) break;
curBytesToRead -= curBytesRead;
Expand Down Expand Up @@ -332,7 +340,8 @@ void RTPInterface::stopNetworkReading() {
////////// Helper Functions - Implementation /////////

Boolean RTPInterface::sendRTPorRTCPPacketOverTCP(u_int8_t* packet, unsigned packetSize,
int socketNum, unsigned char streamChannelId) {
int socketNum, unsigned char streamChannelId,
TLSState* tlsState) {
#ifdef DEBUG_SEND
fprintf(stderr, "sendRTPorRTCPPacketOverTCP: %d bytes over channel %d (socket %d)\n",
packetSize, streamChannelId, socketNum); fflush(stderr);
Expand All @@ -348,9 +357,9 @@ Boolean RTPInterface::sendRTPorRTCPPacketOverTCP(u_int8_t* packet, unsigned pack
framingHeader[1] = streamChannelId;
framingHeader[2] = (u_int8_t) ((packetSize&0xFF00)>>8);
framingHeader[3] = (u_int8_t) (packetSize&0xFF);
if (!sendDataOverTCP(socketNum, framingHeader, 4, False)) break;
if (!sendDataOverTCP(socketNum, tlsState, framingHeader, 4, False)) break;

if (!sendDataOverTCP(socketNum, packet, packetSize, True)) break;
if (!sendDataOverTCP(socketNum, tlsState, packet, packetSize, True)) break;
#ifdef DEBUG_SEND
fprintf(stderr, "sendRTPorRTCPPacketOverTCP: completed\n"); fflush(stderr);
#endif
Expand All @@ -368,8 +377,12 @@ Boolean RTPInterface::sendRTPorRTCPPacketOverTCP(u_int8_t* packet, unsigned pack
#define RTPINTERFACE_BLOCKING_WRITE_TIMEOUT_MS 500
#endif

Boolean RTPInterface::sendDataOverTCP(int socketNum, u_int8_t const* data, unsigned dataSize, Boolean forceSendToSucceed) {
int sendResult = send(socketNum, (char const*)data, dataSize, 0/*flags*/);
Boolean RTPInterface::sendDataOverTCP(int socketNum, TLSState* tlsState,
u_int8_t const* data, unsigned dataSize,
Boolean forceSendToSucceed) {
int sendResult = (tlsState != NULL && tlsState->isNeeded)
? tlsState->write((char const*)data, dataSize)
: send(socketNum, (char const*)data, dataSize, 0/*flags*/);
if (sendResult < (int)dataSize) {
// The TCP send() failed - at least partially.

Expand All @@ -383,7 +396,9 @@ Boolean RTPInterface::sendDataOverTCP(int socketNum, u_int8_t const* data, unsig
fprintf(stderr, "sendDataOverTCP: resending %d-byte send (blocking)\n", numBytesRemainingToSend); fflush(stderr);
#endif
makeSocketBlocking(socketNum, RTPINTERFACE_BLOCKING_WRITE_TIMEOUT_MS);
sendResult = send(socketNum, (char const*)(&data[numBytesSentSoFar]), numBytesRemainingToSend, 0/*flags*/);
sendResult = (tlsState != NULL && tlsState->isNeeded)
? tlsState->write((char const*)(&data[numBytesSentSoFar]), numBytesRemainingToSend)
: send(socketNum, (char const*)(&data[numBytesSentSoFar]), numBytesRemainingToSend, 0/*flags*/);
if ((unsigned)sendResult != numBytesRemainingToSend) {
// The blocking "send()" failed, or timed out. In either case, we assume that the
// TCP connection has failed (or is 'hanging' indefinitely), and we stop using it
Expand Down Expand Up @@ -411,8 +426,8 @@ Boolean RTPInterface::sendDataOverTCP(int socketNum, u_int8_t const* data, unsig
return True;
}

SocketDescriptor::SocketDescriptor(UsageEnvironment& env, int socketNum)
:fEnv(env), fOurSocketNum(socketNum),
SocketDescriptor::SocketDescriptor(UsageEnvironment& env, int socketNum, TLSState* tlsState)
: fEnv(env), fOurSocketNum(socketNum), fTLSState(tlsState),
fSubChannelHashTable(HashTable::create(ONE_WORD_HASH_KEYS)),
fServerRequestAlternativeByteHandler(NULL), fServerRequestAlternativeByteHandlerClientData(NULL),
fReadErrorOccurred(False), fDeleteMyselfNext(False), fAreInReadHandlerLoop(False), fTCPReadingState(AWAITING_DOLLAR) {
Expand Down Expand Up @@ -513,7 +528,9 @@ Boolean SocketDescriptor::tcpReadHandler1(int mask) {
u_int8_t c;
struct sockaddr_storage dummy; // not used
if (fTCPReadingState != AWAITING_PACKET_DATA) {
int result = readSocket(fEnv, fOurSocketNum, &c, 1, dummy);
int result = (fTLSState != NULL && fTLSState->isNeeded)
? fTLSState->read(&c, 1)
: readSocket(fEnv, fOurSocketNum, &c, 1, dummy);
if (result == 0) { // There was no more data to read
return False;
} else if (result != 1) { // error reading TCP socket, so we will no longer handle it
Expand Down Expand Up @@ -573,6 +590,7 @@ Boolean SocketDescriptor::tcpReadHandler1(int mask) {
rtpInterface->fNextTCPReadSize = size;
rtpInterface->fNextTCPReadStreamSocketNum = fOurSocketNum;
rtpInterface->fNextTCPReadStreamChannelId = fStreamChannelId;
rtpInterface->fNextTCPReadTLSState = fTLSState;
}
fTCPReadingState = AWAITING_PACKET_DATA;
break;
Expand All @@ -597,7 +615,9 @@ Boolean SocketDescriptor::tcpReadHandler1(int mask) {
#ifdef DEBUG_RECEIVE
fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): No handler proc for \"rtpInterface\" for channel %d; need to skip %d remaining bytes\n", fOurSocketNum, fStreamChannelId, rtpInterface->fNextTCPReadSize);
#endif
int result = readSocket(fEnv, fOurSocketNum, &c, 1, dummy);
int result = (fTLSState != NULL && fTLSState->isNeeded)
? fTLSState->read(&c, 1)
: readSocket(fEnv, fOurSocketNum, &c, 1, dummy);
if (result < 0) { // error reading TCP socket, so we will no longer handle it
#ifdef DEBUG_RECEIVE
fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): readSocket(1 byte) returned %d (error)\n", fOurSocketNum, result);
Expand Down Expand Up @@ -628,9 +648,11 @@ Boolean SocketDescriptor::tcpReadHandler1(int mask) {

tcpStreamRecord
::tcpStreamRecord(int streamSocketNum, unsigned char streamChannelId,
TLSState* tlsState,
tcpStreamRecord* next)
: fNext(next),
fStreamSocketNum(streamSocketNum), fStreamChannelId(streamChannelId) {
fStreamSocketNum(streamSocketNum), fStreamChannelId(streamChannelId),
fTLSState(tlsState) {
}

tcpStreamRecord::~tcpStreamRecord() {
Expand Down
6 changes: 2 additions & 4 deletions liveMedia/RTSPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ unsigned RTSPClient::sendSetupCommand(MediaSubsession& subsession, responseHandl
Boolean streamOutgoing, Boolean streamUsingTCP, Boolean forceMulticastOnUnspecified,
Authenticator* authenticator) {
if (fTunnelOverHTTPPortNum != 0) streamUsingTCP = True; // RTSP-over-HTTP tunneling uses TCP (by definition)
// However, if we're using a TLS connection, streaming over TCP doesn't work, so disable it:
if (fTLS.isNeeded) streamUsingTCP = False;
if (fCurrentAuthenticator < authenticator) fCurrentAuthenticator = *authenticator;

u_int32_t booleanFlags = 0;
Expand Down Expand Up @@ -1253,13 +1251,13 @@ Boolean RTSPClient::handleSETUPResponse(MediaSubsession& subsession, char const*
if (streamUsingTCP) {
// Tell the subsession to receive RTP (and send/receive RTCP) over the RTSP stream:
if (subsession.rtpSource() != NULL) {
subsession.rtpSource()->setStreamSocket(fInputSocketNum, subsession.rtpChannelId);
subsession.rtpSource()->setStreamSocket(fInputSocketNum, subsession.rtpChannelId, &fTLS);
// So that we continue to receive & handle RTSP commands and responses from the server
subsession.rtpSource()->enableRTCPReports() = False;
// To avoid confusing the server (which won't start handling RTP/RTCP-over-TCP until "PLAY"), don't send RTCP "RR"s yet
increaseReceiveBufferTo(envir(), fInputSocketNum, 50*1024);
}
if (subsession.rtcpInstance() != NULL) subsession.rtcpInstance()->setStreamSocket(fInputSocketNum, subsession.rtcpChannelId);
if (subsession.rtcpInstance() != NULL) subsession.rtcpInstance()->setStreamSocket(fInputSocketNum, subsession.rtcpChannelId, &fTLS);
RTPInterface::setServerRequestAlternativeByteHandler(envir(), fInputSocketNum, handleAlternativeRequestByte, this);
} else {
// Normal case.
Expand Down
Loading

0 comments on commit d54836b

Please sign in to comment.