live555에서 작은 버그 발견

오늘 갑자기 라이브 555의 오픈 RTSP를 발견했습니다.exe의 작은 문제
openRTSP.exe가 서버에 연결된 후 서버가 종료되고 TEARDOWN이 전송되지 않으면 openRTSP.exe는 종료되지 않습니다. 데이터를 받지 못해도 계속 기다립니다.물론 이것은 버그라고 생각하지 않을 수도 있다. 왜냐하면 서버가 작별을 고하지 않아도 옳지 않기 때문이다.그 원인은 주로 오픈RTSP이다.exe에서 사용하는 RTPSource 클래스는 네트워크 오류를 처리하지 않았기 때문에 네트워크 오류가 발생하여 데이터를 받지 못하더라도 데이터를 받는 순환은 계속 진행될 것입니다.이 정도로도 버그라고 할 수 있겠지.
수정은 매우 쉽습니다. 다음은//----------------------- 치수자가 바로 수정처입니다.
void MultiFramedRTPSource::networkReadHandler1()
{
	BufferedPacket* bPacket = fPacketReadInProgress;
	if (bPacket == NULL) {
		// Normal case: Get a free BufferedPacket descriptor to hold the new network packet:
		bPacket = fReorderingBuffer->getFreePacket(this);
	}

	// Read the network packet, and perform sanity checks on the RTP header:
	Boolean readSuccess = False;
	do {
		Boolean packetReadWasIncomplete = fPacketReadInProgress != NULL;
		if (!bPacket->fillInData(fRTPInterface, packetReadWasIncomplete))
			break;
		if (packetReadWasIncomplete) {
			// We need additional read(s) before we can process the incoming packet:
			fPacketReadInProgress = bPacket;
			return;
		} else {
			fPacketReadInProgress = NULL;
		}
#ifdef TEST_LOSS
		setPacketReorderingThresholdTime(0);
		// don't wait for 'lost' packets to arrive out-of-order later
		if ((our_random()%10) == 0) break;// simulate 10% packet loss
#endif

		// Check for the 12-byte RTP header:
		if (bPacket->dataSize() < 12)
			break;
		unsigned rtpHdr = ntohl(*(u_int32_t*) (bPacket->data()));
		ADVANCE(4);
		Boolean rtpMarkerBit = (rtpHdr & 0x00800000) >> 23;
		unsigned rtpTimestamp = ntohl(*(u_int32_t*) (bPacket->data()));
		ADVANCE(4);
		unsigned rtpSSRC = ntohl(*(u_int32_t*) (bPacket->data()));
		ADVANCE(4);

		// Check the RTP version number (it should be 2):
		if ((rtpHdr & 0xC0000000) != 0x80000000)
			break;

		// Skip over any CSRC identifiers in the header:
		unsigned cc = (rtpHdr >> 24) & 0xF;
		if (bPacket->dataSize() < cc)
			break;ADVANCE(cc*4);

		// Check for (& ignore) any RTP header extension
		if (rtpHdr & 0x10000000) {
			if (bPacket->dataSize() < 4)
				break;
			unsigned extHdr = ntohl(*(u_int32_t*) (bPacket->data()));
			ADVANCE(4);
			unsigned remExtSize = 4 * (extHdr & 0xFFFF);
			if (bPacket->dataSize() < remExtSize)
				break;
			ADVANCE(remExtSize);
		}

		// Discard any padding bytes:
		if (rtpHdr & 0x20000000) {
			if (bPacket->dataSize() == 0)
				break;
			unsigned numPaddingBytes = (unsigned) (bPacket->data())[bPacket->dataSize()
					- 1];
			if (bPacket->dataSize() < numPaddingBytes)
				break;
			bPacket->removePadding(numPaddingBytes);
		}
		// Check the Payload Type.
		if ((unsigned char) ((rtpHdr & 0x007F0000) >> 16)
				!= rtpPayloadFormat()) {
			break;
		}

		// The rest of the packet is the usable data.  Record and save it:
		if (rtpSSRC != fLastReceivedSSRC) {
			// The SSRC of incoming packets has changed.  Unfortunately we don't yet handle streams that contain multiple SSRCs,
			// but we can handle a single-SSRC stream where the SSRC changes occasionally:
			fLastReceivedSSRC = rtpSSRC;
			fReorderingBuffer->resetHaveSeenFirstPacket();
		}
		unsigned short rtpSeqNo = (unsigned short) (rtpHdr & 0xFFFF);
		Boolean usableInJitterCalculation = packetIsUsableInJitterCalculation(
				(bPacket->data()), bPacket->dataSize());
		struct timeval presentationTime; // computed by:
		Boolean hasBeenSyncedUsingRTCP; // computed by:
		receptionStatsDB().noteIncomingPacket(rtpSSRC, rtpSeqNo, rtpTimestamp,
				timestampFrequency(), usableInJitterCalculation,
				presentationTime, hasBeenSyncedUsingRTCP, bPacket->dataSize());

		// Fill in the rest of the packet descriptor, and store it:
		struct timeval timeNow;
		gettimeofday(&timeNow, NULL);
		bPacket->assignMiscParams(rtpSeqNo, rtpTimestamp, presentationTime,
				hasBeenSyncedUsingRTCP, rtpMarkerBit, timeNow);
		if (!fReorderingBuffer->storePacket(bPacket))
			break;

		readSuccess = True;
	} while (0);
	if (!readSuccess){
		fReorderingBuffer->freePacket(bPacket);
		//------------ , !-----------------------------
		RTPSource::handleClosure(this);
		return;
		//--------------------------------------------------------------
	}

	doGetNextFrame1();
	// If we didn't get proper data this time, we'll get another chance
}

좋은 웹페이지 즐겨찾기