use of org.checkerframework.checker.nullness.qual.RequiresNonNull in project ExoPlayer by google.
the class SefSlowMotionFlattener method dropOrTransformSample.
/**
* Applies slow motion flattening by either indicating that the buffer's data should be dropped or
* transforming it in place.
*
* @return Whether the buffer should be dropped.
*/
@RequiresNonNull("#1.data")
public boolean dropOrTransformSample(DecoderInputBuffer buffer) {
if (slowMotionData == null) {
// The input is not an SEF slow motion video.
return false;
}
ByteBuffer data = buffer.data;
int originalPosition = data.position();
data.position(originalPosition + NAL_START_CODE_LENGTH);
// Read nal_unit_header_svc_extension.
data.get(scratch, 0, 4);
int nalUnitType = scratch[0] & 0x1F;
boolean svcExtensionFlag = ((scratch[1] & 0xFF) >> 7) == 1;
checkState(nalUnitType == NAL_UNIT_TYPE_PREFIX && svcExtensionFlag, "Missing SVC extension prefix NAL unit.");
int layer = (scratch[3] & 0xFF) >> 5;
boolean shouldKeepFrame = processCurrentFrame(layer, buffer.timeUs);
// Update the timestamp regardless of whether the buffer is dropped as the timestamp may be
// reused for the empty end-of-stream buffer.
buffer.timeUs = getCurrentFrameOutputTimeUs(/* inputTimeUs= */
buffer.timeUs);
if (shouldKeepFrame) {
data.position(originalPosition);
return false;
}
return true;
}
use of org.checkerframework.checker.nullness.qual.RequiresNonNull in project ExoPlayer by google.
the class TransformerBaseRenderer method feedMuxerFromPipeline.
/**
* Attempts to write sample pipeline output data to the muxer.
*
* @return Whether it may be possible to write more data immediately by calling this method again.
* @throws Muxer.MuxerException If a muxing problem occurs.
* @throws TransformationException If a {@link SamplePipeline} problem occurs.
*/
@RequiresNonNull("samplePipeline")
private boolean feedMuxerFromPipeline() throws Muxer.MuxerException, TransformationException {
if (!muxerWrapperTrackAdded) {
@Nullable Format samplePipelineOutputFormat = samplePipeline.getOutputFormat();
if (samplePipelineOutputFormat == null) {
return false;
}
muxerWrapperTrackAdded = true;
muxerWrapper.addTrackFormat(samplePipelineOutputFormat);
}
if (samplePipeline.isEnded()) {
muxerWrapper.endTrack(getTrackType());
muxerWrapperTrackEnded = true;
return false;
}
@Nullable DecoderInputBuffer samplePipelineOutputBuffer = samplePipeline.getOutputBuffer();
if (samplePipelineOutputBuffer == null) {
return false;
}
if (!muxerWrapper.writeSample(getTrackType(), checkStateNotNull(samplePipelineOutputBuffer.data), samplePipelineOutputBuffer.isKeyFrame(), samplePipelineOutputBuffer.timeUs)) {
return false;
}
samplePipeline.releaseOutputBuffer();
return true;
}
use of org.checkerframework.checker.nullness.qual.RequiresNonNull in project ExoPlayer by google.
the class DefaultCodecFactory method createCodec.
@RequiresNonNull("#1.sampleMimeType")
private static Codec createCodec(Format format, MediaFormat mediaFormat, boolean isVideo, boolean isDecoder, @Nullable Surface outputSurface) throws TransformationException {
@Nullable MediaCodec mediaCodec = null;
@Nullable Surface inputSurface = null;
try {
mediaCodec = isDecoder ? MediaCodec.createDecoderByType(format.sampleMimeType) : MediaCodec.createEncoderByType(format.sampleMimeType);
configureCodec(mediaCodec, mediaFormat, isDecoder, outputSurface);
if (isVideo && !isDecoder) {
inputSurface = mediaCodec.createInputSurface();
}
startCodec(mediaCodec);
} catch (Exception e) {
if (inputSurface != null) {
inputSurface.release();
}
@Nullable String mediaCodecName = null;
if (mediaCodec != null) {
mediaCodecName = mediaCodec.getName();
mediaCodec.release();
}
throw createTransformationException(e, format, isVideo, isDecoder, mediaCodecName);
}
return new Codec(mediaCodec, format, inputSurface);
}
use of org.checkerframework.checker.nullness.qual.RequiresNonNull in project ExoPlayer by google.
the class DefaultCodecFactory method getVideoEncoderSupportedFormat.
@RequiresNonNull("#1.sampleMimeType")
private static Format getVideoEncoderSupportedFormat(Format requestedFormat, List<String> allowedMimeTypes) throws TransformationException {
String mimeType = requestedFormat.sampleMimeType;
Format.Builder formatBuilder = requestedFormat.buildUpon();
// TODO(b/210591626) Implement encoder filtering.
if (!allowedMimeTypes.contains(mimeType) || EncoderUtil.getSupportedEncoders(mimeType).isEmpty()) {
mimeType = allowedMimeTypes.contains(DEFAULT_FALLBACK_MIME_TYPE) ? DEFAULT_FALLBACK_MIME_TYPE : allowedMimeTypes.get(0);
if (EncoderUtil.getSupportedEncoders(mimeType).isEmpty()) {
throw createTransformationException(new IllegalArgumentException("No encoder is found for requested MIME type " + requestedFormat.sampleMimeType), requestedFormat, /* isVideo= */
true, /* isDecoder= */
false, /* mediaCodecName= */
null);
}
}
formatBuilder.setSampleMimeType(mimeType);
MediaCodecInfo encoderInfo = EncoderUtil.getSupportedEncoders(mimeType).get(0);
int width = requestedFormat.width;
int height = requestedFormat.height;
@Nullable Pair<Integer, Integer> encoderSupportedResolution = EncoderUtil.getClosestSupportedResolution(encoderInfo, mimeType, width, height);
if (encoderSupportedResolution == null) {
throw createTransformationException(new IllegalArgumentException("Cannot find fallback resolution for resolution " + width + " x " + height), requestedFormat, /* isVideo= */
true, /* isDecoder= */
false, /* mediaCodecName= */
null);
}
width = encoderSupportedResolution.first;
height = encoderSupportedResolution.second;
formatBuilder.setWidth(width).setHeight(height);
// The frameRate does not affect the resulting frame rate. It affects the encoder's rate control
// algorithm. Setting it too high may lead to video quality degradation.
float frameRate = requestedFormat.frameRate != Format.NO_VALUE ? requestedFormat.frameRate : DEFAULT_FRAME_RATE;
int bitrate = EncoderUtil.getClosestSupportedBitrate(encoderInfo, mimeType, /* bitrate= */
requestedFormat.averageBitrate != Format.NO_VALUE ? requestedFormat.averageBitrate : getSuggestedBitrate(width, height, frameRate));
formatBuilder.setFrameRate(frameRate).setAverageBitrate(bitrate);
@Nullable Pair<Integer, Integer> profileLevel = MediaCodecUtil.getCodecProfileAndLevel(requestedFormat);
if (profileLevel == null || // Transcoding to another MIME type.
!requestedFormat.sampleMimeType.equals(mimeType) || !EncoderUtil.isProfileLevelSupported(encoderInfo, mimeType, /* profile= */
profileLevel.first, /* level= */
profileLevel.second)) {
formatBuilder.setCodecs(null);
}
return formatBuilder.build();
}
use of org.checkerframework.checker.nullness.qual.RequiresNonNull in project ExoPlayer by google.
the class HlsSampleStreamWrapper method mapSampleQueuesToMatchTrackGroups.
@RequiresNonNull("trackGroups")
@EnsuresNonNull("trackGroupToSampleQueueIndex")
private void mapSampleQueuesToMatchTrackGroups() {
int trackGroupCount = trackGroups.length;
trackGroupToSampleQueueIndex = new int[trackGroupCount];
Arrays.fill(trackGroupToSampleQueueIndex, C.INDEX_UNSET);
for (int i = 0; i < trackGroupCount; i++) {
for (int queueIndex = 0; queueIndex < sampleQueues.length; queueIndex++) {
SampleQueue sampleQueue = sampleQueues[queueIndex];
Format upstreamFormat = Assertions.checkStateNotNull(sampleQueue.getUpstreamFormat());
if (formatsMatch(upstreamFormat, trackGroups.get(i).getFormat(0))) {
trackGroupToSampleQueueIndex[i] = queueIndex;
break;
}
}
}
for (HlsSampleStream sampleStream : hlsSampleStreams) {
sampleStream.bindSampleQueue();
}
}
Aggregations