In my application I send rtp streams over rtsp (tcp streaming) because I cannot
afford dropping a single frame.
After some research I found that liveMedia will drop my frames in certain
circumstances, especially when I send big I-Frames.
The code is in RTPInterface::sendDataOverTCP, which will not try to resend when
"forceSendToSucceed" is False, which is always the case for frame data.
In my opinion this behaviour is inappropriate, since I use TCP streaming
exactly because I never must drop a frame.
If sending does not work within the timeout, I rather close the connection, so
that the client will realize that something is wrong.
I also find that increasing the TCP sendbuffer from 50kB to 1MB in
GenericMediaServer.cpp is helpful in this cause.
Attached is my patch.
Yours,
Johannes Gajdosik
diff -rp live.2016.08.07/liveMedia/GenericMediaServer.cpp live.2016.08.07.patched/liveMedia/GenericMediaServer.cpp
*** live.2016.08.07/liveMedia/GenericMediaServer.cpp Mon Aug 8 00:45:22 2016
--- live.2016.08.07.patched/liveMedia/GenericMediaServer.cpp Tue Aug 9 18:21:08 2016
*************** void GenericMediaServer::incomingConnect
*** 194,200 ****
}
ignoreSigPipeOnSocket(clientSocket); // so that clients on the same host that are killed don't also kill us
makeSocketNonBlocking(clientSocket);
! increaseSendBufferTo(envir(), clientSocket, 50*1024);
#ifdef DEBUG
envir() << "accept()ed connection from " << AddressString(clientAddr).val() << "\n";
--- 194,201 ----
}
ignoreSigPipeOnSocket(clientSocket); // so that clients on the same host that are killed don't also kill us
makeSocketNonBlocking(clientSocket);
! // gaj: original 50*1024 is much too small
! increaseSendBufferTo(envir(), clientSocket, 1024*1024);
#ifdef DEBUG
envir() << "accept()ed connection from " << AddressString(clientAddr).val() << "\n";
diff -rp live.2016.08.07/liveMedia/RTPInterface.cpp live.2016.08.07.patched/liveMedia/RTPInterface.cpp
*** live.2016.08.07/liveMedia/RTPInterface.cpp Mon Aug 8 00:45:22 2016
--- live.2016.08.07.patched/liveMedia/RTPInterface.cpp Tue Aug 9 18:35:29 2016
*************** Boolean RTPInterface::sendRTPorRTCPPacke
*** 346,357 ****
#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*/);
if (sendResult < (int)dataSize) {
// The TCP send() failed - at least partially.
!
! unsigned numBytesSentSoFar = sendResult < 0 ? 0 : (unsigned)sendResult;
! if (numBytesSentSoFar > 0 || (forceSendToSucceed && envir().getErrno() == EAGAIN)) {
// The OS's TCP send buffer has filled up (because the stream's bitrate has exceeded
// the capacity of the TCP connection!).
// Force this data write to succeed, by blocking if necessary until it does:
--- 346,359 ----
#endif
Boolean RTPInterface::sendDataOverTCP(int socketNum, u_int8_t const* data, unsigned dataSize, Boolean forceSendToSucceed) {
+ if (dataSize <= 0) return True; // gaj: catch silly invocations
int sendResult = send(socketNum, (char const*)data, dataSize, 0/*flags*/);
+ int err = (sendResult < 0) ? envir().getErrno() : 0;
if (sendResult < (int)dataSize) {
// The TCP send() failed - at least partially.
! // gaj: send must always succeed - or close the socket
! if (sendResult >= 0 || err == EAGAIN) {
! const unsigned numBytesSentSoFar = sendResult < 0 ? 0 : (unsigned)sendResult;
// The OS's TCP send buffer has filled up (because the stream's bitrate has exceeded
// the capacity of the TCP connection!).
// Force this data write to succeed, by blocking if necessary until it does:
*************** Boolean RTPInterface::sendDataOverTCP(in
*** 376,382 ****
makeSocketNonBlocking(socketNum);
return True;
! } else if (sendResult < 0 && envir().getErrno() != EAGAIN) {
// Because the "send()" call failed, assume that the socket is now unusable, so stop
// using it (for both RTP and RTCP):
removeStreamSocket(socketNum, 0xFF);
--- 378,384 ----
makeSocketNonBlocking(socketNum);
return True;
! } else {
// Because the "send()" call failed, assume that the socket is now unusable, so stop
// using it (for both RTP and RTCP):
removeStreamSocket(socketNum, 0xFF);
_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel