今天忽然发现了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
- }