예제 #1
0
  /**
   * Gets the first RED block in the RED payload.
   *
   * @param buffer the byte buffer that contains the RED payload.
   * @param offset the offset in the buffer where the RED payload begins.
   * @param length the length of the RED payload.
   * @return the primary RED block if it exists, null otherwise.
   */
  public static REDBlock getPrimaryBlock(byte[] buffer, int offset, int length) {
    // Chrome is typically sending RED packets with a single block carrying
    // either VP8 or FEC. This is unusual, and probably wrong as it messes
    // up the sequence numbers and packet loss computations but it's just
    // the way it is. Here we detect this situation and avoid looping
    // through the blocks if there is a single block.
    if (isMultiBlock(buffer, offset, length)) {
      REDBlock block = null;
      REDBlockIterator redBlockIterator = new REDBlockIterator(buffer, offset, length);
      while (redBlockIterator.hasNext()) {
        block = redBlockIterator.next();
      }

      if (block == null) {
        logger.warn("No primary block found.");
      }

      return block;
    } else {
      if (buffer == null || offset < 0 || length < 0 || buffer.length < offset + length) {
        logger.warn(
            "Prevented an array out of bounds exception: "
                + "buffer length: "
                + buffer.length
                + ", offset: "
                + offset
                + ", len: "
                + length);
        return null;
      }

      byte blockPT = (byte) (buffer[offset] & 0x7f);
      int blockOff = offset + 1; // + 1 for the primary block header.
      int blockLen = length - blockOff;

      if (buffer.length < blockOff + blockLen) {
        logger.warn("Primary block doesn't fit in RED packet.");
        return null;
      }

      return new REDBlock(buffer, blockOff, blockLen, blockPT);
    }
  }
예제 #2
0
  /**
   * Matches a RED block in the RED payload.
   *
   * @param predicate the predicate that is used to match the RED block.
   * @param buffer the byte buffer that contains the RED payload.
   * @param offset the offset in the buffer where the RED payload begins.
   * @param length the length of the RED payload.
   * @return the first RED block that matches the given predicate, null otherwise.
   */
  public static REDBlock matchFirst(
      Predicate<REDBlock> predicate, byte[] buffer, int offset, int length) {
    if (isMultiBlock(buffer, offset, length)) {
      REDBlockIterator it = new REDBlockIterator(buffer, offset, length);
      while (it.hasNext()) {
        REDBlock b = it.next();
        if (b != null && predicate.test(b)) {
          return b;
        }
      }

      return null;
    } else {
      REDBlock b = getPrimaryBlock(buffer, offset, length);
      if (b != null && predicate.test(b)) {
        return b;
      } else {
        return null;
      }
    }
  }