From ce22e6534e808c593f3ef29e7cb87028262c8ba8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 21 Jun 2016 12:26:08 -0400 Subject: [PATCH] fix tabs --- src/zm_rtp_source.cpp | 592 +++++++++++++++++++++--------------------- 1 file changed, 296 insertions(+), 296 deletions(-) diff --git a/src/zm_rtp_source.cpp b/src/zm_rtp_source.cpp index 16bb171c4..3fc66f6d7 100644 --- a/src/zm_rtp_source.cpp +++ b/src/zm_rtp_source.cpp @@ -27,374 +27,374 @@ #if HAVE_LIBAVCODEC RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId ) : - mId( id ), - mSsrc( ssrc ), - mLocalHost( localHost ), - mRemoteHost( remoteHost ), - mRtpClock( rtpClock ), - mCodecId( codecId ), - mFrame( 65536 ), - mFrameCount( 0 ), - mFrameGood( true ), - mFrameReady( false ), - mFrameProcessed( false ) + mId( id ), + mSsrc( ssrc ), + mLocalHost( localHost ), + mRemoteHost( remoteHost ), + mRtpClock( rtpClock ), + mCodecId( codecId ), + mFrame( 65536 ), + mFrameCount( 0 ), + mFrameGood( true ), + mFrameReady( false ), + mFrameProcessed( false ) { - char hostname[256] = ""; - gethostname( hostname, sizeof(hostname) ); + char hostname[256] = ""; + gethostname( hostname, sizeof(hostname) ); - mCname = stringtf( "zm-%d@%s", mId, hostname ); - Debug( 3, "RTP CName = %s", mCname.c_str() ); + mCname = stringtf( "zm-%d@%s", mId, hostname ); + Debug( 3, "RTP CName = %s", mCname.c_str() ); - init( seq ); - mMaxSeq = seq - 1; - mProbation = MIN_SEQUENTIAL; + init( seq ); + mMaxSeq = seq - 1; + mProbation = MIN_SEQUENTIAL; - mLocalPortChans[0] = localPortBase; - mLocalPortChans[1] = localPortBase+1; + mLocalPortChans[0] = localPortBase; + mLocalPortChans[1] = localPortBase+1; - mRemotePortChans[0] = remotePortBase; - mRemotePortChans[1] = remotePortBase+1; + mRemotePortChans[0] = remotePortBase; + mRemotePortChans[1] = remotePortBase+1; - mRtpFactor = mRtpClock; + mRtpFactor = mRtpClock; - mBaseTimeReal = tvNow(); - mBaseTimeNtp = tvZero(); - mBaseTimeRtp = rtpTime; + mBaseTimeReal = tvNow(); + mBaseTimeNtp = tvZero(); + mBaseTimeRtp = rtpTime; - mLastSrTimeReal = tvZero(); - mLastSrTimeNtp = tvZero(); - mLastSrTimeRtp = 0; - - if(mCodecId != AV_CODEC_ID_H264 && mCodecId != AV_CODEC_ID_MPEG4) - Warning( "The device is using a codec that may not be supported. Do not be surprised if things don't work." ); + mLastSrTimeReal = tvZero(); + mLastSrTimeNtp = tvZero(); + mLastSrTimeRtp = 0; + + if(mCodecId != AV_CODEC_ID_H264 && mCodecId != AV_CODEC_ID_MPEG4) + Warning( "The device is using a codec that may not be supported. Do not be surprised if things don't work." ); } void RtpSource::init( uint16_t seq ) { - Debug( 3, "Initialising sequence" ); - mBaseSeq = seq; - mMaxSeq = seq; - mBadSeq = RTP_SEQ_MOD + 1; // so seq == mBadSeq is false - mCycles = 0; - mReceivedPackets = 0; - mReceivedPrior = 0; - mExpectedPrior = 0; - // other initialization - mJitter = 0; - mTransit = 0; + Debug( 3, "Initialising sequence" ); + mBaseSeq = seq; + mMaxSeq = seq; + mBadSeq = RTP_SEQ_MOD + 1; // so seq == mBadSeq is false + mCycles = 0; + mReceivedPackets = 0; + mReceivedPrior = 0; + mExpectedPrior = 0; + // other initialization + mJitter = 0; + mTransit = 0; } bool RtpSource::updateSeq( uint16_t seq ) { - uint16_t uDelta = seq - mMaxSeq; + uint16_t uDelta = seq - mMaxSeq; - // Source is not valid until MIN_SEQUENTIAL packets with - // sequential sequence numbers have been received. - Debug( 5, "Seq: %d", seq ); + // Source is not valid until MIN_SEQUENTIAL packets with + // sequential sequence numbers have been received. + Debug( 5, "Seq: %d", seq ); - if ( mProbation) + if ( mProbation) + { + // packet is in sequence + if ( seq == mMaxSeq + 1) { - // packet is in sequence - if ( seq == mMaxSeq + 1) - { - Debug( 3, "Sequence in probation %d, in sequence", mProbation ); - mProbation--; - mMaxSeq = seq; - if ( mProbation == 0 ) - { - init( seq ); - mReceivedPackets++; - return( true ); - } - } - else - { - Warning( "Sequence in probation %d, out of sequence", mProbation ); - mProbation = MIN_SEQUENTIAL - 1; - mMaxSeq = seq; - return( false ); - } + Debug( 3, "Sequence in probation %d, in sequence", mProbation ); + mProbation--; + mMaxSeq = seq; + if ( mProbation == 0 ) + { + init( seq ); + mReceivedPackets++; return( true ); - } - else if ( uDelta < MAX_DROPOUT ) - { - if ( uDelta == 1 ) - { - Debug( 4, "Packet in sequence, gap %d", uDelta ); - } - else - { - Warning( "Packet in sequence, gap %d", uDelta ); - } - - // in order, with permissible gap - if ( seq < mMaxSeq ) - { - // Sequence number wrapped - count another 64K cycle. - mCycles += RTP_SEQ_MOD; - } - mMaxSeq = seq; - } - else if ( uDelta <= RTP_SEQ_MOD - MAX_MISORDER ) - { - Warning( "Packet out of sequence, gap %d", uDelta ); - // the sequence number made a very large jump - if ( seq == mBadSeq ) - { - Debug( 3, "Restarting sequence" ); - // Two sequential packets -- assume that the other side - // restarted without telling us so just re-sync - // (i.e., pretend this was the first packet). - init( seq ); - } - else - { - mBadSeq = (seq + 1) & (RTP_SEQ_MOD-1); - return( false ); - } + } } else { - Warning( "Packet duplicate or reordered, gap %d", uDelta ); - // duplicate or reordered packet - return( false ); + Warning( "Sequence in probation %d, out of sequence", mProbation ); + mProbation = MIN_SEQUENTIAL - 1; + mMaxSeq = seq; + return( false ); } - mReceivedPackets++; - return( uDelta==1?true:false ); + return( true ); + } + else if ( uDelta < MAX_DROPOUT ) + { + if ( uDelta == 1 ) + { + Debug( 4, "Packet in sequence, gap %d", uDelta ); + } + else + { + Warning( "Packet in sequence, gap %d", uDelta ); + } + + // in order, with permissible gap + if ( seq < mMaxSeq ) + { + // Sequence number wrapped - count another 64K cycle. + mCycles += RTP_SEQ_MOD; + } + mMaxSeq = seq; + } + else if ( uDelta <= RTP_SEQ_MOD - MAX_MISORDER ) + { + Warning( "Packet out of sequence, gap %d", uDelta ); + // the sequence number made a very large jump + if ( seq == mBadSeq ) + { + Debug( 3, "Restarting sequence" ); + // Two sequential packets -- assume that the other side + // restarted without telling us so just re-sync + // (i.e., pretend this was the first packet). + init( seq ); + } + else + { + mBadSeq = (seq + 1) & (RTP_SEQ_MOD-1); + return( false ); + } + } + else + { + Warning( "Packet duplicate or reordered, gap %d", uDelta ); + // duplicate or reordered packet + return( false ); + } + mReceivedPackets++; + return( uDelta==1?true:false ); } void RtpSource::updateJitter( const RtpDataHeader *header ) { - if ( mRtpFactor > 0 ) - { - Debug( 5, "Delta rtp = %.6f", tvDiffSec( mBaseTimeReal ) ); - uint32_t localTimeRtp = mBaseTimeRtp + uint32_t( tvDiffSec( mBaseTimeReal ) * mRtpFactor ); - Debug( 5, "Local RTP time = %x", localTimeRtp ); - Debug( 5, "Packet RTP time = %x", ntohl(header->timestampN) ); - uint32_t packetTransit = localTimeRtp - ntohl(header->timestampN); - Debug( 5, "Packet transit RTP time = %x", packetTransit ); + if ( mRtpFactor > 0 ) + { + Debug( 5, "Delta rtp = %.6f", tvDiffSec( mBaseTimeReal ) ); + uint32_t localTimeRtp = mBaseTimeRtp + uint32_t( tvDiffSec( mBaseTimeReal ) * mRtpFactor ); + Debug( 5, "Local RTP time = %x", localTimeRtp ); + Debug( 5, "Packet RTP time = %x", ntohl(header->timestampN) ); + uint32_t packetTransit = localTimeRtp - ntohl(header->timestampN); + Debug( 5, "Packet transit RTP time = %x", packetTransit ); - if ( mTransit > 0 ) - { - // Jitter - int d = packetTransit - mTransit; - Debug( 5, "Jitter D = %d", d ); - if ( d < 0 ) - d = -d; - //mJitter += (1./16.) * ((double)d - mJitter); - mJitter += d - ((mJitter + 8) >> 4); - } - mTransit = packetTransit; - } - else + if ( mTransit > 0 ) { - mJitter = 0; + // Jitter + int d = packetTransit - mTransit; + Debug( 5, "Jitter D = %d", d ); + if ( d < 0 ) + d = -d; + //mJitter += (1./16.) * ((double)d - mJitter); + mJitter += d - ((mJitter + 8) >> 4); } - Debug( 5, "RTP Jitter: %d", mJitter ); + mTransit = packetTransit; + } + else + { + mJitter = 0; + } + Debug( 5, "RTP Jitter: %d", mJitter ); } void RtpSource::updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime ) { - struct timeval ntpTime = tvMake( ntpTimeSecs, suseconds_t((USEC_PER_SEC*(ntpTimeFrac>>16))/(1<<16)) ); + struct timeval ntpTime = tvMake( ntpTimeSecs, suseconds_t((USEC_PER_SEC*(ntpTimeFrac>>16))/(1<<16)) ); + Debug( 5, "ntpTime: %ld.%06ld, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime ); + + if ( mBaseTimeNtp.tv_sec == 0 ) + { + mBaseTimeReal = tvNow(); + mBaseTimeNtp = ntpTime; + mBaseTimeRtp = rtpTime; + } + else if ( !mRtpClock ) + { + Debug( 5, "lastSrNtpTime: %ld.%06ld, rtpTime: %x", mLastSrTimeNtp.tv_sec, mLastSrTimeNtp.tv_usec, rtpTime ); Debug( 5, "ntpTime: %ld.%06ld, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime ); - - if ( mBaseTimeNtp.tv_sec == 0 ) - { - mBaseTimeReal = tvNow(); - mBaseTimeNtp = ntpTime; - mBaseTimeRtp = rtpTime; - } - else if ( !mRtpClock ) - { - Debug( 5, "lastSrNtpTime: %ld.%06ld, rtpTime: %x", mLastSrTimeNtp.tv_sec, mLastSrTimeNtp.tv_usec, rtpTime ); - Debug( 5, "ntpTime: %ld.%06ld, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime ); - double diffNtpTime = tvDiffSec( mBaseTimeNtp, ntpTime ); - uint32_t diffRtpTime = rtpTime - mBaseTimeRtp; + double diffNtpTime = tvDiffSec( mBaseTimeNtp, ntpTime ); + uint32_t diffRtpTime = rtpTime - mBaseTimeRtp; - //Debug( 5, "Real-diff: %.6f", diffRealTime ); - Debug( 5, "NTP-diff: %.6f", diffNtpTime ); - Debug( 5, "RTP-diff: %d", diffRtpTime ); + //Debug( 5, "Real-diff: %.6f", diffRealTime ); + Debug( 5, "NTP-diff: %.6f", diffNtpTime ); + Debug( 5, "RTP-diff: %d", diffRtpTime ); - mRtpFactor = (uint32_t)(diffRtpTime / diffNtpTime); + mRtpFactor = (uint32_t)(diffRtpTime / diffNtpTime); - Debug( 5, "RTPfactor: %d", mRtpFactor ); - } - mLastSrTimeNtpSecs = ntpTimeSecs; - mLastSrTimeNtpFrac = ntpTimeFrac; - mLastSrTimeNtp = ntpTime; - mLastSrTimeRtp = rtpTime; + Debug( 5, "RTPfactor: %d", mRtpFactor ); + } + mLastSrTimeNtpSecs = ntpTimeSecs; + mLastSrTimeNtpFrac = ntpTimeFrac; + mLastSrTimeNtp = ntpTime; + mLastSrTimeRtp = rtpTime; } void RtpSource::updateRtcpStats() { - uint32_t extendedMax = mCycles + mMaxSeq; - mExpectedPackets = extendedMax - mBaseSeq + 1; + uint32_t extendedMax = mCycles + mMaxSeq; + mExpectedPackets = extendedMax - mBaseSeq + 1; - Debug( 5, "Expected packets = %d", mExpectedPackets ); + Debug( 5, "Expected packets = %d", mExpectedPackets ); - // The number of packets lost is defined to be the number of packets - // expected less the number of packets actually received: - mLostPackets = mExpectedPackets - mReceivedPackets; - Debug( 5, "Lost packets = %d", mLostPackets ); + // The number of packets lost is defined to be the number of packets + // expected less the number of packets actually received: + mLostPackets = mExpectedPackets - mReceivedPackets; + Debug( 5, "Lost packets = %d", mLostPackets ); - uint32_t expectedInterval = mExpectedPackets - mExpectedPrior; - Debug( 5, "Expected interval = %d", expectedInterval ); - mExpectedPrior = mExpectedPackets; - uint32_t receivedInterval = mReceivedPackets - mReceivedPrior; - Debug( 5, "Received interval = %d", receivedInterval ); - mReceivedPrior = mReceivedPackets; - uint32_t lostInterval = expectedInterval - receivedInterval; - Debug( 5, "Lost interval = %d", lostInterval ); + uint32_t expectedInterval = mExpectedPackets - mExpectedPrior; + Debug( 5, "Expected interval = %d", expectedInterval ); + mExpectedPrior = mExpectedPackets; + uint32_t receivedInterval = mReceivedPackets - mReceivedPrior; + Debug( 5, "Received interval = %d", receivedInterval ); + mReceivedPrior = mReceivedPackets; + uint32_t lostInterval = expectedInterval - receivedInterval; + Debug( 5, "Lost interval = %d", lostInterval ); - if ( expectedInterval == 0 || lostInterval <= 0 ) - mLostFraction = 0; - else - mLostFraction = (lostInterval << 8) / expectedInterval; - Debug( 5, "Lost fraction = %d", mLostFraction ); + if ( expectedInterval == 0 || lostInterval <= 0 ) + mLostFraction = 0; + else + mLostFraction = (lostInterval << 8) / expectedInterval; + Debug( 5, "Lost fraction = %d", mLostFraction ); } bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen ) { - const RtpDataHeader *rtpHeader; - rtpHeader = (RtpDataHeader *)packet; - int rtpHeaderSize = 12 + rtpHeader->cc * 4; - // No need to check for nal type as non fragmented packets already have 001 start sequence appended - bool h264FragmentEnd = (mCodecId == AV_CODEC_ID_H264) && (packet[rtpHeaderSize+1] & 0x40); - // M stands for Marker, it is the 8th bit - // The interpretation of the marker is defined by a profile. It is intended - // to allow significant events such as frame boundaries to be marked in the - // packet stream. A profile may define additional marker bits or specify - // that there is no marker bit by changing the number of bits in the payload type field. - bool thisM = rtpHeader->m || h264FragmentEnd; + const RtpDataHeader *rtpHeader; + rtpHeader = (RtpDataHeader *)packet; + int rtpHeaderSize = 12 + rtpHeader->cc * 4; + // No need to check for nal type as non fragmented packets already have 001 start sequence appended + bool h264FragmentEnd = (mCodecId == AV_CODEC_ID_H264) && (packet[rtpHeaderSize+1] & 0x40); + // M stands for Marker, it is the 8th bit + // The interpretation of the marker is defined by a profile. It is intended + // to allow significant events such as frame boundaries to be marked in the + // packet stream. A profile may define additional marker bits or specify + // that there is no marker bit by changing the number of bits in the payload type field. + bool thisM = rtpHeader->m || h264FragmentEnd; - if ( updateSeq( ntohs(rtpHeader->seqN) ) ) + if ( updateSeq( ntohs(rtpHeader->seqN) ) ) + { + Hexdump( 4, packet+rtpHeaderSize, 16 ); + + if ( mFrameGood ) { - Hexdump( 4, packet+rtpHeaderSize, 16 ); + int extraHeader = 0; - if ( mFrameGood ) + if( mCodecId == AV_CODEC_ID_H264 ) + { + int nalType = (packet[rtpHeaderSize] & 0x1f); + Debug( 3, "Have H264 frame: nal type is %d", nalType ); + + switch (nalType) { - int extraHeader = 0; - - if( mCodecId == AV_CODEC_ID_H264 ) + case 24: // STAP-A { - int nalType = (packet[rtpHeaderSize] & 0x1f); - Debug( 3, "Have H264 frame: nal type is %d", nalType ); - - switch (nalType) - { - case 24: // STAP-A - { - extraHeader = 2; - break; - } - case 25: // STAP-B - case 26: // MTAP-16 - case 27: // MTAP-24 - { - extraHeader = 3; - break; - } - // FU-A and FU-B - case 28: case 29: - { - // Is this NAL the first NAL in fragmentation sequence - if ( packet[rtpHeaderSize+1] & 0x80 ) - { - // Now we will form new header of frame - mFrame.append( "\x0\x0\x1\x0", 4 ); - // Reconstruct NAL header from FU headers - *(mFrame+3) = (packet[rtpHeaderSize+1] & 0x1f) | - (packet[rtpHeaderSize] & 0xe0); - } - - extraHeader = 2; - break; - } - default: { - Debug(3, "Unhandled nalType %d", nalType ); - } - } - - // Append NAL frame start code - if ( !mFrame.size() ) - mFrame.append( "\x0\x0\x1", 3 ); + extraHeader = 2; + break; } - mFrame.append( packet+rtpHeaderSize+extraHeader, packetLen-rtpHeaderSize-extraHeader ); - } else { - Debug( 3, "NOT H264 frame: type is %d", mCodecId ); + case 25: // STAP-B + case 26: // MTAP-16 + case 27: // MTAP-24 + { + extraHeader = 3; + break; + } + // FU-A and FU-B + case 28: case 29: + { + // Is this NAL the first NAL in fragmentation sequence + if ( packet[rtpHeaderSize+1] & 0x80 ) + { + // Now we will form new header of frame + mFrame.append( "\x0\x0\x1\x0", 4 ); + // Reconstruct NAL header from FU headers + *(mFrame+3) = (packet[rtpHeaderSize+1] & 0x1f) | + (packet[rtpHeaderSize] & 0xe0); + } + + extraHeader = 2; + break; + } + default: { + Debug(3, "Unhandled nalType %d", nalType ); + } } - Hexdump( 4, mFrame.head(), 16 ); - - if ( thisM ) - { - if ( mFrameGood ) - { - Debug( 2, "Got new frame %d, %d bytes", mFrameCount, mFrame.size() ); - - mFrameProcessed.setValueImmediate( false ); - mFrameReady.updateValueSignal( true ); - if ( !mFrameProcessed.getValueImmediate() ) - { - // What is the point of this for loop? Is it just me, or will it call getUpdatedValue once or twice? Could it not be better written as - // if ( ! mFrameProcessed.getUpdatedValue( 1 ) && mFrameProcessed.getUpdatedValue( 1 ) ) return false; - - for ( int count = 0; !mFrameProcessed.getUpdatedValue( 1 ); count++ ) - if( count > 1 ) - return( false ); - } - mFrameCount++; - } - else - { - Warning( "Discarding incomplete frame %d, %d bytes", mFrameCount, mFrame.size() ); - } - mFrame.clear(); - } - } - else - { - if ( mFrame.size() ) - { - Warning( "Discarding partial frame %d, %d bytes", mFrameCount, mFrame.size() ); - } - else - { - Warning( "Discarding frame %d", mFrameCount ); - } - mFrameGood = false; - mFrame.clear(); + // Append NAL frame start code + if ( !mFrame.size() ) + mFrame.append( "\x0\x0\x1", 3 ); + } + mFrame.append( packet+rtpHeaderSize+extraHeader, packetLen-rtpHeaderSize-extraHeader ); + } else { + Debug( 3, "NOT H264 frame: type is %d", mCodecId ); } + + Hexdump( 4, mFrame.head(), 16 ); + if ( thisM ) { - mFrameGood = true; - prevM = true; + if ( mFrameGood ) + { + Debug( 2, "Got new frame %d, %d bytes", mFrameCount, mFrame.size() ); + + mFrameProcessed.setValueImmediate( false ); + mFrameReady.updateValueSignal( true ); + if ( !mFrameProcessed.getValueImmediate() ) + { + // What is the point of this for loop? Is it just me, or will it call getUpdatedValue once or twice? Could it not be better written as + // if ( ! mFrameProcessed.getUpdatedValue( 1 ) && mFrameProcessed.getUpdatedValue( 1 ) ) return false; + + for ( int count = 0; !mFrameProcessed.getUpdatedValue( 1 ); count++ ) + if( count > 1 ) + return( false ); + } + mFrameCount++; + } + else + { + Warning( "Discarding incomplete frame %d, %d bytes", mFrameCount, mFrame.size() ); + } + mFrame.clear(); + } + } + else + { + if ( mFrame.size() ) + { + Warning( "Discarding partial frame %d, %d bytes", mFrameCount, mFrame.size() ); } else - prevM = false; + { + Warning( "Discarding frame %d", mFrameCount ); + } + mFrameGood = false; + mFrame.clear(); + } + if ( thisM ) + { + mFrameGood = true; + prevM = true; + } + else + prevM = false; - updateJitter( rtpHeader ); + updateJitter( rtpHeader ); - return( true ); + return( true ); } bool RtpSource::getFrame( Buffer &buffer ) { - Debug( 3, "Getting frame" ); - if ( !mFrameReady.getValueImmediate() ) - { - // Allow for a couple of spurious returns - for ( int count = 0; !mFrameReady.getUpdatedValue( 1 ); count++ ) - if ( count > 1 ) - return( false ); - } - buffer = mFrame; - mFrameReady.setValueImmediate( false ); - mFrameProcessed.updateValueSignal( true ); - Debug( 4, "Copied %d bytes", buffer.size() ); - return( true ); + Debug( 3, "Getting frame" ); + if ( !mFrameReady.getValueImmediate() ) + { + // Allow for a couple of spurious returns + for ( int count = 0; !mFrameReady.getUpdatedValue( 1 ); count++ ) + if ( count > 1 ) + return( false ); + } + buffer = mFrame; + mFrameReady.setValueImmediate( false ); + mFrameProcessed.updateValueSignal( true ); + Debug( 4, "Copied %d bytes", buffer.size() ); + return( true ); } #endif // HAVE_LIBAVCODEC