Inin an article of the modified code does not work .After the test,Vibram Five Fingers, the RTPSource Socket cannot detect a network error condition .In RTCPInstance socket can be detected ,Vibram 5 Fingers Shoes,so you can use the RTCPInstance notification RTPSource should stop stream transmission .
Modified as follows ( / / --------------------- contains code to modify Office ) :void RTCPInstance: :incomingReportHandler1 ( ) {do {int tcpReadStreamSocketNum = fRTCPInterface.nextTCPReadStreamSocketNum ( ) ;unsigned char tcpReadStreamChannelId = fRTCPInterface.
nextTCPReadStreamChannelId ( ) ;unsigned packetSize = 0 ;unsigned numBytesRead ;struct sockaddr_in fromAddress ;Boolean packetReadWasIncomplete ;Boolean readResult = fRTCPInterface.handleRead ( & ;fInBuf / fNumBytesAlreadyRead ,maxPacketSize - fNumBytesAlreadyRead ,numBytesRead ,fromAddress ,packetReadWasIncomplete ) ;if ( packetReadWasIncomplete ) {fNumBytesAlreadyRead + = numBytesRead ;return ;/ / more reads are needed to get the entire packet} else { / / normal case: We read the entire packetpacketSize = fNumBytesAlreadyRead + numBytesRead ;fNumBytesAlreadyRead = 0 ;/ / for next time} if ( !ReadResult ) { / / -------------------------------- / / error, stop the network reading fRTCPInterface.
stopNetworkReading ( ) ;/ / notification RTPSource and RTPSink ,the network goes wrong, should stop if ( fSink ) fSink-> ;StopPlaying ( ) ;if ( fSource-> fSource ) ;handleClosure ( fSource ( void * ) ) ;/ / --------------------------------- break ;} / / Ignore the packet if it was looped-back from ourself: Boolean packetWasFromOurHost = False if ( ) ;RTCPgs ( > ;wasLoopedBackFromUs ( envir ) ,( fromAddress ) ) {packetWasFromOurHost = True ;/ / However ,we still want to handle incoming RTCP packets from / / * other processes * on the same machine .
To distinguish from a true this / / case loop-back ,check whether we ve just sent a / / packet of the same size. ( This check isn t perfect ,but it seems / / to be the best we can do.
) if ( fHaveJustSentPacket & ;& ;fLastPacketSentSize = = packetSize ) { / / This is a true loop-back: fHaveJustSentPacket = False ;break ;/ / ignore this packet} } unsigned char * pkt = fInBuf if ( fIsSSMSource ;& ;& ;packetWasFromOurHost !) { / / This packet is assumed to have been received via unicast ( because we re a SSM source ,and SSM receivers send back RTCP " ;RR" ;/ / packets via unicast ) .
the packet by resending it to the multic Ast group ,so that any other receivers can also / / get to see it. / / NOTE: Denial-of-service attacks are possible here. / / Users of this software may wish to add their own ,/ / application-specific mechanism for the of this packet / / validity before reflecting it.
/ / NOTE: The test for " ;packetWasFromOurHost" ;means that we won ! reflect RTCP packets that come from other processes same host as on / / the US . The reason for this is that the packet size above is not 100% reliable ;some were truly looped packets / / that back from us might not be detected as such ,and this might lead to infinite forwarding / receiving / / of some packets .
To avoid this possibility ,we only reflect RTCP packets that we know for sure originated elsewhere. / / ( Note ,though ,that if we ever re-enable the code in " ;Groupsock: :multicastSendOnly ( ) ,then we could " ;remove the test for / / " ;packetWasFromOurHost" ;!.
) fRTCPInterface.sendPacket ( pkt ,packetSize ) ;fHaveJustSentPacket = True ;fLastPacketSentSize = packetSize ;} ifdef DEBUGfprintf ( stderr ," # ; saw incoming RTCP packet ( from address %s ,port %d ) ,this ,our_inet_ntoa n" ;( fromAddress.
sin_addr ) ,ntohs ( fromAddress.sin_port ) ) ;for ( unsigned I = 0 ;I < ;packetSize ;I + + ) {if ( i%4 = = = = = = = = = = = = 0) fprintf ( stderr ," ;" ;fprintf ) ;( stderr ," ;%02x" ;pkt , ) ;} fprintf ( stderr ," ; n" ;) ;# endifint totPacketSize = IP_UDP_HDR_SIZE + packetSize ;/ / Check the RTCP packet for validity : / / It must at least contain a header ( 4 bytes ) ,and this header / / must be version = 2 ,with no padding bit ,and a payload type of / / SR ( 200) or RR ( 201) :if ( packetSize < ;break unsigned rtcpHdr = 4 ) ;ntohl ( pkt * ( u_int32_t * ) ) ;if ( ( rtcpHdr, & ;0xE0FE0000 ) != ( 0x80000000 ( RTCP_PT_SR < ;< ;16.
) ) ) { ifdef DEBUGfprintf ( stderr # ," ;rejected bad RTCP packet: header 0x%08x n" ;rtcpHdr ;endifbreak ,# ) ;} / / Process each of the individual RTCP in ( what may be ) / / a compound RTCP packet.
int typeOfPacket = PACKET_UNKNOWN_TYPE ;unsigned reportSenderSSRC = 0 ;Boolean pack EtOK = False ;while ( 1) {unsigned RC = ( rtcpHdr > ;> ;& ;0x1F 24 ) ;unsigned Pt = ( rtcpHdr > ;> ;& ;0xFF 16 ) ;unsigned length = 4 * ( rtcpHdr & ;0xFFFF ) ;/ / doesn t count hdrADVANCE ( 4) ;/ / skip over the headerif ( length > ;packetSize break Assume that ) ;/ / each RTCP subpacket begins with a 4-byte SSRC: if ( length < ;4) break ;length = 4 ;reportSenderSSRC = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;Boolean subPacketOK = False switch ( PT ;) {case RTCP_PT_SR: { # ifdef DEBUGfprintf ( stderr ," ;SR ,n" ;endifif ( length < ) ;# ;20) break ;length = 20 ;/ / Extract the NTP timestamp ,and note this: unsigned NTPmsw = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;unsigned NTPlsw = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;unsigned rtpTimestamp = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;if ( fSource != NULL ) {RTPReceptionStatsDB& ;receptionStats = fSource-> ;receptionStatsDB ( ) ;receptionStats.
noteIncomingSR ( reportSenderSSRC ,NTPmsw ,NTPlsw ,rtpTimestamp ) ;} ADVANCE ( 8) ;/ / skip over packet count ,octet count / / If a SR handler set ,call it Now: if ( fSRHandlerTask != NULL ) ( fSRHandlerTask ) ( fSRHandlerClientData ) ;/ / The rest of the SR is handled like a RR ( so ,no " ;break ;" ;here ) } case { RTCP_PT_RR :DEBUGfprintf ( stderr ," # ifdef ;RR ,n" ;reportBlocksSize = endifunsigned ;# ) RC * ( 6 * 4) ;if ( length < ;reportBlocksSize break ;length = reportBlocksSize ) ;if ( fSink != NULL ) { / / Use this information to update stats about our transmissions: RTPTransmissionStatsDB& ;transmissionStats = fSink-> ;transmissionStatsDB ( ) ;for ( unsigned I = 0 ;I < ;RC ;+ + I ) {unsigned senderSSRC = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;/ / We care only about reports about our own transmission ,not others if ( senderSSRC = = fSink-> ;SSRC ( ) ) {unsigned lossStats = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;unsigned highestReceived = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;unsigned jitter = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;unsigned timeLastSR = ntohl ( pkt * ( u_int32_t * ) ) ;ADVANCE ( 4) ;unsigned timeSinceLastSR = ntohl ( * ( u_int32_t * ) ) ;pkt ADVANCE ( 4) transmissionStats.
noteIncomingRR ( repo ;RtSenderSSRC ,fromAddress ,lossStats ,highestReceived ,jitter ,timeLastSR ,timeSinceLastSR ) ;} else {ADVANCE ( 4 * 5) ;} } } else {ADVANCE ( reportBlocksSize ) ;} if ( PT = = RTCP_PT_RR ) { / / i.
e t fall through ,we didn from / / If a RR handler was set ,call it now: / / Specific RR handler: if ( fSpecificRRHandlerTable != NULL ) {netAddressBits fromAddr ;portNumBits fromPortNum ;if ( tcpReadStreamSocketNum < ;0) { / / Normal case: We read the RTCP packet over UDPfromAddr = fromAddress.
sin_addr.s_addr ;fromPortNum = ntohs ( fromAddress.sin_port ) ;} else { / Case : We read the / Special RTCP packet over TCP ( interleaved ) / / Hack: Use the TCP socket and channel ID to look up the handlerfromAddr = tcpReadStreamSocketNum ;fromPortNum = tcpReadStreamChannelId ;} Port fromPort ( fromPortNum ) ;RRHandlerRecord * rrHandler = ( RRHandlerRecord * ( fSpecificRRHandlerTable-> ) ;Lookup ( fromAddr ,Coach Outlet,( ~ 0 ) ,fromPort ) ) ;if ( rrHandler != NULL ) {if ( rrHandler-> ;rrHandlerTask != NULL ) { ( x ( rrHandler-> ;rrHandlerTask ) ) ( rrHandler-> ;rrHandlerClientData ) ;} } } / / General RR handler: if ( fRRHandlerTask != NULL ) ( fRRHandlerTask ) ( fRRHandlerClientData ) ;} subPacketOK = True ;typeOfPacket = PACKET_RTCP_REPORT ;break ;} case { RTCP_PT_BYE :DEBUGfprintf ( stderr ," # ifdef ;BYE n" ;) ;/ / If a # ENDIF handler was set ,call it now : TaskFunc * byeHandler = fByeHandlerTask ;if ( byeHandler != NULL& ;& ;( fByeHandleActiveParticipantsOnly ( !FSource != NULL& ;& ;fSource-> ;receptionStatsDB ( ) .
Lookup ( reportSenderSSRC ) != NULL ) ( fSink != NULL& ;& ;fSink-> ;transmissionStatsDB ( ) . Lookup ( reportSenderSSRC ) != NULL ) ) ) {fByeHandlerTask = NULL ;/ / we call this only once by default ( byeHandler ) ( fByeHandlerClientData ) ;} / / We should really check for & ;handle > ;1 SSRCs being present # # # # # subPacketOK = True ;typeOfPacket = PACKET_BYE ;break ;} / / Later handle SDES ,APP ,and compound RTCP packets # # # # # default: # ifdef DEBUGfprintf ( stderr ," ;UNSUPPORTED TYPE n" ( 0x%x ) ;,PT ) ;# endifsubPacketOK = True; break ;} if ( subPacketOK break !) ;/ / need to check for ( & ;handle ) SSRC collision !# # # # # # ifde F DEBUGfprintf ( stderr ," ;validated RTCP subpacket ( type %d ) :%d ,%d ,%d ,0x%08x ,n" ;typeOfPacket ,RC ,Pt ,length ,ENDIF ,reportSenderSSRC ) ;/ / Skip # over any remaining bytes in this subpacket: ADVANCE ( length ) ;/ / Check whether another RTCP follows: if ( packetSize = = 0 ) {packetOK = True ;break ;} else if ( packetSize < ;4 ifdef DEBUGfprintf ( ) { # stderr ," ;extraneous %d bytes at end of RTCP packet ! n" ;endifbreak ,packetSize ) ;# ;} rtcpHdr = ntohl ( pkt * ( u_int32_t * ) ( ( ) ;if rtcpHdr & ;0xC0000000 ) != 0x80000000 ) { ifdef DEBUGfprintf ( stderr # ," ;bad RTCP subpacket: header 0x%08x n" ;rtcpHdr ;endifbreak ,# ) ;} } if ( !PacketOK ifdef DEBUGfprintf ( stderr ) { # ," ;rejected bad RTCP subpacket: header 0x%08x n" ,rtcpHdr ) ;endifbreak ;# ;} else { ifdef DEBUGfprintf ( stderr # ," ;validated entire RTCP packet n" ;) ;# ENDIF} onReceive ( typeOfPacket ,Christian Louboutin Outlet,totPacketSize ,reportSenderSSRC ) ;} while ( 0) ;} ,fSource const * type, designers are not so used ,but couldn way ,UGG Boots Clearance,And the test no problem ,but cannot ensure that in future versions will not be problems .
Related articles:
没有评论:
发表评论