/** {@inheritDoc} */
        @Override
        public RawPacket transform(RawPacket pkt) {
          if (pkt == null) {
            return pkt;
          }

          RTCPCompoundPacket inPacket;
          try {
            inPacket =
                (RTCPCompoundPacket)
                    parser.parse(pkt.getBuffer(), pkt.getOffset(), pkt.getLength());
          } catch (BadFormatException e) {
            logger.warn("Failed to terminate an RTCP packet. " + "Dropping packet.");
            return null;
          }

          // Update our RTCP stats map (timestamps). This operation is
          // read-only.
          remoteClockEstimator.apply(inPacket);

          cnameRegistry.update(inPacket);

          // Remove SRs and RRs from the RTCP packet.
          pkt = feedbackGateway.gateway(inPacket);

          return pkt;
        }
  /**
   * Iterate through all the <tt>ReceiveStream</tt>s that this <tt>MediaStream</tt> has and make
   * <tt>RTCPReportBlock</tt>s for all of them.
   *
   * @param time
   * @return
   */
  private RTCPReportBlock[] makeRTCPReportBlocks(long time) {
    MediaStream stream = getStream();
    // State validation.
    if (stream == null) {
      logger.warn("stream is null.");
      return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
    }

    StreamRTPManager streamRTPManager = stream.getStreamRTPManager();
    if (streamRTPManager == null) {
      logger.warn("streamRTPManager is null.");
      return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
    }

    Collection<ReceiveStream> receiveStreams = streamRTPManager.getReceiveStreams();

    if (receiveStreams == null || receiveStreams.size() == 0) {
      logger.info("There are no receive streams to build report " + "blocks for.");
      return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
    }

    SSRCCache cache = streamRTPManager.getSSRCCache();
    if (cache == null) {
      logger.info("cache is null.");
      return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
    }

    // Create the return object.
    Collection<RTCPReportBlock> rtcpReportBlocks = new ArrayList<RTCPReportBlock>();

    // Populate the return object.
    for (ReceiveStream receiveStream : receiveStreams) {
      // Dig into the guts of FMJ and get the stats for the current
      // receiveStream.
      SSRCInfo info = cache.cache.get((int) receiveStream.getSSRC());

      if (!info.ours && info.sender) {
        RTCPReportBlock rtcpReportBlock = info.makeReceiverReport(time);
        rtcpReportBlocks.add(rtcpReportBlock);
      }
    }

    return rtcpReportBlocks.toArray(new RTCPReportBlock[rtcpReportBlocks.size()]);
  }