diff --git a/Common/RTSPCommon.h b/Common/RTSPCommon.h index 7cda993..01dda5c 100644 --- a/Common/RTSPCommon.h +++ b/Common/RTSPCommon.h @@ -13,8 +13,16 @@ typedef unsigned int u_int32_t; typedef unsigned __int64 uint64_t; typedef unsigned __int64 u_int64_t; typedef __int64 int64_t; + +#define _strcasecmp _strnicmp + +#if _MSC_VER <= 1700 +#define snprintf _snprintf +#endif + #else #include +#define _strcasecmp strncasecmp #endif #pragma pack(push, 1) diff --git a/README.md b/README.md index bc89785..0f1a0f5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # RTSP -c++ RTSP Client/Server - win32/linux/android +c++ RTSP Client/Server - windows/linux/android this project is RTSP client/server library for windows/linux/android. diff --git a/RTSPClient/RTP/AC3RTPSource.cpp b/RTSPClient/RTP/AC3RTPSource.cpp index c27ae85..f01fbc6 100644 --- a/RTSPClient/RTP/AC3RTPSource.cpp +++ b/RTSPClient/RTP/AC3RTPSource.cpp @@ -14,7 +14,7 @@ void AC3RTPSource::processFrame(RTPPacketBuffer *packet) { uint8_t *buf = packet->payload(); int len = packet->payloadLen(); - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); unsigned char* headerStart = buf; @@ -30,9 +30,9 @@ void AC3RTPSource::processFrame(RTPPacketBuffer *packet) // The RTP "M" (marker) bit indicates the last fragment of a frame. // In case the sender did not set the "M" bit correctly, we also test for FT == 0: if (packet->markerBit() || FT == 0) { - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); fBeginFrame = false; } } diff --git a/RTSPClient/RTP/H264RTPSource.cpp b/RTSPClient/RTP/H264RTPSource.cpp index 15b6086..f996e4e 100644 --- a/RTSPClient/RTP/H264RTPSource.cpp +++ b/RTSPClient/RTP/H264RTPSource.cpp @@ -16,10 +16,10 @@ H264RTPSource::~H264RTPSource() void H264RTPSource::putStartCode() { - fFrameBuf[fFrameBufPos++] = 0x00; - fFrameBuf[fFrameBufPos++] = 0x00; - fFrameBuf[fFrameBufPos++] = 0x00; - fFrameBuf[fFrameBufPos++] = 0x01; + fFrameBuffer[fFrameBufferPos++] = 0x00; + fFrameBuffer[fFrameBufferPos++] = 0x00; + fFrameBuffer[fFrameBufferPos++] = 0x00; + fFrameBuffer[fFrameBufferPos++] = 0x01; } void H264RTPSource::processFrame(RTPPacketBuffer *packet) @@ -34,7 +34,7 @@ void H264RTPSource::processFrame(RTPPacketBuffer *packet) uint8_t *buf_ptr = buf; bool isCompleteFrame = false; - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); uint8_t nalUnitType = (buf[0]&0x1F); @@ -42,7 +42,7 @@ void H264RTPSource::processFrame(RTPPacketBuffer *packet) DPRINTF("nal_type: %d, size: %d\n", nalUnitType, len); if (!fIsStartFrame) { - if (fExtraData) { + if (fExtraDataSize > 0) { putStartCode(); offset = trimStartCode(fExtraData, fExtraDataSize); copyToFrameBuffer(&fExtraData[offset], fExtraDataSize - offset); @@ -104,9 +104,9 @@ void H264RTPSource::processFrame(RTPPacketBuffer *packet) buf_ptr += staplen; len -= staplen; - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); } break; } @@ -118,9 +118,9 @@ void H264RTPSource::processFrame(RTPPacketBuffer *packet) } if (isCompleteFrame) { - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); } } diff --git a/RTSPClient/RTP/H265RTPSource.cpp b/RTSPClient/RTP/H265RTPSource.cpp index 048a17a..14b03f6 100644 --- a/RTSPClient/RTP/H265RTPSource.cpp +++ b/RTSPClient/RTP/H265RTPSource.cpp @@ -22,7 +22,7 @@ void H265RTPSource::processFrame(RTPPacketBuffer* packet) uint8_t* headerStart = buf; bool isCompleteFrame = false; - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); uint8_t nalUnitType = (headerStart[0] & 0x7E) >> 1; @@ -48,9 +48,9 @@ void H265RTPSource::processFrame(RTPPacketBuffer* packet) buf_ptr += nalUSize; len -= nalUSize; - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); } } break; case 49: { // Fragmentation Unit (FU) @@ -82,8 +82,8 @@ void H265RTPSource::processFrame(RTPPacketBuffer* packet) } if (isCompleteFrame) { - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); } } \ No newline at end of file diff --git a/RTSPClient/RTP/JPEGRTPSource.cpp b/RTSPClient/RTP/JPEGRTPSource.cpp index d2c86dd..a33149b 100644 --- a/RTSPClient/RTP/JPEGRTPSource.cpp +++ b/RTSPClient/RTP/JPEGRTPSource.cpp @@ -267,7 +267,7 @@ void JPEGRTPSource::processFrame(RTPPacketBuffer *packet) memcpy(&jpeg_buf[MAX_JPEG_HEADER_SIZE], buf, len); uint8_t *buf_ptr = &jpeg_buf[MAX_JPEG_HEADER_SIZE]; - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); unsigned char* qtables = NULL; unsigned qtlen = 0; @@ -390,9 +390,9 @@ void JPEGRTPSource::processFrame(RTPPacketBuffer *packet) copyToFrameBuffer(buf_ptr, len); if (packet->markerBit()) { - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); } delete[] jpeg_buf; diff --git a/RTSPClient/RTP/MPEG4ESRTPSource.cpp b/RTSPClient/RTP/MPEG4ESRTPSource.cpp index 6844a5b..6e4e5ed 100644 --- a/RTSPClient/RTP/MPEG4ESRTPSource.cpp +++ b/RTSPClient/RTP/MPEG4ESRTPSource.cpp @@ -17,7 +17,7 @@ void MPEG4ESRTPSource::processFrame(RTPPacketBuffer *packet) { uint8_t *buf = (uint8_t *)packet->payload(); int len = packet->payloadLen(); - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); if (len >= 4) { if (buf[0] == 0 && buf[1] == 0 && buf[2] == 1) @@ -34,9 +34,9 @@ void MPEG4ESRTPSource::processFrame(RTPPacketBuffer *packet) copyToFrameBuffer(buf, len); if (packet->markerBit()) { - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); fBeginFrame = false; } } diff --git a/RTSPClient/RTP/MPEG4GenericRTPSource.cpp b/RTSPClient/RTP/MPEG4GenericRTPSource.cpp index 14a4588..c86f60d 100644 --- a/RTSPClient/RTP/MPEG4GenericRTPSource.cpp +++ b/RTSPClient/RTP/MPEG4GenericRTPSource.cpp @@ -32,7 +32,7 @@ void MPEG4GenericRTPSource::processFrame(RTPPacketBuffer *packet) uint8_t *buf = (uint8_t *)packet->payload(); int len = packet->payloadLen(); - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); unsigned char* headerStart = buf; unsigned packetSize = len; @@ -79,8 +79,8 @@ void MPEG4GenericRTPSource::processFrame(RTPPacketBuffer *packet) copyToFrameBuffer(ptr, fAUHeaders[i].size); ptr += fAUHeaders[i].size; - if (fFrameHandlerFunc) - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); - resetFrameBuf(); + if (fFrameHandler) + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); + resetFrameBuffer(); } } diff --git a/RTSPClient/RTP/RTPSource.cpp b/RTSPClient/RTP/RTPSource.cpp index 1d59e96..abbfd0c 100644 --- a/RTSPClient/RTP/RTPSource.cpp +++ b/RTSPClient/RTP/RTPSource.cpp @@ -12,8 +12,8 @@ RTPSource::RTPSource(int streamType, MediaSubsession &subsession, TaskScheduler : fStreamType(streamType), fRecvBuf(NULL), fRTPPayloadFormat(subsession.rtpPayloadFormat()), fTimestampFrequency(subsession.rtpTimestampFrequency()), fSSRC(rand()), fTask(&task), fSvrAddr(0), fRtspSock(NULL), fRtcpChannelId(subsession.rtcpChannelId), fCodecName(NULL), fReceptionStatsDB(NULL), fRtcpInstance(NULL), -fFrameHandlerFunc(NULL), fFrameHandlerFuncData(NULL), fIsStartFrame(false), fBeginFrame(false), fExtraData(NULL), fExtraDataSize(0), -fRtpHandlerFunc(NULL), fRtpHandlerFuncData(NULL), fRtcpHandlerFunc(NULL), fRtcpHandlerFuncData(NULL), fFrameType(FRAME_TYPE_ETC) +fFrameHandler(NULL), fFrameHandlerData(NULL), fIsStartFrame(false), fBeginFrame(false), fExtraData(NULL), fExtraDataSize(0), +fRtpHandler(NULL), fRtpHandlerData(NULL), fRtcpHandler(NULL), fRtcpHandlerData(NULL), fFrameType(FRAME_TYPE_ETC) { fReorderingBuffer = new ReorderingPacketBuffer(); @@ -34,8 +34,8 @@ fRtpHandlerFunc(NULL), fRtpHandlerFuncData(NULL), fRtcpHandlerFunc(NULL), fRtcpH else if (!strcmp(subsession.mediumName(), "audio")) fFrameType = FRAME_TYPE_AUDIO; - fFrameBuf = new uint8_t[FRAME_BUFFER_SIZE]; - fFrameBufPos = 0; + fFrameBuffer = new uint8_t[FRAME_BUFFER_SIZE]; + fFrameBufferPos = 0; fLastSeqNum = fLastSeqNum2 = 0; fLastTimestamp = 0; @@ -89,7 +89,7 @@ RTPSource::~RTPSource() DELETE_OBJECT(fRtcpInstance); DELETE_ARRAY(fRecvBuf); - DELETE_ARRAY(fFrameBuf); + DELETE_ARRAY(fFrameBuffer); DELETE_ARRAY(fCodecName); DELETE_ARRAY(fExtraData); DELETE_ARRAY(fTrackId); @@ -101,14 +101,14 @@ void RTPSource::startNetworkReading(FrameHandlerFunc frameHandler, void *frameHa RTPHandlerFunc rtpHandler, void *rtpHandlerData, RTPHandlerFunc rtcpHandler, void *rtcpHandlerData) { - fFrameHandlerFunc = frameHandler; - fFrameHandlerFuncData = frameHandlerData; + fFrameHandler = frameHandler; + fFrameHandlerData = frameHandlerData; - fRtpHandlerFunc = rtpHandler; - fRtpHandlerFuncData = rtpHandlerData; + fRtpHandler = rtpHandler; + fRtpHandlerData = rtpHandlerData; - fRtcpHandlerFunc = rtcpHandler; - fRtcpHandlerFuncData = rtcpHandlerData; + fRtcpHandler = rtcpHandler; + fRtcpHandlerData = rtcpHandlerData; if (fRtpSock.isOpened()) fTask->turnOnBackgroundReadHandling(fRtpSock.sock(), &incomingRtpPacketHandler, this); @@ -125,14 +125,14 @@ void RTPSource::stopNetworkReading() if (fRtcpSock.isOpened()) fTask->turnOffBackgroundReadHandling(fRtcpSock.sock()); - fFrameHandlerFunc = NULL; - fFrameHandlerFuncData = NULL; + fFrameHandler = NULL; + fFrameHandlerData = NULL; - fRtpHandlerFunc = NULL; - fRtpHandlerFuncData = NULL; + fRtpHandler = NULL; + fRtpHandlerData = NULL; - fRtcpHandlerFunc = NULL; - fRtcpHandlerFuncData = NULL; + fRtcpHandler = NULL; + fRtcpHandlerData = NULL; fReorderingBuffer->reset(); } @@ -211,10 +211,10 @@ void RTPSource::processNextPacket() fLastSeqNum = seqnum; - if (fRtpHandlerFunc) - fRtpHandlerFunc(fRtpHandlerFuncData, fTrackId, (char *)nextPacket->buf(), nextPacket->length()); + if (fRtpHandler) + fRtpHandler(fRtpHandlerData, fTrackId, (char *)nextPacket->buf(), nextPacket->length()); - if (fFrameHandlerFunc) + if (fFrameHandler) processFrame(nextPacket); fReorderingBuffer->releaseUsedPacket(nextPacket); @@ -240,15 +240,15 @@ void RTPSource::processFrame(RTPPacketBuffer *packet) { uint8_t *buf = (uint8_t *)packet->payload(); int len = packet->payloadLen(); - int64_t media_timestamp = packet->extTimestamp() == 0 ? getMediaTimestamp(packet->timestamp()) : packet->extTimestamp(); + int64_t timestamp = packet->extTimestamp() == 0 ? getRealTimestamp(packet->timestamp()) : packet->extTimestamp(); copyToFrameBuffer(buf, len); if (packet->markerBit() == 1 || fLastTimestamp != packet->timestamp()) { - if (fFrameHandlerFunc) { - fFrameHandlerFunc(fFrameHandlerFuncData, fFrameType, media_timestamp, fFrameBuf, fFrameBufPos); + if (fFrameHandler) { + fFrameHandler(fFrameHandlerData, fFrameType, timestamp, fFrameBuffer, fFrameBufferPos); } - resetFrameBuf(); + resetFrameBuffer(); } } @@ -321,8 +321,8 @@ void RTPSource::rtcpReadHandler(char *buf, int len, struct sockaddr_in &fromAddr RTCPInstance::onExpire(fRtcpInstance); } - if (fRtcpHandlerFunc) - fRtcpHandlerFunc(fRtcpHandlerFuncData, fTrackId, buf, len); + if (fRtcpHandler) + fRtcpHandler(fRtcpHandlerData, fTrackId, buf, len); } void RTPSource::sendRtcpReport(char *buf, int len) @@ -350,20 +350,20 @@ void RTPSource::sendRtcpReport(char *buf, int len) void RTPSource::copyToFrameBuffer(uint8_t *buf, int len) { - if (fFrameBufPos+len >= FRAME_BUFFER_SIZE) { + if (fFrameBufferPos+len >= FRAME_BUFFER_SIZE) { DPRINTF("RTP Frame Buffer overflow %s\n", fCodecName); - fFrameBufPos = 0; + fFrameBufferPos = 0; } - memmove(&fFrameBuf[fFrameBufPos], buf, len); - fFrameBufPos += len; + memmove(&fFrameBuffer[fFrameBufferPos], buf, len); + fFrameBufferPos += len; } -void RTPSource::resetFrameBuf() +void RTPSource::resetFrameBuffer() { - fFrameBufPos = 0; + fFrameBufferPos = 0; } -uint64_t RTPSource::getMediaTimestamp(uint32_t timestamp) +uint64_t RTPSource::getRealTimestamp(uint32_t timestamp) { uint64_t msec = 1000; uint64_t time_msec = timestamp*msec/fTimestampFrequency; diff --git a/RTSPClient/RTP/RTPSource.h b/RTSPClient/RTP/RTPSource.h index b73c813..1f0534a 100644 --- a/RTSPClient/RTP/RTPSource.h +++ b/RTSPClient/RTP/RTPSource.h @@ -55,10 +55,10 @@ class RTPSource protected: void copyToFrameBuffer(uint8_t *buf, int len); - void resetFrameBuf(); + void resetFrameBuffer(); protected: - uint64_t getMediaTimestamp(uint32_t timestamp); + uint64_t getRealTimestamp(uint32_t timestamp); protected: ReorderingPacketBuffer *fReorderingBuffer; @@ -84,10 +84,10 @@ class RTPSource uint32_t fSvrAddr; time_t fLastRtcpSendTime; - uint8_t* fFrameBuf; - int fFrameBufPos; - FrameHandlerFunc fFrameHandlerFunc; - void* fFrameHandlerFuncData; + uint8_t* fFrameBuffer; + int fFrameBufferPos; + FrameHandlerFunc fFrameHandler; + void* fFrameHandlerData; // TCP À϶§¸¸ »ç¿ë MySock* fRtspSock; @@ -100,11 +100,11 @@ class RTPSource TaskScheduler* fTask; char* fRecvBuf; - RTPHandlerFunc fRtpHandlerFunc; - void* fRtpHandlerFuncData; + RTPHandlerFunc fRtpHandler; + void* fRtpHandlerData; - RTPHandlerFunc fRtcpHandlerFunc; - void* fRtcpHandlerFuncData; + RTPHandlerFunc fRtcpHandler; + void* fRtcpHandlerData; }; #endif diff --git a/RTSPClient/RTSP/MediaSession.cpp b/RTSPClient/RTSP/MediaSession.cpp index 37cc199..da5dbe2 100644 --- a/RTSPClient/RTSP/MediaSession.cpp +++ b/RTSPClient/RTSP/MediaSession.cpp @@ -495,6 +495,7 @@ fObjecttype(0), fOctetalign(0), fProfile_level_id(0), fRobustsorting(0), fSizelength(0), fStreamstateindication(0), fStreamtype(0), fCpresent(false), fRandomaccessindication(false), fConfig(NULL), fMode(NULL), fSpropParameterSets(NULL), +fPropVps(NULL), fPropSps(NULL), fPropPps(NULL), fPlayStartTime(0.0), fPlayEndTime(0.0), fVideoWidth(0), fVideoHeight(0), fVideoFPS(0), fNumChannels(1), fScale(1.0f), fNPT_PTS_Offset(0.0f), fRTPSource(NULL) @@ -509,6 +510,7 @@ MediaSubsession::~MediaSubsession() delete[] fConnectionEndpointName; delete[] fSavedSDPLines; delete[] fMediumName; delete[] fCodecName; delete[] fProtocolName; delete[] fControlPath; delete[] fConfig; delete[] fMode; delete[] fSpropParameterSets; + delete[] fPropVps; delete[] fPropSps; delete[] fPropPps; if (sessionId) delete[] sessionId; @@ -819,6 +821,12 @@ bool MediaSubsession::parseSDPAttribute_fmtp(char const* sdpLine) } else if (sscanf(sdpLine, " sprop-parameter-sets = %[^; \t\r\n]", valueStr) == 1) { // Note: We used "sdpLine" here, because the value is case-sensitive. delete[] fSpropParameterSets; fSpropParameterSets = strDup(valueStr); + } else if (sscanf(sdpLine, " sprop-vps=%[^; \t\r\n]", valueStr) == 1) { + delete[] fPropVps; fPropVps = strDup(valueStr); + } else if (sscanf(sdpLine, " sprop-sps=%[^; \t\r\n]", valueStr) == 1) { + delete[] fPropSps; fPropSps = strDup(valueStr); + } else if (sscanf(sdpLine, " sprop-pps=%[^; \t\r\n]", valueStr) == 1) { + delete[] fPropPps; fPropPps = strDup(valueStr); } else { // Some of the above parameters are bool. Check whether the parameter // names appear alone, without a "= 1" at the end: diff --git a/RTSPClient/RTSP/MediaSession.h b/RTSPClient/RTSP/MediaSession.h index 8c82722..8acb426 100644 --- a/RTSPClient/RTSP/MediaSession.h +++ b/RTSPClient/RTSP/MediaSession.h @@ -148,6 +148,9 @@ class MediaSubsession char const* fmtp_config() const { return fConfig; } char const* fmtp_mode() const { return fMode; } char const* fmtp_spropparametersets() const { return fSpropParameterSets; } + char const* fmtp_spropVps() const { return fPropVps; } + char const* fmtp_spropSps() const { return fPropSps; } + char const* fmtp_spropPps() const { return fPropPps; } unsigned int connectionEndpointAddress() const; // Converts "fConnectionEndpointName" to an address (or 0 if unknown) void setDestinations(unsigned int defaultDestAddress); @@ -220,6 +223,7 @@ class MediaSubsession unsigned fSizelength, fStreamstateindication, fStreamtype; bool fCpresent, fRandomaccessindication; char *fConfig, *fMode, *fSpropParameterSets; + char *fPropVps, *fPropSps, *fPropPps; // H.265 double fPlayStartTime; double fPlayEndTime; diff --git a/RTSPClient/RTSP/RTSPClient.cpp b/RTSPClient/RTSP/RTSPClient.cpp index 23e940c..7c5fc38 100644 --- a/RTSPClient/RTSP/RTSPClient.cpp +++ b/RTSPClient/RTSP/RTSPClient.cpp @@ -38,7 +38,7 @@ RTSPClient::RTSPClient() fLastResponseCode = 0; - fCloseFunc = NULL; fCloseFuncData = NULL; + fCloseHandler = NULL; fCloseHandlerData = NULL; fVideoCodec = fAudioCodec = NULL; fVideoWidth = fVideoHeight = fVideoFps = 0; @@ -52,8 +52,8 @@ RTSPClient::RTSPClient() fIsSendGetParam = false; fLastSendGetParam = 0; - fRTPReceiveFunc = fRTCPReceiveFunc = NULL; - fRTPReceiveFuncData = fRTCPReceiveFuncData = NULL; + fRTPReceiveHandler = fRTCPReceiveHandler = NULL; + fRTPReceiveHandlerData = fRTCPReceiveHandlerData = NULL; fTask = new TaskScheduler(); } @@ -85,7 +85,7 @@ void RTSPClient::reset() fCurrentAuthenticator.reset(); - fCloseFunc = NULL; fCloseFuncData = NULL; + fCloseHandler = NULL; fCloseHandlerData = NULL; fVideoCodec = fAudioCodec = NULL; fVideoWidth = fVideoHeight = fVideoFps = 0; @@ -342,8 +342,8 @@ void RTSPClient::tcpReadError(int result) fTask->turnOffBackgroundReadHandling(fRtspSock.sock()); - if (fCloseFunc) - fCloseFunc(fCloseFuncData, err, result); + if (fCloseHandler) + fCloseHandler(fCloseHandlerData, err, result); } void RTSPClient::tcpReadHandler(void *instance, int) @@ -942,7 +942,8 @@ void RTSPClient::constructSubsessionURL(MediaSubsession const& subsession, prefix = separator = ""; } else { unsigned prefixLen = strlen(prefix); - separator = (prefix[prefixLen-1] == '/' || suffix[0] == '/') ? "" : "/"; + unsigned suffixLen = strlen(suffix); + separator = ((prefixLen > 0 && prefix[prefixLen-1] == '/') || (suffixLen > 0 && suffix[0] == '/')) ? "" : "/"; } } @@ -1484,11 +1485,15 @@ int RTSPClient::openURL(const char *url, int streamType, int timeout, bool rtpOn addr.s_addr = address; const char *ip_address = inet_ntoa(addr); + if (ip_address == NULL) break; + parsedURL = new char[strlen(ip_address)+strlen(urlSuffix)+20]; sprintf((char *)parsedURL, "rtsp://%s:%hu%s", ip_address, port, urlSuffix); parseRTSPURLUsernamePassword(url, username, password); + if (username != NULL && password != NULL) url = parsedURL; + if (connectToServer(ip_address, port, timeout) < 0) break; @@ -1550,11 +1555,64 @@ int RTSPClient::openURL(const char *url, int streamType, int timeout, bool rtpOn fVideoFps = subsession->videoFPS(); if (!strcmp(fVideoCodec, "H264")) { - char *spropParameterSets = (char *)subsession->fmtp_spropparametersets(); + char* spropParameterSets = (char*)subsession->fmtp_spropparametersets(); if (spropParameterSets) { unsigned int sps_size; fVideoExtraData = parseH264ConfigStr(spropParameterSets, fVideoExtraDataSize, sps_size); } + } else if (!strcmp(fVideoCodec, "H265")) { + char* props_vps = (char*)subsession->fmtp_spropVps(); + char* props_sps = (char*)subsession->fmtp_spropSps(); + char* props_pps = (char*)subsession->fmtp_spropPps(); + + uint8_t* extraDataVps = NULL; + uint8_t* extraDataSps = NULL; + uint8_t* extraDataPps = NULL; + + int extraDataVpsSize = 0; + int extraDataSpsSize = 0; + int extraDataPpsSize = 0; + + if (props_vps) { + unsigned int size1 = 0, size2 = 0; + extraDataVps = parseH264ConfigStr(props_vps, size1, size2); + extraDataVpsSize = size1; + + //DPRINTF("size : %d %d\n", size1, size2); + //for (int i = 0; i < size1; i++) printf("0x%02x ", extraDataVps[i]); + //printf("\n"); + } + + if (props_sps) { + unsigned int size1 = 0, size2 = 0; + extraDataSps = parseH264ConfigStr(props_sps, size1, size2); + extraDataSpsSize = size1; + + //DPRINTF("size : %d %d\n", size1, size2); + //for (int i = 0; i < size1; i++) printf("0x%02x ", extraDataSps[i]); + //printf("\n"); + } + + if (props_pps) { + unsigned int size1 = 0, size2 = 0; + extraDataPps = parseH264ConfigStr(props_pps, size1, size2); + extraDataPpsSize = size1; + + //DPRINTF("size : %d %d\n", size1, size2); + //for (int i = 0; i < size1; i++) printf("0x%02x ", extraDataPps[i]); + //printf("\n"); + } + + fVideoExtraDataSize = extraDataVpsSize + extraDataSpsSize + extraDataPpsSize; + fVideoExtraData = new uint8_t[fVideoExtraDataSize]; + + memcpy(fVideoExtraData, extraDataVps, extraDataVpsSize); + memcpy(&fVideoExtraData[extraDataVpsSize], extraDataSps, extraDataSpsSize); + memcpy(&fVideoExtraData[extraDataVpsSize + extraDataSpsSize], extraDataPps, extraDataPpsSize); + + delete[] extraDataVps; + delete[] extraDataSps; + delete[] extraDataPps; } else if (!strcmp(fVideoCodec, "MP4V-ES")) { if (subsession->fmtp_config()) { fVideoExtraData = parseGeneralConfigStr((char const*)subsession->fmtp_config(), fVideoExtraDataSize); @@ -1590,10 +1648,10 @@ int RTSPClient::openURL(const char *url, int streamType, int timeout, bool rtpOn return 0; } -int RTSPClient::playURL(FrameHandlerFunc func, void *funcData, - OnCloseFunc onCloseFunc, void *onCloseFuncData, - OnPacketReceiveFunc onRTPReceiveFunc, void *onRTPReceiveFuncData, - OnPacketReceiveFunc onRTCPReceiveFunc, void *onRTCPReceiveFuncData) +int RTSPClient::playURL(FrameHandlerFunc frameHandler, void *frameHandlerData, + CloseHandlerFunc closeHandler, void *closeHandlerData, + PacketReceiveHandlerFunc rtpReceiveHandler, void *rtpReceiveHandlerData, + PacketReceiveHandlerFunc rtcpReceiveHandler, void *rtcpReceiveHandlerData) { if (!fMediaSession) return -1; @@ -1601,21 +1659,21 @@ int RTSPClient::playURL(FrameHandlerFunc func, void *funcData, if (!playMediaSession(*fMediaSession, true)) return -1; - fCloseFunc = onCloseFunc; - fCloseFuncData = onCloseFuncData; + fCloseHandler = closeHandler; + fCloseHandlerData = closeHandlerData; - fRTPReceiveFunc = onRTPReceiveFunc; - fRTPReceiveFuncData = onRTPReceiveFuncData; + fRTPReceiveHandler = rtpReceiveHandler; + fRTPReceiveHandlerData = rtpReceiveHandlerData; - fRTCPReceiveFunc = onRTCPReceiveFunc; - fRTCPReceiveFuncData = onRTCPReceiveFuncData; + fRTCPReceiveHandler = rtcpReceiveHandler; + fRTCPReceiveHandlerData = rtcpReceiveHandlerData; MediaSubsessionIterator *iter = new MediaSubsessionIterator(*fMediaSession); MediaSubsession *subsession = NULL; while ((subsession=iter->next()) != NULL) { if (subsession->fRTPSource) - subsession->fRTPSource->startNetworkReading(func, funcData, rtpHandlerCallback, this, rtcpHandlerCallback, this); + subsession->fRTPSource->startNetworkReading(frameHandler, frameHandlerData, rtpHandlerCallback, this, rtcpHandlerCallback, this); } if (fTCPStreamIdCount > 0) fTCPReadingState = AWAITING_DOLLAR; @@ -1753,16 +1811,16 @@ void RTSPClient::rtpHandlerCallback(void *arg, char *trackId, char *buf, int len } } - if (client->fRTPReceiveFunc) - client->fRTPReceiveFunc(client->fRTPReceiveFuncData, trackId, buf, len); + if (client->fRTPReceiveHandler) + client->fRTPReceiveHandler(client->fRTPReceiveHandlerData, trackId, buf, len); } void RTSPClient::rtcpHandlerCallback(void *arg, char *trackId, char *buf, int len) { RTSPClient *client = (RTSPClient *)arg; - if (client->fRTCPReceiveFunc) - client->fRTCPReceiveFunc(client->fRTCPReceiveFuncData, trackId, buf, len); + if (client->fRTCPReceiveHandler) + client->fRTCPReceiveHandler(client->fRTCPReceiveHandlerData, trackId, buf, len); } void RTSPClient::sendGetParam() diff --git a/RTSPClient/RTSP/RTSPClient.h b/RTSPClient/RTSP/RTSPClient.h index bd8cf91..41ceb09 100644 --- a/RTSPClient/RTSP/RTSPClient.h +++ b/RTSPClient/RTSP/RTSPClient.h @@ -9,8 +9,8 @@ #define RECV_BUF_SIZE (1024*1024) #define SEND_GET_PARAM_DURATION (50) -typedef void (*OnCloseFunc)(void *arg, int err, int result); -typedef void (*OnPacketReceiveFunc)(void *arg, const char *trackId, char *buf, int len); +typedef void (*CloseHandlerFunc)(void *arg, int err, int result); +typedef void (*PacketReceiveHandlerFunc)(void *arg, const char *trackId, char *buf, int len); class RTPSource; @@ -21,10 +21,10 @@ class RTSPClient virtual ~RTSPClient(); int openURL(const char *url, int streamType, int timeout = 2, bool rtpOnly = false); - int playURL(FrameHandlerFunc func, void *funcData, - OnCloseFunc onCloseFunc, void *onCloseFuncData, - OnPacketReceiveFunc onRTPReceiveFunc = NULL, void *onRTPReceiveFuncData = NULL, - OnPacketReceiveFunc onRTCPReceiveFunc = NULL, void *onRTCPReceiveFuncData = NULL); + int playURL(FrameHandlerFunc frameHandler, void *frameHandlerData, + CloseHandlerFunc closeHandler, void *closeHandlerFunc, + PacketReceiveHandlerFunc rtpReceiveHandler = NULL, void *rtpReceiveHandlerData = NULL, + PacketReceiveHandlerFunc rtcpReceiveHandler = NULL, void *rtcpReceiveHandlerData = NULL); void closeURL(); void sendGetParam(); int sendPause(); @@ -167,8 +167,8 @@ class RTSPClient unsigned fLastResponseCode; - OnCloseFunc fCloseFunc; - void* fCloseFuncData; + CloseHandlerFunc fCloseHandler; + void* fCloseHandlerData; const char* fVideoCodec; const char* fAudioCodec; @@ -188,10 +188,10 @@ class RTSPClient time_t fLastSendGetParam; // GET_PARAMETER polling time // for rtsp server - OnPacketReceiveFunc fRTPReceiveFunc; - void* fRTPReceiveFuncData; - OnPacketReceiveFunc fRTCPReceiveFunc; - void* fRTCPReceiveFuncData; + PacketReceiveHandlerFunc fRTPReceiveHandler; + void* fRTPReceiveHandlerData; + PacketReceiveHandlerFunc fRTCPReceiveHandler; + void* fRTCPReceiveHandlerData; }; #endif diff --git a/RTSPServer/RTSP/ServerMediaSession.cpp b/RTSPServer/RTSP/ServerMediaSession.cpp index 5d469bb..d0c65da 100644 --- a/RTSPServer/RTSP/ServerMediaSession.cpp +++ b/RTSPServer/RTSP/ServerMediaSession.cpp @@ -2,6 +2,7 @@ #include "util.h" #include "SockCommon.h" #include "RTSPCommonEnv.h" +#include "RTSPCommon.h" #include diff --git a/Sock/MySock.cpp b/Sock/MySock.cpp index 443e298..3786e6b 100644 --- a/Sock/MySock.cpp +++ b/Sock/MySock.cpp @@ -7,6 +7,7 @@ MySock::MySock() { fSock = -1; fPort = 0; + fIsOpen = false; memset(&fClientAddr, 0, sizeof(struct sockaddr_in)); fIsSSM = false; fGroupAddress = fSourceFilterAddr = 0; @@ -27,9 +28,9 @@ void MySock::closeSock() } } - if (fSock >= 0) { + if (fIsOpen) { closeSocket(fSock); - fSock = -1; + fIsOpen = false; memset(&fClientAddr, 0, sizeof(struct sockaddr_in)); fGroupAddress = fSourceFilterAddr = 0; } @@ -46,6 +47,7 @@ int MySock::setupStreamSock(short port, int makeNonBlocking) if (sock > 0) { fSock = sock; fPort = port; + fIsOpen = true; } return sock; @@ -57,6 +59,7 @@ int MySock::setupDatagramSock(short port, int makeNonBlocking) if (sock > 0) { fSock = sock; fPort = port; + fIsOpen = true; } return sock; @@ -68,6 +71,7 @@ int MySock::setupServerSock(short port, int makeNonBlocking) if (sock > 0) { fSock = sock; fPort = port; + fIsOpen = true; } return sock; @@ -79,6 +83,7 @@ int MySock::setupClientSock(int serverSock, int makeNonBlocking) if (sock > 0) { fSock = sock; fPort = ntohs(fClientAddr.sin_port); + fIsOpen = true; } return sock; diff --git a/Sock/MySock.h b/Sock/MySock.h index c08308d..b561b70 100644 --- a/Sock/MySock.h +++ b/Sock/MySock.h @@ -13,7 +13,7 @@ class MySock int sock() { return fSock; } unsigned short port() { return fPort; } struct sockaddr_in& clientAddress() { return fClientAddr; } - bool isOpened() { return fSock != -1; } + bool isOpened() { return fIsOpen; } int setupStreamSock(short port, int makeNonBlocking); int setupDatagramSock(short port, int makeNonBlocking); @@ -54,6 +54,7 @@ class MySock protected: int fSock; unsigned short fPort; + bool fIsOpen; struct sockaddr_in fClientAddr; diff --git a/OS_Common/NetCommon.h b/Sock/NetCommon.h similarity index 81% rename from OS_Common/NetCommon.h rename to Sock/NetCommon.h index 1e58046..296f39e 100644 --- a/OS_Common/NetCommon.h +++ b/Sock/NetCommon.h @@ -11,12 +11,6 @@ #define EINPROGRESS WSAEWOULDBLOCK #define EINTR WSAEINTR -#define _strcasecmp _strnicmp - -#if _MSC_VER <= 1700 -#define snprintf _snprintf -#endif - #else #include @@ -32,7 +26,6 @@ #include #include -#define _strcasecmp strncasecmp #endif #endif diff --git a/Sock/SockCommon.cpp b/Sock/SockCommon.cpp index 8ee7481..e3456c0 100644 --- a/Sock/SockCommon.cpp +++ b/Sock/SockCommon.cpp @@ -94,14 +94,14 @@ int setupStreamSock(short port, int makeNonBlocking) socketErr("[%s] unable to create stream socket: ", __FUNCTION__); return newSocket; } -#if 0 + if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseFlag, sizeof reuseFlag) != 0) { socketErr("[%s] setsockopt(SO_REUSEADDR) error: ", __FUNCTION__); closeSocket(newSocket); return -1; } -#endif + struct sockaddr_in c_addr; memset(&c_addr, 0, sizeof(c_addr)); c_addr.sin_addr.s_addr = INADDR_ANY; diff --git a/Sock/TaskScheduler.cpp b/Sock/TaskScheduler.cpp index 97d6170..a90d088 100644 --- a/Sock/TaskScheduler.cpp +++ b/Sock/TaskScheduler.cpp @@ -2,7 +2,7 @@ #include "RTSPCommonEnv.h" #include -THREAD_FUNC DoEventThread(void* lpParam) +static THREAD_FUNC DoEventThread(void* lpParam) { TaskScheduler *scheduler = (TaskScheduler *)lpParam; scheduler->doEventLoop(); @@ -25,8 +25,6 @@ TaskScheduler::~TaskScheduler() delete fReadHandlers; - THREAD_DESTROY(&fThread); - MUTEX_DESTROY(&fMutex); } @@ -94,8 +92,10 @@ void TaskScheduler::stopEventLoop() { fTaskLoop = 0; - THREAD_JOIN(&fThread); - THREAD_DESTROY(&fThread); + if (fThread) { + THREAD_JOIN(&fThread); + THREAD_DESTROY(&fThread); + } } void TaskScheduler::doEventLoop() diff --git a/tests/rtspclient.cpp b/tests/rtspclient.cpp index e734580..495b2bb 100644 --- a/tests/rtspclient.cpp +++ b/tests/rtspclient.cpp @@ -50,15 +50,20 @@ int mygetch(void) FILE *fp_dump = NULL; #ifdef RTSPCLIENT_DLL -static void frameHandlerFunc(void *arg, DLL_RTP_FRAME_TYPE frame_type, __int64 timestamp, unsigned char *buf, int len) +static void frameHandler(void *arg, DLL_RTP_FRAME_TYPE frame_type, __int64 timestamp, unsigned char *buf, int len) #else -static void frameHandlerFunc(void *arg, RTP_FRAME_TYPE frame_type, int64_t timestamp, unsigned char *buf, int len) +static void frameHandler(void *arg, RTP_FRAME_TYPE frame_type, int64_t timestamp, unsigned char *buf, int len) #endif { if (fp_dump) fwrite(buf, len, 1, fp_dump); } +static void closeHandler(void* arg, int err, int result) +{ + printf("RTSP session disconnected, err : %d, result : %d", err, result); +} + int main(int argc, char *argv[]) { #ifdef _DEBUG @@ -71,9 +76,14 @@ int main(int argc, char *argv[]) #else RTSPCommonEnv::SetDebugFlag(DEBUG_FLAG_RTSP); #endif - char *strURL = "rtsp://222.96.113.48:4554/AVStream1_2"; +#if 0 + char* strURL = "rtsp://127.0.0.1:8554/h264ESVideoTest"; fp_dump = fopen("video.264", "wb"); +#else + char* strURL = "rtsp://admin:antsANTS@192.168.140.103/0"; + fp_dump = fopen("video.265", "wb"); +#endif #ifdef RTSPCLIENT_DLL void *rtspClient = rtspclient_new(); @@ -89,9 +99,9 @@ int main(int argc, char *argv[]) #endif { #ifdef RTSPCLIENT_DLL - if (rtspclient_play_url(rtspClient, frameHandlerFunc, rtspClient) == 0) + if (rtspclient_play_url(rtspClient, frameHandler, rtspClient, closeHandler, rtspClient) == 0) #else - if (rtspClient->playURL(frameHandlerFunc, rtspClient, NULL, NULL) == 0) + if (rtspClient->playURL(frameHandler, rtspClient, closeHandler, rtspClient) == 0) #endif { char c; diff --git a/tests/rtspserver.cpp b/tests/rtspserver.cpp index b0b1392..4e45a58 100644 --- a/tests/rtspserver.cpp +++ b/tests/rtspserver.cpp @@ -38,11 +38,11 @@ RTSPLiveStreamer *streamers[NUM_STREAMER] = { NULL }; void addServerSessions() { streamers[0] = new RTSPLiveStreamer(); - streamers[0]->open("rtsp://172.30.1.213/live/main", 0, "stream1"); + streamers[0]->open("rtsp://127.0.0.1:8554/h265ESVideoTest", 0, "stream1"); streamers[0]->run(); streamers[1] = new RTSPLiveStreamer(); - streamers[1]->open("rtsp://admin:1234@172.30.10.103/h264", 0, "stream2"); + streamers[1]->open("rtsp://admin:antsANTS@192.168.140.103/0", 0, "stream2"); streamers[1]->run(); } diff --git a/win32/RTSPClientDll/RTSPClientDll.cpp b/win32/RTSPClientDll/RTSPClientDll.cpp index 1a11394..423eb9a 100644 --- a/win32/RTSPClientDll/RTSPClientDll.cpp +++ b/win32/RTSPClientDll/RTSPClientDll.cpp @@ -28,11 +28,11 @@ RTSPCLIENTDLL_API int rtspclient_open_url(void *rtspclient, const char *url, int return -1; } -RTSPCLIENTDLL_API int rtspclient_play_url(void *rtspclient, DllFrameHandlerFunc *func, void *funcData) +RTSPCLIENTDLL_API int rtspclient_play_url(void *rtspclient, DllFrameHandlerFunc *func, void *funcData, DllCloseHandlerFunc* closeHandlerFunc, void* closeHandlerFuncData) { if (rtspclient) { RTSPClient *pRTSPClient = (RTSPClient *)rtspclient; - return pRTSPClient->playURL((FrameHandlerFunc)func, funcData, NULL, NULL, NULL, NULL); + return pRTSPClient->playURL((FrameHandlerFunc)func, funcData, closeHandlerFunc, closeHandlerFuncData, NULL, NULL); } return -1; } diff --git a/win32/RTSPClientDll/RTSPClientDll.h b/win32/RTSPClientDll/RTSPClientDll.h index ba2e6ab..2388f23 100644 --- a/win32/RTSPClientDll/RTSPClientDll.h +++ b/win32/RTSPClientDll/RTSPClientDll.h @@ -16,11 +16,12 @@ typedef enum DLL_RTP_FRAME_TYPE { DLL_FRAME_TYPE_VIDEO, DLL_FRAME_TYPE_AUDIO, DLL_FRAME_TYPE_ETC }; typedef void DllFrameHandlerFunc(void *arg, DLL_RTP_FRAME_TYPE frame_type, __int64 timestamp, unsigned char *buf, int len); +typedef void DllCloseHandlerFunc(void* arg, int err, int result); RTSPCLIENTDLL_API void* rtspclient_new(); RTSPCLIENTDLL_API void rtspclient_delete(void *rtspclient); RTSPCLIENTDLL_API int rtspclient_open_url(void *rtspclient, const char *url, int conn_type, int timeout); -RTSPCLIENTDLL_API int rtspclient_play_url(void *rtspclient, DllFrameHandlerFunc *func, void *funcData); +RTSPCLIENTDLL_API int rtspclient_play_url(void *rtspclient, DllFrameHandlerFunc *func, void *funcData, DllCloseHandlerFunc *closeHandlerFunc, void *closeHandlerFuncData); RTSPCLIENTDLL_API void rtspclient_close_url(void *rtspclient); RTSPCLIENTDLL_API void rtspclient_set_debug_flag(int flag); RTSPCLIENTDLL_API void rtspclient_set_debug_print(int print); diff --git a/win32/RTSPClientLib/RTSPClientLib.vcxproj b/win32/RTSPClientLib/RTSPClientLib.vcxproj index 75b20c5..8ded870 100644 --- a/win32/RTSPClientLib/RTSPClientLib.vcxproj +++ b/win32/RTSPClientLib/RTSPClientLib.vcxproj @@ -199,13 +199,13 @@ + - diff --git a/win32/RTSPClientLib/RTSPClientLib.vcxproj.filters b/win32/RTSPClientLib/RTSPClientLib.vcxproj.filters index 9791768..7924cf6 100644 --- a/win32/RTSPClientLib/RTSPClientLib.vcxproj.filters +++ b/win32/RTSPClientLib/RTSPClientLib.vcxproj.filters @@ -196,9 +196,6 @@ OS_Common - - OS_Common - OS_Common @@ -214,5 +211,8 @@ RTP + + Sock + \ No newline at end of file diff --git a/win32/RTSPServerLib/RTSPServerLib.vcxproj b/win32/RTSPServerLib/RTSPServerLib.vcxproj index b4040d9..bbc66ee 100644 --- a/win32/RTSPServerLib/RTSPServerLib.vcxproj +++ b/win32/RTSPServerLib/RTSPServerLib.vcxproj @@ -141,10 +141,15 @@ + + + + + @@ -155,9 +160,12 @@ - + + + + diff --git a/win32/RTSPServerLib/RTSPServerLib.vcxproj.filters b/win32/RTSPServerLib/RTSPServerLib.vcxproj.filters index 2e7de43..b28553e 100644 --- a/win32/RTSPServerLib/RTSPServerLib.vcxproj.filters +++ b/win32/RTSPServerLib/RTSPServerLib.vcxproj.filters @@ -60,7 +60,19 @@ RTSP - + + Sock + + + OS_Common + + + OS_Common + + + OS_Common + + OS_Common @@ -110,6 +122,18 @@ RTSP + + OS_Common + + + OS_Common + + + OS_Common + + + OS_Common +