现在的位置: 首页 > 综合 > 正文

发现live555中一个小bug

2013年08月21日 ⁄ 综合 ⁄ 共 3438字 ⁄ 字号 评论关闭

今天忽然发现了live555中的openRTSP.exe中的一个小问题。

在openRTSP.exe连上服务器后,如果服务器退出而没有发送TEARDOWN,openRTSP.exe不会退出,即使收不到数据,它也会一直等待下去。当然,这也可以不认为是一个bug,因为服务器不辞而别也不对。究其原因,主要是openRTSP.exe中所使用的RTPSource类没有对网络出错进行处理,所以尽管网络出错,收不到数据,接收数据的循环会一直进行下去。从这个解度讲也算是个bug吧。

要改正很容易,下面用//---------------标注者即是改正处:

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
}

抱歉!评论已关闭.