Java Code Examples for com.google.android.exoplayer2.util.Util#ceilDivide()

The following examples show how to use com.google.android.exoplayer2.util.Util#ceilDivide() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DefaultTrackSelector.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Given viewport dimensions and video dimensions, computes the maximum size of the video as it
 * will be rendered to fit inside of the viewport.
 */
private static Point getMaxVideoSizeInViewport(boolean orientationMayChange, int viewportWidth,
    int viewportHeight, int videoWidth, int videoHeight) {
  if (orientationMayChange && (videoWidth > videoHeight) != (viewportWidth > viewportHeight)) {
    // Rotation is allowed, and the video will be larger in the rotated viewport.
    int tempViewportWidth = viewportWidth;
    viewportWidth = viewportHeight;
    viewportHeight = tempViewportWidth;
  }

  if (videoWidth * viewportHeight >= videoHeight * viewportWidth) {
    // Horizontal letter-boxing along top and bottom.
    return new Point(viewportWidth, Util.ceilDivide(viewportWidth * videoHeight, videoWidth));
  } else {
    // Vertical letter-boxing along edges.
    return new Point(Util.ceilDivide(viewportHeight * videoWidth, videoHeight), viewportHeight);
  }
}
 
Example 2
Source File: DashManifestParser.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Adds timeline elements for one S tag to the segment timeline.
 *
 * @param startTime Start time of the first timeline element.
 * @param elementDuration Duration of one timeline element.
 * @param elementRepeatCount Number of timeline elements minus one. May be negative to indicate
 *     that the count is determined by the total duration and the element duration.
 * @param endTime End time of the last timeline element for this S tag, or {@link C#TIME_UNSET} if
 *     unknown. Only needed if {@code repeatCount} is negative.
 * @return Calculated next start time.
 */
private long addSegmentTimelineElementsToList(
    List<SegmentTimelineElement> segmentTimeline,
    long startTime,
    long elementDuration,
    int elementRepeatCount,
    long endTime) {
  int count =
      elementRepeatCount >= 0
          ? 1 + elementRepeatCount
          : (int) Util.ceilDivide(endTime - startTime, elementDuration);
  for (int i = 0; i < count; i++) {
    segmentTimeline.add(buildSegmentTimelineElement(startTime, elementDuration));
    startTime += elementDuration;
  }
  return startTime;
}
 
Example 3
Source File: MediaCodecInfo.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Returns the smallest video size greater than or equal to a specified size that also satisfies
 * the {@link MediaCodec}'s width and height alignment requirements.
 * <p>
 * Must not be called if the device SDK version is less than 21.
 *
 * @param width Width in pixels.
 * @param height Height in pixels.
 * @return The smallest video size greater than or equal to the specified size that also satisfies
 *     the {@link MediaCodec}'s width and height alignment requirements, or null if not a video
 *     codec.
 */
@TargetApi(21)
public Point alignVideoSizeV21(int width, int height) {
  if (capabilities == null) {
    logNoSupport("align.caps");
    return null;
  }
  VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities();
  if (videoCapabilities == null) {
    logNoSupport("align.vCaps");
    return null;
  }
  int widthAlignment = videoCapabilities.getWidthAlignment();
  int heightAlignment = videoCapabilities.getHeightAlignment();
  return new Point(Util.ceilDivide(width, widthAlignment) * widthAlignment,
      Util.ceilDivide(height, heightAlignment) * heightAlignment);
}
 
Example 4
Source File: DefaultTrackSelector.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Given viewport dimensions and video dimensions, computes the maximum size of the video as it
 * will be rendered to fit inside of the viewport.
 */
private static Point getMaxVideoSizeInViewport(boolean orientationMayChange, int viewportWidth,
    int viewportHeight, int videoWidth, int videoHeight) {
  if (orientationMayChange && (videoWidth > videoHeight) != (viewportWidth > viewportHeight)) {
    // Rotation is allowed, and the video will be larger in the rotated viewport.
    int tempViewportWidth = viewportWidth;
    viewportWidth = viewportHeight;
    viewportHeight = tempViewportWidth;
  }

  if (videoWidth * viewportHeight >= videoHeight * viewportWidth) {
    // Horizontal letter-boxing along top and bottom.
    return new Point(viewportWidth, Util.ceilDivide(viewportWidth * videoHeight, videoWidth));
  } else {
    // Vertical letter-boxing along edges.
    return new Point(Util.ceilDivide(viewportHeight * videoWidth, videoHeight), viewportHeight);
  }
}
 
Example 5
Source File: DefaultTrackSelector.java    From K-Sonic with MIT License 6 votes vote down vote up
/**
 * Given viewport dimensions and video dimensions, computes the maximum size of the video as it
 * will be rendered to fit inside of the viewport.
 */
private static Point getMaxVideoSizeInViewport(boolean orientationMayChange, int viewportWidth,
    int viewportHeight, int videoWidth, int videoHeight) {
  if (orientationMayChange && (videoWidth > videoHeight) != (viewportWidth > viewportHeight)) {
    // Rotation is allowed, and the video will be larger in the rotated viewport.
    int tempViewportWidth = viewportWidth;
    viewportWidth = viewportHeight;
    viewportHeight = tempViewportWidth;
  }

  if (videoWidth * viewportHeight >= videoHeight * viewportWidth) {
    // Horizontal letter-boxing along top and bottom.
    return new Point(viewportWidth, Util.ceilDivide(viewportWidth * videoHeight, videoWidth));
  } else {
    // Vertical letter-boxing along edges.
    return new Point(Util.ceilDivide(viewportHeight * videoWidth, videoHeight), viewportHeight);
  }
}
 
Example 6
Source File: SegmentBase.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public int getSegmentCount(long periodDurationUs) {
  if (segmentTimeline != null) {
    return segmentTimeline.size();
  } else if (periodDurationUs != C.TIME_UNSET) {
    long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
    return (int) Util.ceilDivide(periodDurationUs, durationUs);
  } else {
    return DashSegmentIndex.INDEX_UNBOUNDED;
  }
}
 
Example 7
Source File: SegmentBase.java    From K-Sonic with MIT License 5 votes vote down vote up
@Override
public int getSegmentCount(long periodDurationUs) {
  if (segmentTimeline != null) {
    return segmentTimeline.size();
  } else if (periodDurationUs != C.TIME_UNSET) {
    long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
    return (int) Util.ceilDivide(periodDurationUs, durationUs);
  } else {
    return DashSegmentIndex.INDEX_UNBOUNDED;
  }
}
 
Example 8
Source File: SegmentBase.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
@Override
public int getSegmentCount(long periodDurationUs) {
  if (segmentTimeline != null) {
    return segmentTimeline.size();
  } else if (endNumber != C.INDEX_UNSET) {
    return (int) (endNumber - startNumber + 1);
  } else if (periodDurationUs != C.TIME_UNSET) {
    long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
    return (int) Util.ceilDivide(periodDurationUs, durationUs);
  } else {
    return DashSegmentIndex.INDEX_UNBOUNDED;
  }
}
 
Example 9
Source File: MediaCodecVideoRenderer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns a maximum video size to use when configuring a codec for {@code format} in a way that
 * will allow possible adaptation to other compatible formats that are expected to have the same
 * aspect ratio, but whose sizes are unknown.
 *
 * @param codecInfo Information about the {@link MediaCodec} being configured.
 * @param format The format for which the codec is being configured.
 * @return The maximum video size to use, or null if the size of {@code format} should be used.
 */
private static Point getCodecMaxSize(MediaCodecInfo codecInfo, Format format) {
  boolean isVerticalVideo = format.height > format.width;
  int formatLongEdgePx = isVerticalVideo ? format.height : format.width;
  int formatShortEdgePx = isVerticalVideo ? format.width : format.height;
  float aspectRatio = (float) formatShortEdgePx / formatLongEdgePx;
  for (int longEdgePx : STANDARD_LONG_EDGE_VIDEO_PX) {
    int shortEdgePx = (int) (longEdgePx * aspectRatio);
    if (longEdgePx <= formatLongEdgePx || shortEdgePx <= formatShortEdgePx) {
      // Don't return a size not larger than the format for which the codec is being configured.
      return null;
    } else if (Util.SDK_INT >= 21) {
      Point alignedSize = codecInfo.alignVideoSizeV21(isVerticalVideo ? shortEdgePx : longEdgePx,
          isVerticalVideo ? longEdgePx : shortEdgePx);
      float frameRate = format.frameRate;
      if (codecInfo.isVideoSizeAndRateSupportedV21(alignedSize.x, alignedSize.y, frameRate)) {
        return alignedSize;
      }
    } else {
      try {
        // Conservatively assume the codec requires 16px width and height alignment.
        longEdgePx = Util.ceilDivide(longEdgePx, 16) * 16;
        shortEdgePx = Util.ceilDivide(shortEdgePx, 16) * 16;
        if (longEdgePx * shortEdgePx <= MediaCodecUtil.maxH264DecodableFrameSize()) {
          return new Point(
              isVerticalVideo ? shortEdgePx : longEdgePx,
              isVerticalVideo ? longEdgePx : shortEdgePx);
        }
      } catch (DecoderQueryException e) {
        // We tried our best. Give up!
        return null;
      }
    }
  }
  return null;
}
 
Example 10
Source File: MediaCodecVideoRenderer.java    From K-Sonic with MIT License 5 votes vote down vote up
/**
 * Returns a maximum video size to use when configuring a codec for {@code format} in a way
 * that will allow possible adaptation to other compatible formats that are expected to have the
 * same aspect ratio, but whose sizes are unknown.
 *
 * @param codecInfo Information about the {@link MediaCodec} being configured.
 * @param format The format for which the codec is being configured.
 * @return The maximum video size to use, or null if the size of {@code format} should be used.
 * @throws DecoderQueryException If an error occurs querying {@code codecInfo}.
 */
private static Point getCodecMaxSize(MediaCodecInfo codecInfo, Format format)
    throws DecoderQueryException {
  boolean isVerticalVideo = format.height > format.width;
  int formatLongEdgePx = isVerticalVideo ? format.height : format.width;
  int formatShortEdgePx = isVerticalVideo ? format.width : format.height;
  float aspectRatio = (float) formatShortEdgePx / formatLongEdgePx;
  for (int longEdgePx : STANDARD_LONG_EDGE_VIDEO_PX) {
    int shortEdgePx = (int) (longEdgePx * aspectRatio);
    if (longEdgePx <= formatLongEdgePx || shortEdgePx <= formatShortEdgePx) {
      // Don't return a size not larger than the format for which the codec is being configured.
      return null;
    } else if (Util.SDK_INT >= 21) {
      Point alignedSize = codecInfo.alignVideoSizeV21(isVerticalVideo ? shortEdgePx : longEdgePx,
          isVerticalVideo ? longEdgePx : shortEdgePx);
      float frameRate = format.frameRate;
      if (codecInfo.isVideoSizeAndRateSupportedV21(alignedSize.x, alignedSize.y, frameRate)) {
        return alignedSize;
      }
    } else {
      // Conservatively assume the codec requires 16px width and height alignment.
      longEdgePx = Util.ceilDivide(longEdgePx, 16) * 16;
      shortEdgePx = Util.ceilDivide(shortEdgePx, 16) * 16;
      if (longEdgePx * shortEdgePx <= MediaCodecUtil.maxH264DecodableFrameSize()) {
        return new Point(isVerticalVideo ? shortEdgePx : longEdgePx,
            isVerticalVideo ? longEdgePx : shortEdgePx);
      }
    }
  }
  return null;
}
 
Example 11
Source File: MediaCodecVideoRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns a maximum video size to use when configuring a codec for {@code format} in a way
 * that will allow possible adaptation to other compatible formats that are expected to have the
 * same aspect ratio, but whose sizes are unknown.
 *
 * @param codecInfo Information about the {@link MediaCodec} being configured.
 * @param format The format for which the codec is being configured.
 * @return The maximum video size to use, or null if the size of {@code format} should be used.
 * @throws DecoderQueryException If an error occurs querying {@code codecInfo}.
 */
private static Point getCodecMaxSize(MediaCodecInfo codecInfo, Format format)
    throws DecoderQueryException {
  boolean isVerticalVideo = format.height > format.width;
  int formatLongEdgePx = isVerticalVideo ? format.height : format.width;
  int formatShortEdgePx = isVerticalVideo ? format.width : format.height;
  float aspectRatio = (float) formatShortEdgePx / formatLongEdgePx;
  for (int longEdgePx : STANDARD_LONG_EDGE_VIDEO_PX) {
    int shortEdgePx = (int) (longEdgePx * aspectRatio);
    if (longEdgePx <= formatLongEdgePx || shortEdgePx <= formatShortEdgePx) {
      // Don't return a size not larger than the format for which the codec is being configured.
      return null;
    } else if (Util.SDK_INT >= 21) {
      Point alignedSize = codecInfo.alignVideoSizeV21(isVerticalVideo ? shortEdgePx : longEdgePx,
          isVerticalVideo ? longEdgePx : shortEdgePx);
      float frameRate = format.frameRate;
      if (codecInfo.isVideoSizeAndRateSupportedV21(alignedSize.x, alignedSize.y, frameRate)) {
        return alignedSize;
      }
    } else {
      // Conservatively assume the codec requires 16px width and height alignment.
      longEdgePx = Util.ceilDivide(longEdgePx, 16) * 16;
      shortEdgePx = Util.ceilDivide(shortEdgePx, 16) * 16;
      if (longEdgePx * shortEdgePx <= MediaCodecUtil.maxH264DecodableFrameSize()) {
        return new Point(isVerticalVideo ? shortEdgePx : longEdgePx,
            isVerticalVideo ? longEdgePx : shortEdgePx);
      }
    }
  }
  return null;
}
 
Example 12
Source File: MediaCodecInfo.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@TargetApi(21)
private static Point alignVideoSizeV21(VideoCapabilities capabilities, int width, int height) {
  int widthAlignment = capabilities.getWidthAlignment();
  int heightAlignment = capabilities.getHeightAlignment();
  return new Point(
      Util.ceilDivide(width, widthAlignment) * widthAlignment,
      Util.ceilDivide(height, heightAlignment) * heightAlignment);
}
 
Example 13
Source File: SegmentBase.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public int getSegmentCount(long periodDurationUs) {
  if (segmentTimeline != null) {
    return segmentTimeline.size();
  } else if (endNumber != C.INDEX_UNSET) {
    return (int) (endNumber - startNumber + 1);
  } else if (periodDurationUs != C.TIME_UNSET) {
    long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
    return (int) Util.ceilDivide(periodDurationUs, durationUs);
  } else {
    return DashSegmentIndex.INDEX_UNBOUNDED;
  }
}
 
Example 14
Source File: DefaultAllocator.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
@Override
public synchronized void trim() {
  int targetAllocationCount = Util.ceilDivide(targetBufferSize, individualAllocationSize);
  int targetAvailableCount = Math.max(0, targetAllocationCount - allocatedCount);
  if (targetAvailableCount >= availableCount) {
    // We're already at or below the target.
    return;
  }

  if (initialAllocationBlock != null) {
    // Some allocations are backed by an initial block. We need to make sure that we hold onto all
    // such allocations. Re-order the available allocations so that the ones backed by the initial
    // block come first.
    int lowIndex = 0;
    int highIndex = availableCount - 1;
    while (lowIndex <= highIndex) {
      Allocation lowAllocation = availableAllocations[lowIndex];
      if (lowAllocation.data == initialAllocationBlock) {
        lowIndex++;
      } else {
        Allocation highAllocation = availableAllocations[highIndex];
        if (highAllocation.data != initialAllocationBlock) {
          highIndex--;
        } else {
          availableAllocations[lowIndex++] = highAllocation;
          availableAllocations[highIndex--] = lowAllocation;
        }
      }
    }
    // lowIndex is the index of the first allocation not backed by an initial block.
    targetAvailableCount = Math.max(targetAvailableCount, lowIndex);
    if (targetAvailableCount >= availableCount) {
      // We're already at or below the target.
      return;
    }
  }

  // Discard allocations beyond the target.
  Arrays.fill(availableAllocations, targetAvailableCount, availableCount, null);
  availableCount = targetAvailableCount;
}
 
Example 15
Source File: MediaCodecVideoRenderer.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Returns a maximum input size for a given codec, MIME type, width and height.
 *
 * @param codecInfo Information about the {@link MediaCodec} being configured.
 * @param sampleMimeType The format mime type.
 * @param width The width in pixels.
 * @param height The height in pixels.
 * @return A maximum input size in bytes, or {@link Format#NO_VALUE} if a maximum could not be
 *     determined.
 */
private static int getCodecMaxInputSize(
    MediaCodecInfo codecInfo, String sampleMimeType, int width, int height) {
  if (width == Format.NO_VALUE || height == Format.NO_VALUE) {
    // We can't infer a maximum input size without video dimensions.
    return Format.NO_VALUE;
  }

  // Attempt to infer a maximum input size from the format.
  int maxPixels;
  int minCompressionRatio;
  switch (sampleMimeType) {
    case MimeTypes.VIDEO_H263:
    case MimeTypes.VIDEO_MP4V:
      maxPixels = width * height;
      minCompressionRatio = 2;
      break;
    case MimeTypes.VIDEO_H264:
      if ("BRAVIA 4K 2015".equals(Util.MODEL) // Sony Bravia 4K
          || ("Amazon".equals(Util.MANUFACTURER)
              && ("KFSOWI".equals(Util.MODEL) // Kindle Soho
                  || ("AFTS".equals(Util.MODEL) && codecInfo.secure)))) { // Fire TV Gen 2
        // Use the default value for cases where platform limitations may prevent buffers of the
        // calculated maximum input size from being allocated.
        return Format.NO_VALUE;
      }
      // Round up width/height to an integer number of macroblocks.
      maxPixels = Util.ceilDivide(width, 16) * Util.ceilDivide(height, 16) * 16 * 16;
      minCompressionRatio = 2;
      break;
    case MimeTypes.VIDEO_VP8:
      // VPX does not specify a ratio so use the values from the platform's SoftVPX.cpp.
      maxPixels = width * height;
      minCompressionRatio = 2;
      break;
    case MimeTypes.VIDEO_H265:
    case MimeTypes.VIDEO_VP9:
      maxPixels = width * height;
      minCompressionRatio = 4;
      break;
    default:
      // Leave the default max input size.
      return Format.NO_VALUE;
  }
  // Estimate the maximum input size assuming three channel 4:2:0 subsampled input frames.
  return (maxPixels * 3) / (2 * minCompressionRatio);
}
 
Example 16
Source File: FixedSampleSizeRechunker.java    From K-Sonic with MIT License 4 votes vote down vote up
/**
 * Rechunk the given fixed sample size input to produce a new sequence of samples.
 *
 * @param fixedSampleSize Size in bytes of each sample.
 * @param chunkOffsets Chunk offsets in the MP4 stream to rechunk.
 * @param chunkSampleCounts Sample counts for each of the MP4 stream's chunks.
 * @param timestampDeltaInTimeUnits Timestamp delta between each sample in time units.
 */
public static Results rechunk(int fixedSampleSize, long[] chunkOffsets, int[] chunkSampleCounts,
    long timestampDeltaInTimeUnits) {
  int maxSampleCount = MAX_SAMPLE_SIZE / fixedSampleSize;

  // Count the number of new, rechunked buffers.
  int rechunkedSampleCount = 0;
  for (int chunkSampleCount : chunkSampleCounts) {
    rechunkedSampleCount += Util.ceilDivide(chunkSampleCount, maxSampleCount);
  }

  long[] offsets = new long[rechunkedSampleCount];
  int[] sizes = new int[rechunkedSampleCount];
  int maximumSize = 0;
  long[] timestamps = new long[rechunkedSampleCount];
  int[] flags = new int[rechunkedSampleCount];

  int originalSampleIndex = 0;
  int newSampleIndex = 0;
  for (int chunkIndex = 0; chunkIndex < chunkSampleCounts.length; chunkIndex++) {
    int chunkSamplesRemaining = chunkSampleCounts[chunkIndex];
    long sampleOffset = chunkOffsets[chunkIndex];

    while (chunkSamplesRemaining > 0) {
      int bufferSampleCount = Math.min(maxSampleCount, chunkSamplesRemaining);

      offsets[newSampleIndex] = sampleOffset;
      sizes[newSampleIndex] = fixedSampleSize * bufferSampleCount;
      maximumSize = Math.max(maximumSize, sizes[newSampleIndex]);
      timestamps[newSampleIndex] = (timestampDeltaInTimeUnits * originalSampleIndex);
      flags[newSampleIndex] = C.BUFFER_FLAG_KEY_FRAME;

      sampleOffset += sizes[newSampleIndex];
      originalSampleIndex += bufferSampleCount;

      chunkSamplesRemaining -= bufferSampleCount;
      newSampleIndex++;
    }
  }

  return new Results(offsets, sizes, maximumSize, timestamps, flags);
}
 
Example 17
Source File: DefaultAllocator.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
@Override
public synchronized void trim() {
  int targetAllocationCount = Util.ceilDivide(targetBufferSize, individualAllocationSize);
  int targetAvailableCount = Math.max(0, targetAllocationCount - allocatedCount);
  if (targetAvailableCount >= availableCount) {
    // We're already at or below the target.
    return;
  }

  if (initialAllocationBlock != null) {
    // Some allocations are backed by an initial block. We need to make sure that we hold onto all
    // such allocations. Re-order the available allocations so that the ones backed by the initial
    // block come first.
    int lowIndex = 0;
    int highIndex = availableCount - 1;
    while (lowIndex <= highIndex) {
      Allocation lowAllocation = availableAllocations[lowIndex];
      if (lowAllocation.data == initialAllocationBlock) {
        lowIndex++;
      } else {
        Allocation highAllocation = availableAllocations[highIndex];
        if (highAllocation.data != initialAllocationBlock) {
          highIndex--;
        } else {
          availableAllocations[lowIndex++] = highAllocation;
          availableAllocations[highIndex--] = lowAllocation;
        }
      }
    }
    // lowIndex is the index of the first allocation not backed by an initial block.
    targetAvailableCount = Math.max(targetAvailableCount, lowIndex);
    if (targetAvailableCount >= availableCount) {
      // We're already at or below the target.
      return;
    }
  }

  // Discard allocations beyond the target.
  Arrays.fill(availableAllocations, targetAvailableCount, availableCount, null);
  availableCount = targetAvailableCount;
}
 
Example 18
Source File: FixedSampleSizeRechunker.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Rechunk the given fixed sample size input to produce a new sequence of samples.
 *
 * @param fixedSampleSize Size in bytes of each sample.
 * @param chunkOffsets Chunk offsets in the MP4 stream to rechunk.
 * @param chunkSampleCounts Sample counts for each of the MP4 stream's chunks.
 * @param timestampDeltaInTimeUnits Timestamp delta between each sample in time units.
 */
public static Results rechunk(int fixedSampleSize, long[] chunkOffsets, int[] chunkSampleCounts,
    long timestampDeltaInTimeUnits) {
  int maxSampleCount = MAX_SAMPLE_SIZE / fixedSampleSize;

  // Count the number of new, rechunked buffers.
  int rechunkedSampleCount = 0;
  for (int chunkSampleCount : chunkSampleCounts) {
    rechunkedSampleCount += Util.ceilDivide(chunkSampleCount, maxSampleCount);
  }

  long[] offsets = new long[rechunkedSampleCount];
  int[] sizes = new int[rechunkedSampleCount];
  int maximumSize = 0;
  long[] timestamps = new long[rechunkedSampleCount];
  int[] flags = new int[rechunkedSampleCount];

  int originalSampleIndex = 0;
  int newSampleIndex = 0;
  for (int chunkIndex = 0; chunkIndex < chunkSampleCounts.length; chunkIndex++) {
    int chunkSamplesRemaining = chunkSampleCounts[chunkIndex];
    long sampleOffset = chunkOffsets[chunkIndex];

    while (chunkSamplesRemaining > 0) {
      int bufferSampleCount = Math.min(maxSampleCount, chunkSamplesRemaining);

      offsets[newSampleIndex] = sampleOffset;
      sizes[newSampleIndex] = fixedSampleSize * bufferSampleCount;
      maximumSize = Math.max(maximumSize, sizes[newSampleIndex]);
      timestamps[newSampleIndex] = (timestampDeltaInTimeUnits * originalSampleIndex);
      flags[newSampleIndex] = C.BUFFER_FLAG_KEY_FRAME;

      sampleOffset += sizes[newSampleIndex];
      originalSampleIndex += bufferSampleCount;

      chunkSamplesRemaining -= bufferSampleCount;
      newSampleIndex++;
    }
  }
  long duration = timestampDeltaInTimeUnits * originalSampleIndex;

  return new Results(offsets, sizes, maximumSize, timestamps, flags, duration);
}
 
Example 19
Source File: MediaCodecVideoRenderer.java    From K-Sonic with MIT License 4 votes vote down vote up
/**
 * Returns a maximum input size for a given mime type, width and height.
 *
 * @param sampleMimeType The format mime type.
 * @param width The width in pixels.
 * @param height The height in pixels.
 * @return A maximum input size in bytes, or {@link Format#NO_VALUE} if a maximum could not be
 *     determined.
 */
private static int getMaxInputSize(String sampleMimeType, int width, int height) {
  if (width == Format.NO_VALUE || height == Format.NO_VALUE) {
    // We can't infer a maximum input size without video dimensions.
    return Format.NO_VALUE;
  }

  // Attempt to infer a maximum input size from the format.
  int maxPixels;
  int minCompressionRatio;
  switch (sampleMimeType) {
    case MimeTypes.VIDEO_H263:
    case MimeTypes.VIDEO_MP4V:
      maxPixels = width * height;
      minCompressionRatio = 2;
      break;
    case MimeTypes.VIDEO_H264:
      if ("BRAVIA 4K 2015".equals(Util.MODEL)) {
        // The Sony BRAVIA 4k TV has input buffers that are too small for the calculated 4k video
        // maximum input size, so use the default value.
        return Format.NO_VALUE;
      }
      // Round up width/height to an integer number of macroblocks.
      maxPixels = Util.ceilDivide(width, 16) * Util.ceilDivide(height, 16) * 16 * 16;
      minCompressionRatio = 2;
      break;
    case MimeTypes.VIDEO_VP8:
      // VPX does not specify a ratio so use the values from the platform's SoftVPX.cpp.
      maxPixels = width * height;
      minCompressionRatio = 2;
      break;
    case MimeTypes.VIDEO_H265:
    case MimeTypes.VIDEO_VP9:
      maxPixels = width * height;
      minCompressionRatio = 4;
      break;
    default:
      // Leave the default max input size.
      return Format.NO_VALUE;
  }
  // Estimate the maximum input size assuming three channel 4:2:0 subsampled input frames.
  return (maxPixels * 3) / (2 * minCompressionRatio);
}
 
Example 20
Source File: DefaultAllocator.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
@Override
public synchronized void trim() {
  int targetAllocationCount = Util.ceilDivide(targetBufferSize, individualAllocationSize);
  int targetAvailableCount = Math.max(0, targetAllocationCount - allocatedCount);
  if (targetAvailableCount >= availableCount) {
    // We're already at or below the target.
    return;
  }

  if (initialAllocationBlock != null) {
    // Some allocations are backed by an initial block. We need to make sure that we hold onto all
    // such allocations. Re-order the available allocations so that the ones backed by the initial
    // block come first.
    int lowIndex = 0;
    int highIndex = availableCount - 1;
    while (lowIndex <= highIndex) {
      Allocation lowAllocation = availableAllocations[lowIndex];
      if (lowAllocation.data == initialAllocationBlock) {
        lowIndex++;
      } else {
        Allocation highAllocation = availableAllocations[highIndex];
        if (highAllocation.data != initialAllocationBlock) {
          highIndex--;
        } else {
          availableAllocations[lowIndex++] = highAllocation;
          availableAllocations[highIndex--] = lowAllocation;
        }
      }
    }
    // lowIndex is the index of the first allocation not backed by an initial block.
    targetAvailableCount = Math.max(targetAvailableCount, lowIndex);
    if (targetAvailableCount >= availableCount) {
      // We're already at or below the target.
      return;
    }
  }

  // Discard allocations beyond the target.
  Arrays.fill(availableAllocations, targetAvailableCount, availableCount, null);
  availableCount = targetAvailableCount;
}