HLS comment connection deletion that make crash

pull/33/head
mpromonet 9 years ago
parent 8a593ab42f
commit 5ff2e9abb4

@ -34,14 +34,6 @@ class HLSServer : public RTSPServer
: RTSPServer::RTSPClientConnection(ourServer, clientSocket, clientAddr), fClientSessionId(0), fTCPSink(NULL) { : RTSPServer::RTSPClientConnection(ourServer, clientSocket, clientAddr), fClientSessionId(0), fTCPSink(NULL) {
} }
~HLSClientConnection() {
if (fTCPSink != NULL)
{
fTCPSink->stopPlaying();
Medium::close(fTCPSink);
}
}
private: private:
void sendHeader(const char* contentType, unsigned int contentLength) void sendHeader(const char* contentType, unsigned int contentLength)
@ -68,9 +60,11 @@ class HLSServer : public RTSPServer
{ {
if (fTCPSink != NULL) if (fTCPSink != NULL)
{ {
fTCPSink->stopPlaying(); FramedSource* oldSource = fTCPSink->source();
fTCPSink->stopPlaying();
Medium::close(fTCPSink); Medium::close(fTCPSink);
fTCPSink = NULL; fTCPSink = NULL;
Medium::close(oldSource);
} }
if (source != NULL) if (source != NULL)
{ {
@ -79,29 +73,32 @@ class HLSServer : public RTSPServer
} }
} }
void sendPlayList(char const* urlSuffix) ServerMediaSubsession* getSubsesion(const char* urlSuffix)
{ {
// First, make sure that the named file exists, and is streamable: ServerMediaSubsession* subsession = NULL;
ServerMediaSession* session = fOurServer.lookupServerMediaSession(urlSuffix); ServerMediaSession* session = fOurServer.lookupServerMediaSession(urlSuffix);
if (session == NULL) { if (session != NULL)
handleHTTPCmd_notFound(); {
return; ServerMediaSubsessionIterator iter(*session);
} subsession = iter.next();
// To be able to construct a playlist for the requested file, we need to know its duration:
float duration = session->duration();
if (duration <= 0.0) {
handleHTTPCmd_notSupported();
return;
} }
return subsession;
ServerMediaSubsessionIterator iter(*session); }
ServerMediaSubsession* subsession = iter.next();
void sendPlayList(char const* urlSuffix)
{
ServerMediaSubsession* subsession = this->getSubsesion(urlSuffix);
if (subsession == NULL) { if (subsession == NULL) {
handleHTTPCmd_notSupported(); handleHTTPCmd_notSupported();
return; return;
} }
float duration = subsession->duration();
if (duration <= 0.0) {
handleHTTPCmd_notSupported();
return;
}
unsigned int startTime = subsession->getCurrentNPT(NULL); unsigned int startTime = subsession->getCurrentNPT(NULL);
unsigned sliceDuration = 10; unsigned sliceDuration = 10;
std::ostringstream os; std::ostringstream os;
@ -127,69 +124,62 @@ class HLSServer : public RTSPServer
this->streamSource(ByteStreamMemoryBufferSource::createNew(envir(), playListBuffer, playList.size())); this->streamSource(ByteStreamMemoryBufferSource::createNew(envir(), playListBuffer, playList.size()));
} }
void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* /*fullRequestStr*/) { void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* /*fullRequestStr*/)
// If "urlSuffix" ends with "?segment=<offset-in-seconds>,<duration-in-seconds>", then strip this off, and send the {
// specified segment. Otherwise, construct and send a playlist that consists of segments from the specified file. char const* questionMarkPos = strrchr(urlSuffix, '?');
do { if (questionMarkPos == NULL)
char const* questionMarkPos = strrchr(urlSuffix, '?'); {
if (questionMarkPos == NULL) break; this->sendPlayList(urlSuffix);
unsigned offsetInSeconds; }
if (sscanf(questionMarkPos, "?segment=%u", &offsetInSeconds) != 1) break; else
{
char* streamName = strDup(urlSuffix); unsigned offsetInSeconds;
streamName[questionMarkPos-urlSuffix] = '\0'; if (sscanf(questionMarkPos, "?segment=%u", &offsetInSeconds) != 1)
{
do { handleHTTPCmd_notSupported();
ServerMediaSession* session = fOurServer.lookupServerMediaSession(streamName); return;
if (session == NULL) { }
handleHTTPCmd_notFound();
break;
}
// We can't send multi-subsession streams over HTTP (because there's no defined way to multiplex more than one subsession). char* streamName = strDup(urlSuffix);
// Therefore, use the first (and presumed only) substream: streamName[questionMarkPos-urlSuffix] = '\0';
ServerMediaSubsessionIterator iter(*session);
ServerMediaSubsession* subsession = iter.next();
if (subsession == NULL) {
// Treat an 'empty' ServerMediaSession the same as one that doesn't exist at all:
handleHTTPCmd_notFound();
break;
}
// Call "getStreamParameters()" to create the stream's source. (Because we're not actually streaming via RTP/RTCP, most do {
// of the parameters to the call are dummy.) ServerMediaSubsession* subsession = this->getSubsesion(streamName);
++fClientSessionId; if (subsession == NULL) {
Port clientRTPPort(0), clientRTCPPort(0), serverRTPPort(0), serverRTCPPort(0); handleHTTPCmd_notSupported();
netAddressBits destinationAddress = 0; break;
u_int8_t destinationTTL = 0; }
Boolean isMulticast = False;
void* streamToken = NULL; // Call "getStreamParameters()" to create the stream's source. (Because we're not actually streaming via RTP/RTCP, most
subsession->getStreamParameters(fClientSessionId, 0, clientRTPPort,clientRTCPPort, -1,0,0, destinationAddress,destinationTTL, isMulticast, serverRTPPort,serverRTCPPort, streamToken); // of the parameters to the call are dummy.)
++fClientSessionId;
// Seek the stream source to the desired place, with the desired duration, and (as a side effect) get the number of bytes: Port clientRTPPort(0), clientRTCPPort(0), serverRTPPort(0), serverRTCPPort(0);
double dOffsetInSeconds = (double)offsetInSeconds; netAddressBits destinationAddress = 0;
u_int64_t numBytes = 0; u_int8_t destinationTTL = 0;
subsession->seekStream(fClientSessionId, streamToken, dOffsetInSeconds, 0.0, numBytes); Boolean isMulticast = False;
void* streamToken = NULL;
if (numBytes == 0) { subsession->getStreamParameters(fClientSessionId, 0, clientRTPPort,clientRTCPPort, -1,0,0, destinationAddress,destinationTTL, isMulticast, serverRTPPort,serverRTCPPort, streamToken);
// For some reason, we do not know the size of the requested range. We can't handle this request:
handleHTTPCmd_notSupported(); // Seek the stream source to the desired place, with the desired duration, and (as a side effect) get the number of bytes:
break; double dOffsetInSeconds = (double)offsetInSeconds;
} u_int64_t numBytes = 0;
subsession->seekStream(fClientSessionId, streamToken, dOffsetInSeconds, 0.0, numBytes);
// send response header
this->sendHeader("video/mp2t", numBytes); if (numBytes == 0) {
// For some reason, we do not know the size of the requested range. We can't handle this request:
// stream body handleHTTPCmd_notSupported();
this->streamSource(subsession->getStreamSource(streamToken)); break;
}
} while(0); // send response header
this->sendHeader("video/mp2t", numBytes);
delete[] streamName; // stream body
return; this->streamSource(subsession->getStreamSource(streamToken));
} while (0); } while(0);
this->sendPlayList(urlSuffix); delete[] streamName;
}
} }
static void afterStreaming(void* clientData) static void afterStreaming(void* clientData)
@ -201,7 +191,7 @@ class HLSServer : public RTSPServer
clientConnection->fIsActive = False; // will cause the object to get deleted at the end of handling the request clientConnection->fIsActive = False; // will cause the object to get deleted at the end of handling the request
} else { } else {
// We're no longer handling a request; delete the object now: // We're no longer handling a request; delete the object now:
delete clientConnection; // delete clientConnection;
} }
} }
private: private:

Loading…
Cancel
Save