Avoid re-encoding if video effects are no-op
This is to avoid regressions introduced by removing the convenience methods from TransformationRequest. PiperOrigin-RevId: 502864512
This commit is contained in:
parent
50f066d634
commit
a043c8c204
@ -90,6 +90,13 @@ public final class ScaleToFitTransformation implements MatrixTransformation {
|
||||
}
|
||||
}
|
||||
|
||||
/** The multiplier by which the frame will scale horizontally, along the x-axis. */
|
||||
public final float scaleX;
|
||||
/** The multiplier by which the frame will scale vertically, along the y-axis. */
|
||||
public final float scaleY;
|
||||
/** How much to rotate the frame counterclockwise, in degrees. */
|
||||
public final float rotationDegrees;
|
||||
|
||||
private final Matrix transformationMatrix;
|
||||
private @MonotonicNonNull Matrix adjustedTransformationMatrix;
|
||||
|
||||
@ -101,6 +108,9 @@ public final class ScaleToFitTransformation implements MatrixTransformation {
|
||||
* @param rotationDegrees How much to rotate the frame counterclockwise, in degrees.
|
||||
*/
|
||||
private ScaleToFitTransformation(float scaleX, float scaleY, float rotationDegrees) {
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
this.rotationDegrees = rotationDegrees;
|
||||
transformationMatrix = new Matrix();
|
||||
transformationMatrix.postScale(scaleX, scaleY);
|
||||
transformationMatrix.postRotate(rotationDegrees);
|
||||
|
@ -35,6 +35,8 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.audio.AudioProcessor;
|
||||
import com.google.android.exoplayer2.effect.Presentation;
|
||||
import com.google.android.exoplayer2.effect.ScaleToFitTransformation;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
@ -44,6 +46,7 @@ import com.google.android.exoplayer2.util.Effect;
|
||||
import com.google.android.exoplayer2.util.FrameProcessor;
|
||||
import com.google.android.exoplayer2.util.HandlerWrapper;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Size;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.lang.annotation.Documented;
|
||||
@ -577,16 +580,34 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
if (inputFormat.pixelWidthHeightRatio != 1f) {
|
||||
return true;
|
||||
}
|
||||
// The decoder rotates encoded frames for display by inputFormat.rotationDegrees.
|
||||
int decodedHeight =
|
||||
(inputFormat.rotationDegrees % 180 == 0) ? inputFormat.height : inputFormat.width;
|
||||
if (transformationRequest.outputHeight != C.LENGTH_UNSET
|
||||
&& transformationRequest.outputHeight != decodedHeight) {
|
||||
return true;
|
||||
}
|
||||
if (!videoEffects.isEmpty()) {
|
||||
return true;
|
||||
|
||||
// TODO(b/265927935): consider generalizing this logic.
|
||||
for (int i = 0; i < videoEffects.size(); i++) {
|
||||
Effect videoEffect = videoEffects.get(i);
|
||||
if (videoEffect instanceof Presentation) {
|
||||
Presentation presentation = (Presentation) videoEffect;
|
||||
// The decoder rotates encoded frames for display by inputFormat.rotationDegrees.
|
||||
int decodedWidth =
|
||||
(inputFormat.rotationDegrees % 180 == 0) ? inputFormat.width : inputFormat.height;
|
||||
int decodedHeight =
|
||||
(inputFormat.rotationDegrees % 180 == 0) ? inputFormat.height : inputFormat.width;
|
||||
Size outputSize = presentation.configure(decodedWidth, decodedHeight);
|
||||
if (outputSize.getWidth() != decodedWidth || outputSize.getHeight() != decodedHeight) {
|
||||
return true;
|
||||
}
|
||||
} else if (videoEffect instanceof ScaleToFitTransformation) {
|
||||
ScaleToFitTransformation scaleToFitTransformation =
|
||||
(ScaleToFitTransformation) videoEffect;
|
||||
if (scaleToFitTransformation.scaleX != 1f
|
||||
|| scaleToFitTransformation.scaleY != 1f
|
||||
|| scaleToFitTransformation.rotationDegrees != 0f) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.audio.SonicAudioProcessor;
|
||||
import com.google.android.exoplayer2.effect.Presentation;
|
||||
import com.google.android.exoplayer2.effect.ScaleToFitTransformation;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
@ -58,6 +60,7 @@ import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.testutil.DumpFileAsserts;
|
||||
import com.google.android.exoplayer2.testutil.FakeClock;
|
||||
import com.google.android.exoplayer2.util.Effect;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -728,6 +731,23 @@ public final class TransformerEndToEndTest {
|
||||
assertThat(transformationException).hasCauseThat().isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startTransformation_withNoOpEffects_transmuxes() throws Exception {
|
||||
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
|
||||
int mediaItemHeightPixels = 720;
|
||||
List<Effect> videoEffects = new ArrayList<>();
|
||||
videoEffects.add(Presentation.createForHeight(mediaItemHeightPixels));
|
||||
videoEffects.add(new ScaleToFitTransformation.Builder().build());
|
||||
Transformer transformer =
|
||||
createTransformerBuilder(/* enableFallback= */ false).setVideoEffects(videoEffects).build();
|
||||
|
||||
transformer.startTransformation(mediaItem, outputPath);
|
||||
TransformerTestRunner.runLooper(transformer);
|
||||
|
||||
// Video transcoding in unit tests is not supported.
|
||||
DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_VIDEO_ONLY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getProgress_knownDuration_returnsConsistentStates() throws Exception {
|
||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||
|
Loading…
x
Reference in New Issue
Block a user