From 4304e597d834e7fa0075a42cbab66575d950b018 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 17 Apr 2021 21:43:13 -0500 Subject: [PATCH] Add byteswapping macros for big-endian systems --- src/AudioStream.c | 6 +-- src/ByteBuffer.c | 12 ++--- src/ByteBuffer.h | 12 ----- src/ControlStream.c | 55 ++++++++++++++++------ src/InputStream.c | 108 ++++++++++++++++++++++---------------------- src/Platform.h | 35 ++++++++++++++ src/RtpFecQueue.c | 4 ++ src/VideoStream.c | 6 +-- 8 files changed, 146 insertions(+), 92 deletions(-) diff --git a/src/AudioStream.c b/src/AudioStream.c index 6874210..a4f4156 100644 --- a/src/AudioStream.c +++ b/src/AudioStream.c @@ -221,9 +221,9 @@ static void ReceiveThreadProc(void* context) { } // Convert fields to host byte-order - rtp->sequenceNumber = htons(rtp->sequenceNumber); - rtp->timestamp = htonl(rtp->timestamp); - rtp->ssrc = htonl(rtp->ssrc); + rtp->sequenceNumber = BE16(rtp->sequenceNumber); + rtp->timestamp = BE32(rtp->timestamp); + rtp->ssrc = BE32(rtp->ssrc); queueStatus = RtpqAddPacket(&rtpReorderQueue, (PRTP_PACKET)packet, &packet->q.rentry); if (RTPQ_HANDLE_NOW(queueStatus)) { diff --git a/src/ByteBuffer.c b/src/ByteBuffer.c index a1516c3..2c5f5f1 100644 --- a/src/ByteBuffer.c +++ b/src/ByteBuffer.c @@ -10,30 +10,30 @@ void BbInitializeWrappedBuffer(PBYTE_BUFFER buff, char* data, int offset, int le // Get the long long in the correct byte order static uint64_t byteSwap64(PBYTE_BUFFER buff, uint64_t l) { if (buff->byteOrder == BYTE_ORDER_BIG) { - return HTONLL(l); + return BE64(l); } else { - return l; + return LE64(l); } } // Get the int in the correct byte order static uint32_t byteSwap32(PBYTE_BUFFER buff, uint32_t i) { if (buff->byteOrder == BYTE_ORDER_BIG) { - return htonl(i); + return BE32(i); } else { - return i; + return LE32(i); } } // Get the short in the correct byte order static uint16_t byteSwap16(PBYTE_BUFFER buff, uint16_t s) { if (buff->byteOrder == BYTE_ORDER_BIG) { - return htons(s); + return BE16(s); } else { - return s; + return LE16(s); } } diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index c416f46..7f7ad52 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -5,18 +5,6 @@ #define BYTE_ORDER_LITTLE 1 #define BYTE_ORDER_BIG 2 -#ifndef HTONLL -#define HTONLL(x) \ - ((((x) & 0xff00000000000000ull) >> 56) \ - | (((x) & 0x00ff000000000000ull) >> 40) \ - | (((x) & 0x0000ff0000000000ull) >> 24) \ - | (((x) & 0x000000ff00000000ull) >> 8) \ - | (((x) & 0x00000000ff000000ull) << 8) \ - | (((x) & 0x0000000000ff0000ull) << 24) \ - | (((x) & 0x000000000000ff00ull) << 40) \ - | (((x) & 0x00000000000000ffull) << 56)) -#endif - typedef struct _BYTE_BUFFER { char* buffer; unsigned int length; diff --git a/src/ControlStream.c b/src/ControlStream.c index 30d2081..24e46c9 100644 --- a/src/ControlStream.c +++ b/src/ControlStream.c @@ -369,6 +369,9 @@ static PNVCTL_TCP_PACKET_HEADER readNvctlPacketTcp(void) { return NULL; } + staticHeader.type = LE16(staticHeader.type); + staticHeader.payloadLength = LE16(staticHeader.payloadLength); + fullPacket = (PNVCTL_TCP_PACKET_HEADER)malloc(staticHeader.payloadLength + sizeof(staticHeader)); if (fullPacket == NULL) { return NULL; @@ -390,6 +393,13 @@ static bool encryptControlMessage(PNVCTL_ENCRYPTED_PACKET_HEADER encPacket, PNVC unsigned char iv[16]; int encryptedSize = sizeof(*packet) + packet->payloadLength; + encPacket->encryptedHeaderType = LE16(encPacket->encryptedHeaderType); + encPacket->length = LE16(encPacket->length); + encPacket->seq = LE32(encPacket->seq); + + packet->type = LE16(packet->type); + packet->payloadLength = LE16(packet->payloadLength); + // This is a truncating cast, but it's what Nvidia does, so we have to mimic it. memset(iv, 0, sizeof(iv)); iv[0] = (unsigned char)encPacket->seq; @@ -479,7 +489,7 @@ static bool sendMessageEnet(short ptype, short paylen, const void* payload) { packet->payloadLength = paylen; memcpy(&packet[1], payload, paylen); - // Encrypt the data into the final packet + // Encrypt the data into the final packet (and byteswap for BE machines) if (!encryptControlMessage(encPacket, packet)) { Limelog("Failed to encrypt control stream message\n"); enet_packet_destroy(enetPacket); @@ -497,7 +507,7 @@ static bool sendMessageEnet(short ptype, short paylen, const void* payload) { } packet = (PNVCTL_ENET_PACKET_HEADER_V1)enetPacket->data; - packet->type = ptype; + packet->type = LE16(ptype); memcpy(&packet[1], payload, paylen); } @@ -528,8 +538,8 @@ static bool sendMessageTcp(short ptype, short paylen, const void* payload) { return false; } - packet->type = ptype; - packet->payloadLength = paylen; + packet->type = LE16(ptype); + packet->payloadLength = LE16(paylen); memcpy(&packet[1], payload, paylen); err = send(ctlSock, (char*) packet, sizeof(*packet) + paylen, 0); @@ -680,23 +690,34 @@ static void controlReceiveThreadFunc(void* context) { } ctlHdr = (PNVCTL_ENET_PACKET_HEADER_V1)event.packet->data; + ctlHdr->type = LE16(ctlHdr->type); if (encryptedControlStream) { // V2 headers can be interpreted as V1 headers for the purpose of examining type, // so this check is safe. if (ctlHdr->type == 0x0001) { + PNVCTL_ENCRYPTED_PACKET_HEADER encHdr; + if (event.packet->dataLength < sizeof(NVCTL_ENCRYPTED_PACKET_HEADER)) { Limelog("Discarding runt encrypted control packet: %d < %d\n", event.packet->dataLength, (int)sizeof(NVCTL_ENCRYPTED_PACKET_HEADER)); enet_packet_destroy(event.packet); continue; } + // encryptedHeaderType is already byteswapped by aliasing through ctlHdr above + encHdr = (PNVCTL_ENCRYPTED_PACKET_HEADER)event.packet->data; + encHdr->length = LE16(encHdr->length); + encHdr->seq = LE32(encHdr->seq); + ctlHdr = NULL; - if (!decryptControlMessageToV1((PNVCTL_ENCRYPTED_PACKET_HEADER)event.packet->data, &ctlHdr, &packetLength)) { + if (!decryptControlMessageToV1(encHdr, &ctlHdr, &packetLength)) { Limelog("Failed to decrypt control packet of size %d\n", event.packet->dataLength); enet_packet_destroy(event.packet); continue; } + + // We need to byteswap the unsealed header too + ctlHdr->type = LE16(ctlHdr->type); } else { // What do we do here??? @@ -706,7 +727,6 @@ static void controlReceiveThreadFunc(void* context) { } else { // Take ownership of the packet data directly for the non-encrypted case - ctlHdr = (PNVCTL_ENET_PACKET_HEADER_V1)event.packet->data; packetLength = event.packet->dataLength; event.packet->data = NULL; } @@ -879,11 +899,11 @@ static void requestIdrFrame(void) { // Form the payload if (lastSeenFrame < 0x20) { payload[0] = 0; - payload[1] = lastSeenFrame; + payload[1] = LE64(lastSeenFrame); } else { - payload[0] = lastSeenFrame - 0x20; - payload[1] = lastSeenFrame; + payload[0] = LE64(lastSeenFrame - 0x20); + payload[1] = LE64(lastSeenFrame); } payload[2] = 0; @@ -912,6 +932,8 @@ static void requestIdrFrame(void) { static void requestInvalidateReferenceFrames(void) { int64_t payload[3]; PQUEUED_FRAME_INVALIDATION_TUPLE qfit; + int startFrame; + int endFrame; LC_ASSERT(isReferenceFrameInvalidationEnabled()); @@ -921,17 +943,20 @@ static void requestInvalidateReferenceFrames(void) { LC_ASSERT(qfit->startFrame <= qfit->endFrame); - payload[0] = qfit->startFrame; - payload[1] = qfit->endFrame; - payload[2] = 0; + startFrame = qfit->startFrame; + endFrame = qfit->endFrame; // Aggregate all lost frames into one range do { - LC_ASSERT(qfit->endFrame >= payload[1]); - payload[1] = qfit->endFrame; + LC_ASSERT(qfit->endFrame >= endFrame); + endFrame = qfit->endFrame; free(qfit); } while (getNextFrameInvalidationTuple(&qfit)); + payload[0] = LE64(startFrame); + payload[1] = LE64(endFrame); + payload[2] = 0; + // Send the reference frame invalidation request and read the response if (!sendMessageAndDiscardReply(packetTypes[IDX_INVALIDATE_REF_FRAMES], payloadLengths[IDX_INVALIDATE_REF_FRAMES], payload)) { @@ -940,7 +965,7 @@ static void requestInvalidateReferenceFrames(void) { return; } - Limelog("Invalidate reference frame request sent (%d to %d)\n", (int)payload[0], (int)payload[1]); + Limelog("Invalidate reference frame request sent (%d to %d)\n", startFrame, endFrame); } static void invalidateRefFramesFunc(void* context) { diff --git a/src/InputStream.c b/src/InputStream.c index 1c8faef..bba41db 100644 --- a/src/InputStream.c +++ b/src/InputStream.c @@ -110,7 +110,7 @@ static void inputSendThreadProc(void* context) { } // If it's a multi-controller packet we can do batching - if (holder->packet.multiController.header.packetType == htonl(PACKET_TYPE_MULTI_CONTROLLER)) { + if (holder->packet.multiController.header.packetType == BE32(PACKET_TYPE_MULTI_CONTROLLER)) { PPACKET_HOLDER controllerBatchHolder; PNV_MULTI_CONTROLLER_PACKET origPkt; @@ -124,7 +124,7 @@ static void inputSendThreadProc(void* context) { } // If it's not a controller packet, we're done - if (controllerBatchHolder->packet.multiController.header.packetType != htonl(PACKET_TYPE_MULTI_CONTROLLER)) { + if (controllerBatchHolder->packet.multiController.header.packetType != BE32(PACKET_TYPE_MULTI_CONTROLLER)) { break; } @@ -159,10 +159,10 @@ static void inputSendThreadProc(void* context) { } } // If it's a relative mouse move packet, we can also do batching - else if (holder->packet.mouseMoveRel.header.packetType == htonl(PACKET_TYPE_REL_MOUSE_MOVE)) { + else if (holder->packet.mouseMoveRel.header.packetType == BE32(PACKET_TYPE_REL_MOUSE_MOVE)) { PPACKET_HOLDER mouseBatchHolder; - int totalDeltaX = (short)htons(holder->packet.mouseMoveRel.deltaX); - int totalDeltaY = (short)htons(holder->packet.mouseMoveRel.deltaY); + int totalDeltaX = (short)BE16(holder->packet.mouseMoveRel.deltaX); + int totalDeltaY = (short)BE16(holder->packet.mouseMoveRel.deltaY); for (;;) { int partialDeltaX; @@ -174,12 +174,12 @@ static void inputSendThreadProc(void* context) { } // If it's not a mouse move packet, we're done - if (mouseBatchHolder->packet.mouseMoveRel.header.packetType != htonl(PACKET_TYPE_REL_MOUSE_MOVE)) { + if (mouseBatchHolder->packet.mouseMoveRel.header.packetType != BE32(PACKET_TYPE_REL_MOUSE_MOVE)) { break; } - partialDeltaX = (short)htons(mouseBatchHolder->packet.mouseMoveRel.deltaX); - partialDeltaY = (short)htons(mouseBatchHolder->packet.mouseMoveRel.deltaY); + partialDeltaX = (short)BE16(mouseBatchHolder->packet.mouseMoveRel.deltaX); + partialDeltaY = (short)BE16(mouseBatchHolder->packet.mouseMoveRel.deltaY); // Check for overflow if (partialDeltaX + totalDeltaX > INT16_MAX || @@ -203,11 +203,11 @@ static void inputSendThreadProc(void* context) { } // Update the original packet - holder->packet.mouseMoveRel.deltaX = htons((short)totalDeltaX); - holder->packet.mouseMoveRel.deltaY = htons((short)totalDeltaY); + holder->packet.mouseMoveRel.deltaX = BE16((short)totalDeltaX); + holder->packet.mouseMoveRel.deltaY = BE16((short)totalDeltaY); } // If it's an absolute mouse move packet, we should only send the latest - else if (holder->packet.mouseMoveAbs.header.packetType == htonl(PACKET_TYPE_ABS_MOUSE_MOVE)) { + else if (holder->packet.mouseMoveAbs.header.packetType == BE32(PACKET_TYPE_ABS_MOUSE_MOVE)) { for (;;) { PPACKET_HOLDER mouseBatchHolder; @@ -217,7 +217,7 @@ static void inputSendThreadProc(void* context) { } // If it's not a mouse position packet, we're done - if (mouseBatchHolder->packet.mouseMoveAbs.header.packetType != htonl(PACKET_TYPE_ABS_MOUSE_MOVE)) { + if (mouseBatchHolder->packet.mouseMoveAbs.header.packetType != BE32(PACKET_TYPE_ABS_MOUSE_MOVE)) { break; } @@ -257,7 +257,7 @@ static void inputSendThreadProc(void* context) { } // Prepend the length to the message - encryptedLengthPrefix = htonl(encryptedSize); + encryptedLengthPrefix = BE32(encryptedSize); memcpy(&encryptedBuffer[0], &encryptedLengthPrefix, 4); if (AppVersionQuad[0] < 5) { @@ -310,9 +310,9 @@ static int sendEnableHaptics(void) { } holder->packetLength = sizeof(NV_HAPTICS_PACKET); - holder->packet.haptics.header.packetType = htonl(PACKET_TYPE_HAPTICS); - holder->packet.haptics.magicA = H_MAGIC_A; - holder->packet.haptics.magicB = H_MAGIC_B; + holder->packet.haptics.header.packetType = BE32(PACKET_TYPE_HAPTICS); + holder->packet.haptics.magicA = LE32(H_MAGIC_A); + holder->packet.haptics.magicB = LE32(H_MAGIC_B); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); if (err != LBQ_SUCCESS) { @@ -398,14 +398,15 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY) { } holder->packetLength = sizeof(NV_REL_MOUSE_MOVE_PACKET); - holder->packet.mouseMoveRel.header.packetType = htonl(PACKET_TYPE_REL_MOUSE_MOVE); + holder->packet.mouseMoveRel.header.packetType = BE32(PACKET_TYPE_REL_MOUSE_MOVE); holder->packet.mouseMoveRel.magic = MOUSE_MOVE_REL_MAGIC; // On Gen 5 servers, the header code is incremented by one if (AppVersionQuad[0] >= 5) { holder->packet.mouseMoveRel.magic++; } - holder->packet.mouseMoveRel.deltaX = htons(deltaX); - holder->packet.mouseMoveRel.deltaY = htons(deltaY); + holder->packet.mouseMoveRel.magic = LE32(holder->packet.mouseMoveRel.magic); + holder->packet.mouseMoveRel.deltaX = BE16(deltaX); + holder->packet.mouseMoveRel.deltaY = BE16(deltaY); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); if (err != LBQ_SUCCESS) { @@ -430,10 +431,10 @@ int LiSendMousePositionEvent(short x, short y, short referenceWidth, short refer } holder->packetLength = sizeof(NV_ABS_MOUSE_MOVE_PACKET); - holder->packet.mouseMoveAbs.header.packetType = htonl(PACKET_TYPE_ABS_MOUSE_MOVE); - holder->packet.mouseMoveAbs.magic = MOUSE_MOVE_ABS_MAGIC; - holder->packet.mouseMoveAbs.x = htons(x); - holder->packet.mouseMoveAbs.y = htons(y); + holder->packet.mouseMoveAbs.header.packetType = BE32(PACKET_TYPE_ABS_MOUSE_MOVE); + holder->packet.mouseMoveAbs.magic = LE32(MOUSE_MOVE_ABS_MAGIC); + holder->packet.mouseMoveAbs.x = BE16(x); + holder->packet.mouseMoveAbs.y = BE16(y); holder->packet.mouseMoveAbs.unused = 0; // There appears to be a rounding error in GFE's scaling calculation which prevents @@ -441,8 +442,8 @@ int LiSendMousePositionEvent(short x, short y, short referenceWidth, short refer // resolutions with a higher desktop resolution (like streaming 720p with a desktop // resolution of 1080p, or streaming 720p/1080p with a desktop resolution of 4K). // Subtracting one from the reference dimensions seems to work around this issue. - holder->packet.mouseMoveAbs.width = htons(referenceWidth - 1); - holder->packet.mouseMoveAbs.height = htons(referenceHeight - 1); + holder->packet.mouseMoveAbs.width = BE16(referenceWidth - 1); + holder->packet.mouseMoveAbs.height = BE16(referenceHeight - 1); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); if (err != LBQ_SUCCESS) { @@ -467,12 +468,12 @@ int LiSendMouseButtonEvent(char action, int button) { } holder->packetLength = sizeof(NV_MOUSE_BUTTON_PACKET); - holder->packet.mouseButton.header.packetType = htonl(PACKET_TYPE_MOUSE_BUTTON); + holder->packet.mouseButton.header.packetType = BE32(PACKET_TYPE_MOUSE_BUTTON); holder->packet.mouseButton.action = action; if (AppVersionQuad[0] >= 5) { holder->packet.mouseButton.action++; } - holder->packet.mouseButton.button = htonl(button); + holder->packet.mouseButton.button = BE32(button); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); if (err != LBQ_SUCCESS) { @@ -539,10 +540,10 @@ int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers) { } holder->packetLength = sizeof(NV_KEYBOARD_PACKET); - holder->packet.keyboard.header.packetType = htonl(PACKET_TYPE_KEYBOARD); + holder->packet.keyboard.header.packetType = BE32(PACKET_TYPE_KEYBOARD); holder->packet.keyboard.keyAction = keyAction; holder->packet.keyboard.zero1 = 0; - holder->packet.keyboard.keyCode = keyCode; + holder->packet.keyboard.keyCode = LE16(keyCode); holder->packet.keyboard.modifiers = modifiers; holder->packet.keyboard.zero2 = 0; @@ -574,41 +575,42 @@ static int sendControllerEventInternal(short controllerNumber, short activeGamep // Generation 3 servers don't support multiple controllers so we send // the legacy packet holder->packetLength = sizeof(NV_CONTROLLER_PACKET); - holder->packet.controller.header.packetType = htonl(PACKET_TYPE_CONTROLLER); - holder->packet.controller.headerA = C_HEADER_A; - holder->packet.controller.headerB = C_HEADER_B; - holder->packet.controller.buttonFlags = buttonFlags; + holder->packet.controller.header.packetType = BE32(PACKET_TYPE_CONTROLLER); + holder->packet.controller.headerA = LE32(C_HEADER_A); + holder->packet.controller.headerB = LE16(C_HEADER_B); + holder->packet.controller.buttonFlags = LE16(buttonFlags); holder->packet.controller.leftTrigger = leftTrigger; holder->packet.controller.rightTrigger = rightTrigger; - holder->packet.controller.leftStickX = leftStickX; - holder->packet.controller.leftStickY = leftStickY; - holder->packet.controller.rightStickX = rightStickX; - holder->packet.controller.rightStickY = rightStickY; - holder->packet.controller.tailA = C_TAIL_A; - holder->packet.controller.tailB = C_TAIL_B; + holder->packet.controller.leftStickX = LE16(leftStickX); + holder->packet.controller.leftStickY = LE16(leftStickY); + holder->packet.controller.rightStickX = LE16(rightStickX); + holder->packet.controller.rightStickY = LE16(rightStickY); + holder->packet.controller.tailA = LE32(C_TAIL_A); + holder->packet.controller.tailB = LE16(C_TAIL_B); } else { // Generation 4+ servers support passing the controller number holder->packetLength = sizeof(NV_MULTI_CONTROLLER_PACKET); - holder->packet.multiController.header.packetType = htonl(PACKET_TYPE_MULTI_CONTROLLER); + holder->packet.multiController.header.packetType = BE32(PACKET_TYPE_MULTI_CONTROLLER); holder->packet.multiController.headerA = MC_HEADER_A; // On Gen 5 servers, the header code is decremented by one if (AppVersionQuad[0] >= 5) { holder->packet.multiController.headerA--; } - holder->packet.multiController.headerB = MC_HEADER_B; - holder->packet.multiController.controllerNumber = controllerNumber; - holder->packet.multiController.activeGamepadMask = activeGamepadMask; - holder->packet.multiController.midB = MC_MID_B; - holder->packet.multiController.buttonFlags = buttonFlags; + holder->packet.multiController.headerA = LE32(holder->packet.multiController.headerA); + holder->packet.multiController.headerB = LE16(MC_HEADER_B); + holder->packet.multiController.controllerNumber = LE16(controllerNumber); + holder->packet.multiController.activeGamepadMask = LE16(activeGamepadMask); + holder->packet.multiController.midB = LE16(MC_MID_B); + holder->packet.multiController.buttonFlags = LE16(buttonFlags); holder->packet.multiController.leftTrigger = leftTrigger; holder->packet.multiController.rightTrigger = rightTrigger; - holder->packet.multiController.leftStickX = leftStickX; - holder->packet.multiController.leftStickY = leftStickY; - holder->packet.multiController.rightStickX = rightStickX; - holder->packet.multiController.rightStickY = rightStickY; - holder->packet.multiController.tailA = MC_TAIL_A; - holder->packet.multiController.tailB = MC_TAIL_B; + holder->packet.multiController.leftStickX = LE16(leftStickX); + holder->packet.multiController.leftStickY = LE16(leftStickY); + holder->packet.multiController.rightStickX = LE16(rightStickX); + holder->packet.multiController.rightStickY = LE16(rightStickY); + holder->packet.multiController.tailA = LE32(MC_TAIL_A); + holder->packet.multiController.tailB = LE16(MC_TAIL_B); } err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); @@ -656,7 +658,7 @@ int LiSendHighResScrollEvent(short scrollAmount) { } holder->packetLength = sizeof(NV_SCROLL_PACKET); - holder->packet.scroll.header.packetType = htonl(PACKET_TYPE_SCROLL); + holder->packet.scroll.header.packetType = BE32(PACKET_TYPE_SCROLL); holder->packet.scroll.magicA = MAGIC_A; // On Gen 5 servers, the header code is incremented by one if (AppVersionQuad[0] >= 5) { @@ -664,7 +666,7 @@ int LiSendHighResScrollEvent(short scrollAmount) { } holder->packet.scroll.zero1 = 0; holder->packet.scroll.zero2 = 0; - holder->packet.scroll.scrollAmt1 = htons(scrollAmount); + holder->packet.scroll.scrollAmt1 = BE16(scrollAmount); holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1; holder->packet.scroll.zero3 = 0; diff --git a/src/Platform.h b/src/Platform.h index 598a1a4..bdda9a3 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -61,6 +61,41 @@ #define LC_ASSERT(x) assert(x) #endif +#ifdef _MSC_VER +#pragma intrinsic(_byteswap_ushort) +#define BSWAP16(x) _byteswap_ushort(x) +#pragma intrinsic(_byteswap_ulong) +#define BSWAP32(x) _byteswap_ulong(x) +#pragma intrinsic(_byteswap_uint64) +#define BSWAP64(x) _byteswap_uint64(x) +#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +#define BSWAP16(x) __builtin_bswap16(x) +#define BSWAP32(x) __builtin_bswap32(x) +#define BSWAP64(x) __builtin_bswap64(x) +#elif defined(__has_builtin) && __has_builtin(__builtin_bswap16) +#define BSWAP16(x) __builtin_bswap16(x) +#define BSWAP32(x) __builtin_bswap32(x) +#define BSWAP64(x) __builtin_bswap64(x) +#else +#error Please define your platform's byteswap macros! +#endif + +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__) +#define LE16(x) BSWAP16(x) +#define LE32(x) BSWAP32(x) +#define LE64(x) BSWAP64(x) +#define BE16(x) (x) +#define BE32(x) (x) +#define BE64(x) (x) +#else +#define LE16(x) (x) +#define LE32(x) (x) +#define LE64(x) (x) +#define BE16(x) BSWAP16(x) +#define BE32(x) BSWAP32(x) +#define BE64(x) BSWAP64(x) +#endif + int initializePlatform(void); void cleanupPlatform(void); diff --git a/src/RtpFecQueue.c b/src/RtpFecQueue.c index 1902e71..2c08735 100644 --- a/src/RtpFecQueue.c +++ b/src/RtpFecQueue.c @@ -413,6 +413,10 @@ int RtpfAddPacket(PRTP_FEC_QUEUE queue, PRTP_PACKET packet, int length, PRTPFEC_ } PNV_VIDEO_PACKET nvPacket = (PNV_VIDEO_PACKET)(((char*)packet) + dataOffset); + + nvPacket->streamPacketIndex = LE32(nvPacket->streamPacketIndex); + nvPacket->frameIndex = LE32(nvPacket->frameIndex); + nvPacket->fecInfo = LE32(nvPacket->fecInfo); if (isBefore16(nvPacket->frameIndex, queue->currentFrameNumber)) { // Reject frames behind our current frame number diff --git a/src/VideoStream.c b/src/VideoStream.c index ecdad94..1b170b9 100644 --- a/src/VideoStream.c +++ b/src/VideoStream.c @@ -142,9 +142,9 @@ static void ReceiveThreadProc(void* context) { // Convert fields to host byte-order packet = (PRTP_PACKET)&buffer[0]; - packet->sequenceNumber = htons(packet->sequenceNumber); - packet->timestamp = htonl(packet->timestamp); - packet->ssrc = htonl(packet->ssrc); + packet->sequenceNumber = BE16(packet->sequenceNumber); + packet->timestamp = BE32(packet->timestamp); + packet->ssrc = BE32(packet->ssrc); queueStatus = RtpfAddPacket(&rtpQueue, packet, err, (PRTPFEC_QUEUE_ENTRY)&buffer[receiveSize]);