发现live555中一个小bug

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

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

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

view plain
  1. void MultiFramedRTPSource::networkReadHandler1()  
  2. {  
  3.     BufferedPacket* bPacket = fPacketReadInProgress;  
  4.     if (bPacket == NULL) {  
  5.         // Normal case: Get a free BufferedPacket descriptor to hold the new network packet:  
  6.         bPacket = fReorderingBuffer->getFreePacket(this);  
  7.     }  
  8.   
  9.     // Read the network packet, and perform sanity checks on the RTP header:  
  10.     Boolean readSuccess = False;  
  11.     do {  
  12.         Boolean packetReadWasIncomplete = fPacketReadInProgress != NULL;  
  13.         if (!bPacket->fillInData(fRTPInterface, packetReadWasIncomplete))  
  14.             break;  
  15.         if (packetReadWasIncomplete) {  
  16.             // We need additional read(s) before we can process the incoming packet:  
  17.             fPacketReadInProgress = bPacket;  
  18.             return;  
  19.         } else {  
  20.             fPacketReadInProgress = NULL;  
  21.         }  
  22. #ifdef TEST_LOSS  
  23.         setPacketReorderingThresholdTime(0);  
  24.         // don't wait for 'lost' packets to arrive out-of-order later  
  25.         if ((our_random()%10) == 0) break;// simulate 10% packet loss  
  26. #endif  
  27.   
  28.         // Check for the 12-byte RTP header:  
  29.         if (bPacket->dataSize() < 12)  
  30.             break;  
  31.         unsigned rtpHdr = ntohl(*(u_int32_t*) (bPacket->data()));  
  32.         ADVANCE(4);  
  33.         Boolean rtpMarkerBit = (rtpHdr & 0x00800000) >> 23;  
  34.         unsigned rtpTimestamp = ntohl(*(u_int32_t*) (bPacket->data()));  
  35.         ADVANCE(4);  
  36.         unsigned rtpSSRC = ntohl(*(u_int32_t*) (bPacket->data()));  
  37.         ADVANCE(4);  
  38.   
  39.         // Check the RTP version number (it should be 2):  
  40.         if ((rtpHdr & 0xC0000000) != 0x80000000)  
  41.             break;  
  42.   
  43.         // Skip over any CSRC identifiers in the header:  
  44.         unsigned cc = (rtpHdr >> 24) & 0xF;  
  45.         if (bPacket->dataSize() < cc)  
  46.             break;ADVANCE(cc*4);  
  47.   
  48.         // Check for (& ignore) any RTP header extension  
  49.         if (rtpHdr & 0x10000000) {  
  50.             if (bPacket->dataSize() < 4)  
  51.                 break;  
  52.             unsigned extHdr = ntohl(*(u_int32_t*) (bPacket->data()));  
  53.             ADVANCE(4);  
  54.             unsigned remExtSize = 4 * (extHdr & 0xFFFF);  
  55.             if (bPacket->dataSize() < remExtSize)  
  56.                 break;  
  57.             ADVANCE(remExtSize);  
  58.         }  
  59.   
  60.         // Discard any padding bytes:  
  61.         if (rtpHdr & 0x20000000) {  
  62.             if (bPacket->dataSize() == 0)  
  63.                 break;  
  64.             unsigned numPaddingBytes = (unsigned) (bPacket->data())[bPacket->dataSize()  
  65.                     - 1];  
  66.             if (bPacket->dataSize() < numPaddingBytes)  
  67.                 break;  
  68.             bPacket->removePadding(numPaddingBytes);  
  69.         }  
  70.         // Check the Payload Type.  
  71.         if ((unsigned char) ((rtpHdr & 0x007F0000) >> 16)  
  72.                 != rtpPayloadFormat()) {  
  73.             break;  
  74.         }  
  75.   
  76.         // The rest of the packet is the usable data.  Record and save it:  
  77.         if (rtpSSRC != fLastReceivedSSRC) {  
  78.             // The SSRC of incoming packets has changed.  Unfortunately we don't yet handle streams that contain multiple SSRCs,  
  79.             // but we can handle a single-SSRC stream where the SSRC changes occasionally:  
  80.             fLastReceivedSSRC = rtpSSRC;  
  81.             fReorderingBuffer->resetHaveSeenFirstPacket();  
  82.         }  
  83.         unsigned short rtpSeqNo = (unsigned short) (rtpHdr & 0xFFFF);  
  84.         Boolean usableInJitterCalculation = packetIsUsableInJitterCalculation(  
  85.                 (bPacket->data()), bPacket->dataSize());  
  86.         struct timeval presentationTime; // computed by:  
  87.         Boolean hasBeenSyncedUsingRTCP; // computed by:  
  88.         receptionStatsDB().noteIncomingPacket(rtpSSRC, rtpSeqNo, rtpTimestamp,  
  89.                 timestampFrequency(), usableInJitterCalculation,  
  90.                 presentationTime, hasBeenSyncedUsingRTCP, bPacket->dataSize());  
  91.   
  92.         // Fill in the rest of the packet descriptor, and store it:  
  93.         struct timeval timeNow;  
  94.         gettimeofday(&timeNow, NULL);  
  95.         bPacket->assignMiscParams(rtpSeqNo, rtpTimestamp, presentationTime,  
  96.                 hasBeenSyncedUsingRTCP, rtpMarkerBit, timeNow);  
  97.         if (!fReorderingBuffer->storePacket(bPacket))  
  98.             break;  
  99.   
  100.         readSuccess = True;  
  101.     } while (0);  
  102.     if (!readSuccess){  
  103.         fReorderingBuffer->freePacket(bPacket);  
  104.         //------------通知调用者,我结束了!-----------------------------  
  105.         RTPSource::handleClosure(this);  
  106.         return;  
  107.         //--------------------------------------------------------------  
  108.     }  
  109.   
  110.     doGetNextFrame1();  
  111.     // If we didn't get proper data this time, we'll get another chance  
  112. }  

转自http://blog.csdn.net/nkmnkm/article/details/7003956

你可能感兴趣的:(发现live555中一个小bug)