diff --git a/src/AudioStream.c b/src/AudioStream.c index 6407d3c..ee8da1c 100644 --- a/src/AudioStream.c +++ b/src/AudioStream.c @@ -37,12 +37,6 @@ typedef struct _QUEUED_AUDIO_PACKET { static void AudioPingThreadProc(void* context) { char legacyPingData[] = { 0x50, 0x49, 0x4E, 0x47 }; - LC_SOCKADDR saddr; - - LC_ASSERT(AudioPortNumber != 0); - - memcpy(&saddr, &RemoteAddr, sizeof(saddr)); - SET_PORT(&saddr, AudioPortNumber); // We do not check for errors here. Socket errors will be handled // on the read-side in ReceiveThreadProc(). This avoids potential @@ -54,10 +48,10 @@ static void AudioPingThreadProc(void* context) { pingCount++; AudioPingPayload.sequenceNumber = BE32(pingCount); - sendto(rtpSocket, (char*)&AudioPingPayload, sizeof(AudioPingPayload), 0, (struct sockaddr*)&saddr, RemoteAddrLen); + send(rtpSocket, (char*)&AudioPingPayload, sizeof(AudioPingPayload), 0); } else { - sendto(rtpSocket, legacyPingData, sizeof(legacyPingData), 0, (struct sockaddr*)&saddr, RemoteAddrLen); + send(rtpSocket, legacyPingData, sizeof(legacyPingData), 0); } PltSleepMsInterruptible(&udpPingThread, 500); @@ -98,9 +92,15 @@ int notifyAudioPortNegotiationComplete(void) { LC_ASSERT(!pingThreadStarted); LC_ASSERT(AudioPortNumber != 0); + // Connect our audio socket to the target address and port + int err = connectUdpSocket(rtpSocket, &RemoteAddr, RemoteAddrLen, AudioPortNumber); + if (err != 0) { + return err; + } + // We may receive audio before our threads are started, but that's okay. We'll // drop the first 1 second of audio packets to catch up with the backlog. - int err = PltCreateThread("AudioPing", AudioPingThreadProc, NULL, &udpPingThread); + err = PltCreateThread("AudioPing", AudioPingThreadProc, NULL, &udpPingThread); if (err != 0) { return err; } diff --git a/src/PlatformSockets.c b/src/PlatformSockets.c index 986903d..25a6905 100644 --- a/src/PlatformSockets.c +++ b/src/PlatformSockets.c @@ -309,6 +309,23 @@ SOCKET bindUdpSocket(int addrfamily, int bufferSize) { return s; } +int connectUdpSocket(SOCKET s, struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port) { + int err; + LC_SOCKADDR saddr; + + LC_ASSERT(port != 0); + + memcpy(&saddr, dstaddr, addrlen); + SET_PORT(&saddr, port); + err = connect(s, (struct sockaddr*)&saddr, addrlen); + if (err < 0) { + Limelog("connect() failed for UDP socket: %d\n", (int)LastSocketError()); + return LastSocketFail(); + } + + return 0; +} + int setSocketNonBlocking(SOCKET s, bool enabled) { #if defined(__vita__) int val = enabled ? 1 : 0; diff --git a/src/PlatformSockets.h b/src/PlatformSockets.h index 97c5ad6..5e72bbf 100644 --- a/src/PlatformSockets.h +++ b/src/PlatformSockets.h @@ -86,6 +86,7 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string); SOCKET createSocket(int addressFamily, int socketType, int protocol, bool nonBlocking); SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec); +int connectUdpSocket(SOCKET s, struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port); int sendMtuSafe(SOCKET s, char* buffer, int size); SOCKET bindUdpSocket(int addrfamily, int bufferSize); int enableNoDelay(SOCKET s); diff --git a/src/VideoStream.c b/src/VideoStream.c index 0429237..3041cc2 100644 --- a/src/VideoStream.c +++ b/src/VideoStream.c @@ -50,12 +50,6 @@ void destroyVideoStream(void) { // UDP Ping proc static void VideoPingThreadProc(void* context) { char legacyPingData[] = { 0x50, 0x49, 0x4E, 0x47 }; - LC_SOCKADDR saddr; - - LC_ASSERT(VideoPortNumber != 0); - - memcpy(&saddr, &RemoteAddr, sizeof(saddr)); - SET_PORT(&saddr, VideoPortNumber); // We do not check for errors here. Socket errors will be handled // on the read-side in ReceiveThreadProc(). This avoids potential @@ -67,10 +61,10 @@ static void VideoPingThreadProc(void* context) { pingCount++; VideoPingPayload.sequenceNumber = BE32(pingCount); - sendto(rtpSocket, (char*)&VideoPingPayload, sizeof(VideoPingPayload), 0, (struct sockaddr*)&saddr, RemoteAddrLen); + send(rtpSocket, (char*)&VideoPingPayload, sizeof(VideoPingPayload), 0); } else { - sendto(rtpSocket, legacyPingData, sizeof(legacyPingData), 0, (struct sockaddr*)&saddr, RemoteAddrLen); + send(rtpSocket, legacyPingData, sizeof(legacyPingData), 0); } PltSleepMsInterruptible(&udpPingThread, 500); @@ -271,6 +265,15 @@ int startVideoStream(void* rendererContext, int drFlags) { return LastSocketError(); } + // Connect our video socket to the target address and port + LC_ASSERT(VideoPortNumber != 0); + err = connectUdpSocket(rtpSocket, &RemoteAddr, RemoteAddrLen, VideoPortNumber); + if (err != 0) { + VideoCallbacks.cleanup(); + closeSocket(rtpSocket); + return err; + } + VideoCallbacks.start(); err = PltCreateThread("VideoRecv", VideoReceiveThreadProc, NULL, &receiveThread);