mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-02-16 02:21:07 +00:00
Add separate LC_ASSERT_VT() for asserts that only apply for valid traffic
This commit is contained in:
@@ -197,14 +197,14 @@ static void decodeInputData(PQUEUED_AUDIO_PACKET packet) {
|
||||
(unsigned char*)(rtp + 1), dataLength,
|
||||
decryptedOpusData, &dataLength)) {
|
||||
Limelog("Failed to decrypt audio packet (sequence number: %u)\n", rtp->sequenceNumber);
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LC_DEBUG
|
||||
if (opusHeaderByte == INVALID_OPUS_HEADER) {
|
||||
opusHeaderByte = decryptedOpusData[0];
|
||||
LC_ASSERT(opusHeaderByte != INVALID_OPUS_HEADER);
|
||||
LC_ASSERT_VT(opusHeaderByte != INVALID_OPUS_HEADER);
|
||||
}
|
||||
else {
|
||||
// Opus header should stay constant for the entire stream.
|
||||
@@ -212,7 +212,7 @@ static void decodeInputData(PQUEUED_AUDIO_PACKET packet) {
|
||||
// incorrectly recovered a data shard or the decryption
|
||||
// of the audio packet failed. Sunshine violates this for
|
||||
// surround sound in some cases, so just ignore it.
|
||||
LC_ASSERT(decryptedOpusData[0] == opusHeaderByte || IS_SUNSHINE());
|
||||
LC_ASSERT_VT(decryptedOpusData[0] == opusHeaderByte || IS_SUNSHINE());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -222,13 +222,13 @@ static void decodeInputData(PQUEUED_AUDIO_PACKET packet) {
|
||||
#ifdef LC_DEBUG
|
||||
if (opusHeaderByte == INVALID_OPUS_HEADER) {
|
||||
opusHeaderByte = ((uint8_t*)(rtp + 1))[0];
|
||||
LC_ASSERT(opusHeaderByte != INVALID_OPUS_HEADER);
|
||||
LC_ASSERT_VT(opusHeaderByte != INVALID_OPUS_HEADER);
|
||||
}
|
||||
else {
|
||||
// Opus header should stay constant for the entire stream.
|
||||
// If it doesn't, it may indicate that the RtpAudioQueue
|
||||
// incorrectly recovered a data shard.
|
||||
LC_ASSERT(((uint8_t*)(rtp + 1))[0] == opusHeaderByte);
|
||||
LC_ASSERT_VT(((uint8_t*)(rtp + 1))[0] == opusHeaderByte);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ void connectionSendFrameFecStatus(PSS_FRAME_FEC_STATUS fecStatus) {
|
||||
}
|
||||
|
||||
void connectionSawFrame(int frameIndex) {
|
||||
LC_ASSERT(!isBefore16(frameIndex, lastSeenFrame));
|
||||
LC_ASSERT_VT(!isBefore16(frameIndex, lastSeenFrame));
|
||||
|
||||
uint64_t now = PltGetMillis();
|
||||
|
||||
@@ -1123,7 +1123,7 @@ static void controlReceiveThreadFunc(void* context) {
|
||||
}
|
||||
else {
|
||||
// What do we do here???
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
packetLength = (int)event.packet->dataLength;
|
||||
event.packet->data = NULL;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,17 @@
|
||||
#define LC_ASSERT(x) assert(x)
|
||||
#endif
|
||||
|
||||
// If we're fuzzing, we don't want to enable asserts that can be affected by
|
||||
// bad input from the remote host. LC_ASSERT_VT() is used for assertions that
|
||||
// check data that comes from the host. These checks are enabled for normal
|
||||
// debug builds, since they indicate an error in Moonlight or on the host.
|
||||
// These are disabled when fuzzing, since the traffic is intentionally invalid.
|
||||
#ifdef LC_FUZZING
|
||||
#define LC_ASSERT_VT(x)
|
||||
#else
|
||||
#define LC_ASSERT_VT(x) LC_ASSERT(x)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma intrinsic(_byteswap_ushort)
|
||||
#define BSWAP16(x) _byteswap_ushort(x)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Limelight-internal.h"
|
||||
|
||||
#ifdef LC_DEBUG
|
||||
#if defined(LC_DEBUG) && !defined(LC_FUZZING)
|
||||
// This enables FEC validation mode with a synthetic drop
|
||||
// and recovered packet checks vs the original input. It
|
||||
// is on by default for debug builds.
|
||||
@@ -86,12 +86,12 @@ static void validateFecBlockState(PRTP_AUDIO_QUEUE queue) {
|
||||
while (block != NULL) {
|
||||
// Ensure the list is sorted correctly
|
||||
LC_ASSERT(isBefore16(lastSeqNum, block->fecHeader.baseSequenceNumber));
|
||||
LC_ASSERT(isBefore32(lastTs, block->fecHeader.baseTimestamp));
|
||||
LC_ASSERT_VT(isBefore32(lastTs, block->fecHeader.baseTimestamp));
|
||||
|
||||
// Ensure entry invariants are satisfied
|
||||
LC_ASSERT(block->blockSize == lastBlock->blockSize);
|
||||
LC_ASSERT(block->fecHeader.payloadType == lastBlock->fecHeader.payloadType);
|
||||
LC_ASSERT(block->fecHeader.ssrc == lastBlock->fecHeader.ssrc);
|
||||
LC_ASSERT_VT(block->blockSize == lastBlock->blockSize);
|
||||
LC_ASSERT_VT(block->fecHeader.payloadType == lastBlock->fecHeader.payloadType);
|
||||
LC_ASSERT_VT(block->fecHeader.ssrc == lastBlock->fecHeader.ssrc);
|
||||
|
||||
// Ensure the list itself is consistent
|
||||
LC_ASSERT(block->prev == lastBlock);
|
||||
@@ -205,7 +205,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
if (packet->packetType == RTP_PAYLOAD_TYPE_AUDIO) {
|
||||
if (length < sizeof(RTP_PACKET)) {
|
||||
Limelog("RTP audio data packet too small: %u\n", length);
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
|
||||
if (length < sizeof(RTP_PACKET) + sizeof(AUDIO_FEC_HEADER)) {
|
||||
Limelog("RTP audio FEC packet too small: %u\n", length);
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
// later during recovery.
|
||||
if (fecHeader->fecShardIndex >= RTPA_FEC_SHARDS) {
|
||||
Limelog("Too many audio FEC shards: %u\n", fecHeader->fecShardIndex);
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
Limelog("Invalid FEC block base sequence number (got %u, expected %u)\n",
|
||||
fecBlockBaseSeqNum, (fecBlockBaseSeqNum / RTPA_DATA_SHARDS) * RTPA_DATA_SHARDS);
|
||||
Limelog("Audio FEC has been disabled due to an incompatibility with your host's old software!\n");
|
||||
LC_ASSERT(fecBlockBaseSeqNum % RTPA_DATA_SHARDS == 0);
|
||||
LC_ASSERT_VT(fecBlockBaseSeqNum % RTPA_DATA_SHARDS == 0);
|
||||
queue->incompatibleServer = true;
|
||||
return NULL;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
}
|
||||
else {
|
||||
Limelog("Invalid RTP audio payload type: %u\n", packet->packetType);
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -296,9 +296,9 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
while (existingBlock != NULL) {
|
||||
if (existingBlock->fecHeader.baseSequenceNumber == fecBlockBaseSeqNum) {
|
||||
// The FEC header data should match for all packets
|
||||
LC_ASSERT(existingBlock->fecHeader.payloadType == fecBlockPayloadType);
|
||||
LC_ASSERT(existingBlock->fecHeader.baseTimestamp == fecBlockBaseTs);
|
||||
LC_ASSERT(existingBlock->fecHeader.ssrc == fecBlockSsrc);
|
||||
LC_ASSERT_VT(existingBlock->fecHeader.payloadType == fecBlockPayloadType);
|
||||
LC_ASSERT_VT(existingBlock->fecHeader.baseTimestamp == fecBlockBaseTs);
|
||||
LC_ASSERT_VT(existingBlock->fecHeader.ssrc == fecBlockSsrc);
|
||||
|
||||
// The block size must match in order to safely copy shards into it
|
||||
if (existingBlock->blockSize != blockSize) {
|
||||
@@ -306,7 +306,7 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
// constant size for audio packets.
|
||||
Limelog("Audio block size mismatch (got %u, expected %u)\n", blockSize, existingBlock->blockSize);
|
||||
Limelog("Audio FEC has been disabled due to an incompatibility with your host's old software!\n");
|
||||
LC_ASSERT(existingBlock->blockSize == blockSize);
|
||||
LC_ASSERT_VT(existingBlock->blockSize == blockSize);
|
||||
queue->incompatibleServer = true;
|
||||
return NULL;
|
||||
}
|
||||
@@ -464,11 +464,11 @@ static bool completeFecBlock(PRTP_AUDIO_QUEUE queue, PRTPA_FEC_BLOCK block) {
|
||||
|
||||
#ifdef FEC_VALIDATION_MODE
|
||||
// Check the RTP header values
|
||||
LC_ASSERT(block->dataPackets[dropIndex]->header == droppedRtpPacket->header);
|
||||
LC_ASSERT(block->dataPackets[dropIndex]->packetType == droppedRtpPacket->packetType);
|
||||
LC_ASSERT(block->dataPackets[dropIndex]->sequenceNumber == droppedRtpPacket->sequenceNumber);
|
||||
LC_ASSERT(block->dataPackets[dropIndex]->timestamp == droppedRtpPacket->timestamp);
|
||||
LC_ASSERT(block->dataPackets[dropIndex]->ssrc == droppedRtpPacket->ssrc);
|
||||
LC_ASSERT_VT(block->dataPackets[dropIndex]->header == droppedRtpPacket->header);
|
||||
LC_ASSERT_VT(block->dataPackets[dropIndex]->packetType == droppedRtpPacket->packetType);
|
||||
LC_ASSERT_VT(block->dataPackets[dropIndex]->sequenceNumber == droppedRtpPacket->sequenceNumber);
|
||||
LC_ASSERT_VT(block->dataPackets[dropIndex]->timestamp == droppedRtpPacket->timestamp);
|
||||
LC_ASSERT_VT(block->dataPackets[dropIndex]->ssrc == droppedRtpPacket->ssrc);
|
||||
|
||||
// Check the data itself - use memcmp() and only loop if an error is detected
|
||||
if (memcmp(block->dataPackets[dropIndex] + 1, droppedRtpPacket + 1, block->blockSize)) {
|
||||
@@ -484,7 +484,7 @@ static bool completeFecBlock(PRTP_AUDIO_QUEUE queue, PRTPA_FEC_BLOCK block) {
|
||||
}
|
||||
}
|
||||
|
||||
LC_ASSERT(recoveryErrors == 0);
|
||||
LC_ASSERT_VT(recoveryErrors == 0);
|
||||
}
|
||||
|
||||
free(droppedRtpPacket);
|
||||
@@ -523,7 +523,7 @@ static void handleMissingPackets(PRTP_AUDIO_QUEUE queue) {
|
||||
// If we reach this point, we know the next packet resides in the first FEC block we're
|
||||
// currently waiting on. In that case, we want to wait at least until we have a second FEC
|
||||
// block to give up on the first one. If we don't have a second block now, just keep waiting.
|
||||
LC_ASSERT(isBefore16(queue->nextRtpSequenceNumber, queue->blockHead->fecHeader.baseSequenceNumber + RTPA_DATA_SHARDS));
|
||||
LC_ASSERT_VT(isBefore16(queue->nextRtpSequenceNumber, queue->blockHead->fecHeader.baseSequenceNumber + RTPA_DATA_SHARDS));
|
||||
if (queue->blockHead == queue->blockTail) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Limelight-internal.h"
|
||||
#include "rs.h"
|
||||
|
||||
#ifdef LC_DEBUG
|
||||
#if defined(LC_DEBUG) && !defined(LC_FUZZING)
|
||||
// This enables FEC validation mode with a synthetic drop
|
||||
// and recovered packet checks vs the original input. It
|
||||
// is on by default for debug builds.
|
||||
@@ -376,15 +376,15 @@ cleanup_packets:
|
||||
int j;
|
||||
int recoveryErrors = 0;
|
||||
|
||||
LC_ASSERT(droppedDataLength <= recoveredDataLength);
|
||||
LC_ASSERT(droppedDataLength == recoveredDataLength || (nvPacket->flags & FLAG_EOF));
|
||||
LC_ASSERT_VT(droppedDataLength <= recoveredDataLength);
|
||||
LC_ASSERT_VT(droppedDataLength == recoveredDataLength || (nvPacket->flags & FLAG_EOF));
|
||||
|
||||
// Check all NV_VIDEO_PACKET fields except FEC stuff which differs in the recovered packet
|
||||
LC_ASSERT(nvPacket->flags == droppedNvPacket->flags);
|
||||
LC_ASSERT(nvPacket->frameIndex == droppedNvPacket->frameIndex);
|
||||
LC_ASSERT(nvPacket->streamPacketIndex == droppedNvPacket->streamPacketIndex);
|
||||
LC_ASSERT(nvPacket->reserved == droppedNvPacket->reserved);
|
||||
LC_ASSERT(!queue->multiFecCapable || nvPacket->multiFecBlocks == droppedNvPacket->multiFecBlocks);
|
||||
LC_ASSERT_VT(nvPacket->flags == droppedNvPacket->flags);
|
||||
LC_ASSERT_VT(nvPacket->frameIndex == droppedNvPacket->frameIndex);
|
||||
LC_ASSERT_VT(nvPacket->streamPacketIndex == droppedNvPacket->streamPacketIndex);
|
||||
LC_ASSERT_VT(nvPacket->reserved == droppedNvPacket->reserved);
|
||||
LC_ASSERT_VT(!queue->multiFecCapable || nvPacket->multiFecBlocks == droppedNvPacket->multiFecBlocks);
|
||||
|
||||
// Check the data itself - use memcmp() and only loop if an error is detected
|
||||
if (memcmp(nvPacket + 1, droppedNvPacket + 1, droppedDataLength)) {
|
||||
@@ -409,7 +409,7 @@ cleanup_packets:
|
||||
}
|
||||
}
|
||||
|
||||
LC_ASSERT(recoveryErrors == 0);
|
||||
LC_ASSERT_VT(recoveryErrors == 0);
|
||||
|
||||
// This drop was fake, so we don't want to actually submit it to the depacketizer.
|
||||
// It will get confused because it's already seen this packet before.
|
||||
@@ -542,7 +542,7 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_
|
||||
}
|
||||
|
||||
// FLAG_EXTENSION is required for all supported versions of GFE.
|
||||
LC_ASSERT(packet->header & FLAG_EXTENSION);
|
||||
LC_ASSERT_VT(packet->header & FLAG_EXTENSION);
|
||||
|
||||
int dataOffset = sizeof(*packet);
|
||||
if (packet->header & FLAG_EXTENSION) {
|
||||
@@ -567,11 +567,13 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_
|
||||
nvPacket->multiFecFlags = 0x10;
|
||||
nvPacket->multiFecBlocks = 0x00;
|
||||
}
|
||||
|
||||
|
||||
#ifndef LC_FUZZING
|
||||
if (isBefore16(nvPacket->frameIndex, queue->currentFrameNumber)) {
|
||||
// Reject frames behind our current frame number
|
||||
return RTPF_RET_REJECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t fecIndex = (nvPacket->fecInfo & 0x3FF000) >> 12;
|
||||
uint8_t fecCurrentBlockNumber = (nvPacket->multiFecBlocks >> 4) & 0x3;
|
||||
@@ -666,7 +668,7 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_
|
||||
// The check here looks weird, but that's because we increment the frame number
|
||||
// after successfully processing a frame.
|
||||
if (queue->currentFrameNumber != nvPacket->frameIndex) {
|
||||
LC_ASSERT(queue->currentFrameNumber < nvPacket->frameIndex);
|
||||
LC_ASSERT_VT(queue->currentFrameNumber < nvPacket->frameIndex);
|
||||
|
||||
// If the frame immediately preceding this one was lost, we may have already
|
||||
// reported it using our speculative RFI logic. Don't report it again.
|
||||
@@ -707,19 +709,19 @@ int RtpvAddPacket(PRTP_VIDEO_QUEUE queue, PRTP_PACKET packet, int length, PRTPV_
|
||||
return RTPF_RET_REJECTED;
|
||||
}
|
||||
|
||||
LC_ASSERT(!queue->fecPercentage || U16(packet->sequenceNumber - fecIndex) == queue->bufferLowestSequenceNumber);
|
||||
LC_ASSERT((nvPacket->fecInfo & 0xFF0) >> 4 == queue->fecPercentage);
|
||||
LC_ASSERT((nvPacket->fecInfo & 0xFFC00000) >> 22 == queue->bufferDataPackets);
|
||||
LC_ASSERT_VT(!queue->fecPercentage || U16(packet->sequenceNumber - fecIndex) == queue->bufferLowestSequenceNumber);
|
||||
LC_ASSERT_VT((nvPacket->fecInfo & 0xFF0) >> 4 == queue->fecPercentage);
|
||||
LC_ASSERT_VT((nvPacket->fecInfo & 0xFFC00000) >> 22 == queue->bufferDataPackets);
|
||||
|
||||
// Verify that the legacy non-multi-FEC compatibility code works
|
||||
LC_ASSERT(queue->multiFecCapable || fecCurrentBlockNumber == 0);
|
||||
LC_ASSERT(queue->multiFecCapable || queue->multiFecLastBlockNumber == 0);
|
||||
LC_ASSERT_VT(queue->multiFecCapable || fecCurrentBlockNumber == 0);
|
||||
LC_ASSERT_VT(queue->multiFecCapable || queue->multiFecLastBlockNumber == 0);
|
||||
|
||||
// Multi-block FEC details must remain the same within a single frame
|
||||
LC_ASSERT(fecCurrentBlockNumber == queue->multiFecCurrentBlockNumber);
|
||||
LC_ASSERT(((nvPacket->multiFecBlocks >> 6) & 0x3) == queue->multiFecLastBlockNumber);
|
||||
LC_ASSERT_VT(fecCurrentBlockNumber == queue->multiFecCurrentBlockNumber);
|
||||
LC_ASSERT_VT(((nvPacket->multiFecBlocks >> 6) & 0x3) == queue->multiFecLastBlockNumber);
|
||||
|
||||
LC_ASSERT((nvPacket->flags & FLAG_EOF) || length - dataOffset == StreamConfig.packetSize);
|
||||
LC_ASSERT_VT((nvPacket->flags & FLAG_EOF) || length - dataOffset == StreamConfig.packetSize);
|
||||
if (!queuePacket(queue, packetEntry, packet, length, !isBefore16(packet->sequenceNumber, queue->bufferFirstParitySequenceNumber), false)) {
|
||||
return RTPF_RET_REJECTED;
|
||||
}
|
||||
|
||||
@@ -198,27 +198,27 @@ void validateDecodeUnitForPlayback(PDECODE_UNIT decodeUnit) {
|
||||
// IDR frames always start with codec configuration data
|
||||
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||
// H.264 IDR frames should have an SPS, PPS, then picture data
|
||||
LC_ASSERT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_SPS);
|
||||
LC_ASSERT(decodeUnit->bufferList->next != NULL);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_PPS);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->next != NULL);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PICDATA);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_SPS);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next != NULL);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_PPS);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->next != NULL);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PICDATA);
|
||||
}
|
||||
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||
// HEVC IDR frames should have an VPS, SPS, PPS, then picture data
|
||||
LC_ASSERT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_VPS);
|
||||
LC_ASSERT(decodeUnit->bufferList->next != NULL);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_SPS);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->next != NULL);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PPS);
|
||||
LC_ASSERT(decodeUnit->bufferList->next->next->next != NULL);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_VPS);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next != NULL);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->bufferType == BUFFER_TYPE_SPS);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->next != NULL);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->next->bufferType == BUFFER_TYPE_PPS);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->next->next->next != NULL);
|
||||
|
||||
// We get 2 sets of VPS, SPS, and PPS NALUs in HDR mode.
|
||||
// FIXME: Should we normalize this or something for clients?
|
||||
}
|
||||
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_AV1) {
|
||||
// We don't parse the AV1 bitstream
|
||||
LC_ASSERT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_PICDATA);
|
||||
LC_ASSERT_VT(decodeUnit->bufferList->bufferType == BUFFER_TYPE_PICDATA);
|
||||
}
|
||||
else {
|
||||
LC_ASSERT(false);
|
||||
@@ -697,7 +697,7 @@ static void processAvcHevcRtpPayloadSlow(PBUFFER_DESC currentPos, PLENTRY_INTERN
|
||||
while (currentPos->length != 0) {
|
||||
// Any NALUs we encounter on the way to the end of the packet must be
|
||||
// reference frame slices or filler data.
|
||||
LC_ASSERT(isSeqReferenceFrameStart(currentPos) || isFillerDataNal(currentPos));
|
||||
LC_ASSERT_VT(isSeqReferenceFrameStart(currentPos) || isFillerDataNal(currentPos));
|
||||
skipToNextNalOrEnd(currentPos);
|
||||
}
|
||||
}
|
||||
@@ -765,7 +765,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
firstPacket = isFirstPacket(flags, fecCurrentBlockNumber);
|
||||
lastPacket = (flags & FLAG_EOF) && fecCurrentBlockNumber == fecLastBlockNumber;
|
||||
|
||||
LC_ASSERT((flags & ~(FLAG_SOF | FLAG_EOF | FLAG_CONTAINS_PIC_DATA)) == 0);
|
||||
LC_ASSERT_VT((flags & ~(FLAG_SOF | FLAG_EOF | FLAG_CONTAINS_PIC_DATA)) == 0);
|
||||
|
||||
streamPacketIndex = videoPacket->streamPacketIndex;
|
||||
|
||||
@@ -843,10 +843,10 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
|
||||
// If this is the first packet, skip the frame header (if one exists)
|
||||
uint32_t frameHeaderSize;
|
||||
LC_ASSERT(currentPos.length > 0);
|
||||
LC_ASSERT_VT(currentPos.length > 0);
|
||||
if (firstPacket && currentPos.length > 0) {
|
||||
// Parse the frame type from the header
|
||||
LC_ASSERT(currentPos.length >= 4);
|
||||
LC_ASSERT_VT(currentPos.length >= 4);
|
||||
if (APP_VERSION_AT_LEAST(7, 1, 350) && currentPos.length >= 4) {
|
||||
switch (currentPos.data[currentPos.offset + 3]) {
|
||||
case 1: // Normal P-frame
|
||||
@@ -874,7 +874,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
break;
|
||||
default:
|
||||
Limelog("Unrecognized frame type: %d", currentPos.data[currentPos.offset + 3]);
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -888,7 +888,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
}
|
||||
|
||||
// Sunshine can provide host processing latency of the frame
|
||||
LC_ASSERT(currentPos.length >= 3);
|
||||
LC_ASSERT_VT(currentPos.length >= 3);
|
||||
if (IS_SUNSHINE() && currentPos.length >= 3) {
|
||||
BYTE_BUFFER bb;
|
||||
BbInitializeWrappedBuffer(&bb, currentPos.data, currentPos.offset + 1, 2, BYTE_ORDER_LITTLE);
|
||||
@@ -897,7 +897,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
|
||||
// Codecs like H.264 and HEVC handle the FEC trailing zero padding just fine, but other
|
||||
// codecs need the exact length encoded separately.
|
||||
LC_ASSERT(currentPos.length >= 6);
|
||||
LC_ASSERT_VT(currentPos.length >= 6);
|
||||
if (!(NegotiatedVideoFormat & (VIDEO_FORMAT_MASK_H264 | VIDEO_FORMAT_MASK_H265)) && currentPos.length >= 6) {
|
||||
BYTE_BUFFER bb;
|
||||
BbInitializeWrappedBuffer(&bb, currentPos.data, currentPos.offset + 4, 2, BYTE_ORDER_LITTLE);
|
||||
@@ -912,7 +912,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
frameHeaderSize = 8;
|
||||
}
|
||||
else {
|
||||
LC_ASSERT(currentPos.data[0] == (char)0x81);
|
||||
LC_ASSERT_VT(currentPos.data[0] == (char)0x81);
|
||||
frameHeaderSize = 44;
|
||||
}
|
||||
}
|
||||
@@ -924,7 +924,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
frameHeaderSize = 8;
|
||||
}
|
||||
else {
|
||||
LC_ASSERT(currentPos.data[0] == (char)0x81);
|
||||
LC_ASSERT_VT(currentPos.data[0] == (char)0x81);
|
||||
frameHeaderSize = 41;
|
||||
}
|
||||
}
|
||||
@@ -936,7 +936,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
frameHeaderSize = 8;
|
||||
}
|
||||
else {
|
||||
LC_ASSERT(currentPos.data[0] == (char)0x81);
|
||||
LC_ASSERT_VT(currentPos.data[0] == (char)0x81);
|
||||
frameHeaderSize = 24;
|
||||
}
|
||||
}
|
||||
@@ -957,7 +957,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
frameHeaderSize = 0;
|
||||
}
|
||||
|
||||
LC_ASSERT(currentPos.length >= frameHeaderSize);
|
||||
LC_ASSERT_VT(currentPos.length >= frameHeaderSize);
|
||||
if (currentPos.length >= frameHeaderSize) {
|
||||
// Skip past the frame header
|
||||
currentPos.offset += frameHeaderSize;
|
||||
@@ -969,7 +969,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
// The Annex B NALU start prefix must be next
|
||||
if (!getAnnexBStartSequence(¤tPos, NULL)) {
|
||||
// If we aren't starting on a start prefix, something went wrong.
|
||||
LC_ASSERT(false);
|
||||
LC_ASSERT_VT(false);
|
||||
|
||||
// For release builds, we will try to recover by searching for one.
|
||||
// This mimics the way most decoders handle this situation.
|
||||
@@ -1022,11 +1022,11 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||
// of trailing zero padding like H.264/HEVC Annex B bitstream parsers are.
|
||||
if (lastPacket) {
|
||||
// The payload length includes the frame header, so it cannot be smaller than that
|
||||
LC_ASSERT(lastPacketPayloadLength > frameHeaderSize);
|
||||
LC_ASSERT_VT(lastPacketPayloadLength > frameHeaderSize);
|
||||
|
||||
// The payload length cannot be smaller than the actual received payload
|
||||
// NB: currentPos.length is already adjusted to exclude the frameHeaderSize from above
|
||||
LC_ASSERT(lastPacketPayloadLength - frameHeaderSize <= currentPos.length);
|
||||
LC_ASSERT_VT(lastPacketPayloadLength - frameHeaderSize <= currentPos.length);
|
||||
|
||||
// If the payload length is valid, truncate the packet. If not, discard this frame.
|
||||
if (lastPacketPayloadLength > frameHeaderSize && lastPacketPayloadLength - frameHeaderSize <= currentPos.length) {
|
||||
|
||||
@@ -135,6 +135,7 @@ static void VideoReceiveThreadProc(void* context) {
|
||||
firstDataTimeMs = PltGetMillis();
|
||||
}
|
||||
|
||||
#ifndef LC_FUZZING
|
||||
if (!receivedFullFrame) {
|
||||
uint64_t now = PltGetMillis();
|
||||
|
||||
@@ -144,6 +145,7 @@ static void VideoReceiveThreadProc(void* context) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err < (int)sizeof(RTP_PACKET)) {
|
||||
// Runt packet
|
||||
|
||||
Reference in New Issue
Block a user