protected boolean dropMessage(RTMP rtmp,int channelId,IRTMPEvent message){
  boolean drop=false;
  if (rtmp.getMode() == RTMP.MODE_SERVER) {
    boolean isVideo=false;
    if (message instanceof Ping) {
      final Ping pingMessage=(Ping)message;
      if (pingMessage.getEventType() == Ping.STREAM_PLAYBUFFER_CLEAR) {
        final int channel=(4 + ((pingMessage.getValue2() - 1) * 5));
        rtmp.setLastTimestampMapping(channel,null);
        rtmp.setLastTimestampMapping(channel + 1,null);
        rtmp.setLastTimestampMapping(channel + 2,null);
      }
      return false;
    }
    if ((isVideo=message instanceof VideoData) || message instanceof AudioData) {
      if (message.getTimestamp() == 0) {
        return false;
      }
      boolean isLive=message.getSourceType() == Constants.SOURCE_TYPE_LIVE;
      long timestamp=(message.getTimestamp() & 0xFFFFFFFFL);
      LiveTimestampMapping mapping=rtmp.getLastTimestampMapping(channelId);
      long now=System.currentTimeMillis();
      if (mapping == null || timestamp < mapping.getLastStreamTime()) {
        log.debug("Resetting clock time ({}) to stream time ({})",now,timestamp);
        mapping=new LiveTimestampMapping(now,timestamp);
        rtmp.setLastTimestampMapping(channelId,mapping);
      }
      mapping.setLastStreamTime(timestamp);
      long clockTimeOfMessage=mapping.getClockStartTime() + timestamp - mapping.getStreamStartTime();
      long tardiness=clockTimeOfMessage - now;
      if (isLive && dropLiveFuture) {
        tardiness=Math.abs(tardiness);
      }
      IConnection conn=Red5.getConnectionLocal();
      if (conn != null) {
        tardiness-=conn.getLastPingTime();
      }
 else {
        log.debug("Connection is null");
      }
      if (tardiness < baseTolerance) {
      }
 else       if (tardiness > highestTolerance) {
        log.debug("Dropping late message: {}",message);
        if (isVideo) {
          mapping.setKeyFrameNeeded(true);
        }
        drop=true;
      }
 else {
        if (isVideo) {
          VideoData video=(VideoData)message;
          if (video.getFrameType() == FrameType.KEYFRAME) {
            mapping.setKeyFrameNeeded(false);
          }
 else           if (tardiness >= baseTolerance && tardiness < midTolerance) {
            if (video.getFrameType() == FrameType.DISPOSABLE_INTERFRAME) {
              log.debug("Dropping disposible frame; message: {}",message);
              drop=true;
            }
          }
 else           if (tardiness >= midTolerance && tardiness <= highestTolerance) {
            log.debug("Dropping disposible or inter frame; message: {}",message);
            drop=true;
          }
        }
      }
    }
    log.debug("Drop data: {}",drop);
  }
  return drop;
}

protected boolean dropMessage ( RTMP rtmp , int channelId , IRTMPEvent message ) { boolean drop = false ; if ( rtmp . getMode ( ) == RTMP . MODE_SERVER ) { boolean isVideo = false ; if ( message instanceof Ping ) { final Ping pingMessage = ( Ping ) message ; if ( pingMessage . getEventType ( ) == Ping . STREAM_PLAYBUFFER_CLEAR ) { final int channel = ( 4 + ( ( pingMessage . getValue2 ( ) - 1 ) * 5 ) ) ; rtmp . setLastTimestampMapping ( channel , null ) ; rtmp . setLastTimestampMapping ( channel + 1 , null ) ; rtmp . setLastTimestampMapping ( channel + 2 , null ) ; } return false ; } if ( ( isVideo = message instanceof VideoData ) || message instanceof AudioData ) { if ( message . getTimestamp ( ) == 0 ) { return false ; } boolean isLive = message . getSourceType ( ) == Constants . SOURCE_TYPE_LIVE ; long timestamp = ( message . getTimestamp ( ) & 0xFFFFFFFFL ) ; LiveTimestampMapping mapping = rtmp . getLastTimestampMapping ( channelId ) ; long now = System . currentTimeMillis ( ) ; if ( mapping == null || timestamp < mapping . getLastStreamTime ( ) ) { log . debug ( "Resetting clock time ({}) to stream time ({})" , now , timestamp ) ; mapping = new LiveTimestampMapping ( now , timestamp ) ; rtmp . setLastTimestampMapping ( channelId , mapping ) ; } mapping . setLastStreamTime ( timestamp ) ; long clockTimeOfMessage = mapping . getClockStartTime ( ) + timestamp - mapping . getStreamStartTime ( ) ; long tardiness = clockTimeOfMessage - now ; if ( isLive && dropLiveFuture ) { tardiness = Math . abs ( tardiness ) ; } IConnection conn = Red5 . getConnectionLocal ( ) ; if ( conn != null ) { tardiness -= conn . getLastPingTime ( ) ; } else { log . debug ( "Connection is null" ) ; } if ( tardiness < baseTolerance ) { } else if ( tardiness > highestTolerance ) { log . debug ( "Dropping late message: {}" , message ) ; if ( isVideo ) { mapping . setKeyFrameNeeded ( true ) ; } drop = true ; } else { if ( isVideo ) { VideoData video = ( VideoData ) message ; if ( video . getFrameType ( ) == FrameType . KEYFRAME ) { mapping . setKeyFrameNeeded ( false ) ; } else if ( tardiness >= baseTolerance && tardiness < midTolerance ) { if ( video . getFrameType ( ) == FrameType . DISPOSABLE_INTERFRAME ) { log . debug ( "Dropping disposible frame; message: {}" , message ) ; drop = true ; } } else if ( tardiness >= midTolerance && tardiness <= highestTolerance ) { log . debug ( "Dropping disposible or inter frame; message: {}" , message ) ; drop = true ; } } } } log . debug ( "Drop data: {}" , drop ) ; } return drop ; }
determine if this message should be dropped for lateness . live publish data does not come through this section , only outgoing data does . - determine latency between server and client using ping - ping timestamp is unsigned int ( 4 bytes ) and is set from value on sender 1st drop disposable frames - lowest mark 2nd drop interframes - middle 3rd drop key frames - high mark
