您的位置:首页 > 其它

发现live555中一个小bug

2011-11-23 14:06 281 查看
今天忽然发现了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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: