use of com.google.android.exoplayer2.transformer.TransformationException 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 com.google.android.exoplayer2.transformer.TransformationException in project ExoPlayer by google.
the class AndroidTestUtil method runTransformer.
/**
* Transforms the {@code uriString} with the {@link Transformer}.
*
* @param context The {@link Context}.
* @param testId An identifier for the test.
* @param transformer The {@link Transformer} that performs the transformation.
* @param uriString The uri (as a {@link String}) that will be transformed.
* @param timeoutSeconds The transformer timeout. An assertion confirms this is not exceeded.
* @return The {@link TransformationResult}.
* @throws Exception The cause of the transformation not completing.
*/
public static TransformationResult runTransformer(Context context, String testId, Transformer transformer, String uriString, int timeoutSeconds) throws Exception {
AtomicReference<@NullableType Exception> exceptionReference = new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
Transformer testTransformer = transformer.buildUpon().addListener(new Transformer.Listener() {
@Override
public void onTransformationCompleted(MediaItem inputMediaItem) {
countDownLatch.countDown();
}
@Override
public void onTransformationError(MediaItem inputMediaItem, TransformationException exception) {
exceptionReference.set(exception);
countDownLatch.countDown();
}
}).build();
Uri uri = Uri.parse(uriString);
File outputVideoFile = createExternalCacheFile(context, /* fileName= */
testId + "-output.mp4");
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
try {
testTransformer.startTransformation(MediaItem.fromUri(uri), outputVideoFile.getAbsolutePath());
} catch (IOException e) {
exceptionReference.set(e);
}
});
assertWithMessage("Transformer timed out after " + timeoutSeconds + " seconds.").that(countDownLatch.await(timeoutSeconds, SECONDS)).isTrue();
@Nullable Exception exception = exceptionReference.get();
if (exception != null) {
throw exception;
}
TransformationResult result = new TransformationResult.Builder(testId).setFileSizeBytes(outputVideoFile.length()).build();
writeTransformationResultToFile(context, result);
return result;
}
use of com.google.android.exoplayer2.transformer.TransformationException in project ExoPlayer by google.
the class TransformerBaseRenderer method feedPipelineFromInput.
/**
* Attempts to read input data and pass the input data to the sample pipeline.
*
* @return Whether it may be possible to read more data immediately by calling this method again.
* @throws TransformationException If a {@link SamplePipeline} problem occurs.
*/
@RequiresNonNull("samplePipeline")
private boolean feedPipelineFromInput() throws TransformationException {
@Nullable DecoderInputBuffer samplePipelineInputBuffer = samplePipeline.dequeueInputBuffer();
if (samplePipelineInputBuffer == null) {
return false;
}
@ReadDataResult int result = readSource(getFormatHolder(), samplePipelineInputBuffer, /* readFlags= */
0);
switch(result) {
case C.RESULT_BUFFER_READ:
samplePipelineInputBuffer.flip();
if (samplePipelineInputBuffer.isEndOfStream()) {
samplePipeline.queueInputBuffer();
return false;
}
mediaClock.updateTimeForTrackType(getTrackType(), samplePipelineInputBuffer.timeUs);
samplePipelineInputBuffer.timeUs -= streamOffsetUs;
checkStateNotNull(samplePipelineInputBuffer.data);
maybeQueueSampleToPipeline(samplePipelineInputBuffer);
return true;
case C.RESULT_FORMAT_READ:
throw new IllegalStateException("Format changes are not supported.");
case C.RESULT_NOTHING_READ:
default:
return false;
}
}
use of com.google.android.exoplayer2.transformer.TransformationException in project ExoPlayer by google.
the class TransformerActivity method createTransformer.
@RequiresNonNull({ "playerView", "debugTextView", "informationTextView", "transformationStopwatch", "progressViewGroup", "debugFrame" })
private Transformer createTransformer(@Nullable Bundle bundle, String filePath) {
Transformer.Builder transformerBuilder = new Transformer.Builder(/* context= */
this);
if (bundle != null) {
TransformationRequest.Builder requestBuilder = new TransformationRequest.Builder();
requestBuilder.setFlattenForSlowMotion(bundle.getBoolean(ConfigurationActivity.SHOULD_FLATTEN_FOR_SLOW_MOTION));
@Nullable String audioMimeType = bundle.getString(ConfigurationActivity.AUDIO_MIME_TYPE);
if (audioMimeType != null) {
requestBuilder.setAudioMimeType(audioMimeType);
}
@Nullable String videoMimeType = bundle.getString(ConfigurationActivity.VIDEO_MIME_TYPE);
if (videoMimeType != null) {
requestBuilder.setVideoMimeType(videoMimeType);
}
int resolutionHeight = bundle.getInt(ConfigurationActivity.RESOLUTION_HEIGHT, /* defaultValue= */
C.LENGTH_UNSET);
if (resolutionHeight != C.LENGTH_UNSET) {
requestBuilder.setResolution(resolutionHeight);
}
Matrix transformationMatrix = getTransformationMatrix(bundle);
if (!transformationMatrix.isIdentity()) {
requestBuilder.setTransformationMatrix(transformationMatrix);
}
requestBuilder.experimental_setEnableHdrEditing(bundle.getBoolean(ConfigurationActivity.ENABLE_HDR_EDITING));
transformerBuilder.setTransformationRequest(requestBuilder.build()).setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO)).setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO));
}
return transformerBuilder.addListener(new Transformer.Listener() {
@Override
public void onTransformationCompleted(MediaItem mediaItem) {
TransformerActivity.this.onTransformationCompleted(filePath);
}
@Override
public void onTransformationError(MediaItem mediaItem, TransformationException exception) {
TransformerActivity.this.onTransformationError(exception);
}
}).setDebugViewProvider(new DemoDebugViewProvider()).build();
}
use of com.google.android.exoplayer2.transformer.TransformationException in project ExoPlayer by google.
the class TransformerEndToEndTest method startTransformation_withVideoEncoderFormatUnsupported_completesWithError.
@Test
public void startTransformation_withVideoEncoderFormatUnsupported_completesWithError() throws Exception {
Transformer transformer = createTransformerBuilder().setTransformationRequest(new TransformationRequest.Builder().setVideoMimeType(// unsupported encoder MIME type
MimeTypes.VIDEO_H263).build()).build();
MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY);
transformer.startTransformation(mediaItem, outputPath);
TransformationException exception = TransformerTestRunner.runUntilError(transformer);
assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
assertThat(exception.errorCode).isEqualTo(TransformationException.ERROR_CODE_OUTPUT_FORMAT_UNSUPPORTED);
}
Aggregations