Force video encoding if VideoEncoderSettings are not default.

Add a MH test exercising this behaviour.

PiperOrigin-RevId: 436177198
This commit is contained in:
samrobinson 2022-03-21 12:16:50 +00:00 committed by Ian Baker
parent c8e8bb14d6
commit 18388f02c0
3 changed files with 65 additions and 1 deletions

View File

@ -25,10 +25,13 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.transformer.Codec; import com.google.android.exoplayer2.transformer.Codec;
import com.google.android.exoplayer2.transformer.DefaultEncoderFactory;
import com.google.android.exoplayer2.transformer.EncoderSelector;
import com.google.android.exoplayer2.transformer.TransformationException; import com.google.android.exoplayer2.transformer.TransformationException;
import com.google.android.exoplayer2.transformer.TransformationRequest; import com.google.android.exoplayer2.transformer.TransformationRequest;
import com.google.android.exoplayer2.transformer.Transformer; import com.google.android.exoplayer2.transformer.Transformer;
import com.google.android.exoplayer2.transformer.TransformerAndroidTestRunner; import com.google.android.exoplayer2.transformer.TransformerAndroidTestRunner;
import com.google.android.exoplayer2.transformer.VideoEncoderSettings;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.util.List; import java.util.List;
@ -97,6 +100,27 @@ public class TransformationTest {
.run(testId, MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING); .run(testId, MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING);
} }
@Test
public void transformToSpecificBitrate() throws Exception {
final String testId = TAG + "_transformWithSpecificBitrate";
Context context = ApplicationProvider.getApplicationContext();
Transformer transformer =
new Transformer.Builder(context)
.setRemoveAudio(true)
.setEncoderFactory(
new DefaultEncoderFactory(
EncoderSelector.DEFAULT,
new VideoEncoderSettings.Builder().setBitrate(5_000_000).build(),
/* enableFallback= */ true))
.build();
// TODO(b/223381524): Remove analysis failure suppression after ssim calculation doesn't fail.
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.setSuppressAnalysisExceptions(true)
.build()
.run(testId, MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING);
}
@Test @Test
public void transform4K60() throws Exception { public void transform4K60() throws Exception {
final String testId = TAG + "_transform4K60"; final String testId = TAG + "_transform4K60";

View File

@ -57,7 +57,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
/** Creates a new instance using a default {@link VideoEncoderSettings}. */ /** Creates a new instance using a default {@link VideoEncoderSettings}. */
public DefaultEncoderFactory(EncoderSelector videoEncoderSelector, boolean enableFallback) { public DefaultEncoderFactory(EncoderSelector videoEncoderSelector, boolean enableFallback) {
this(videoEncoderSelector, new VideoEncoderSettings.Builder().build(), enableFallback); this(videoEncoderSelector, VideoEncoderSettings.DEFAULT, enableFallback);
} }
/** /**
@ -191,6 +191,11 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
/* outputSurface= */ null); /* outputSurface= */ null);
} }
@Override
public boolean videoNeedsEncoding() {
return !requestedVideoEncoderSettings.equals(VideoEncoderSettings.DEFAULT);
}
/** /**
* Finds an {@link MediaCodecInfo encoder} that supports the requested format most closely. * Finds an {@link MediaCodecInfo encoder} that supports the requested format most closely.
* *

View File

@ -19,8 +19,10 @@ package com.google.android.exoplayer2.transformer;
import static com.google.android.exoplayer2.util.Assertions.checkArgument; import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.ElementType.TYPE_USE;
import android.annotation.SuppressLint;
import android.media.MediaCodecInfo; import android.media.MediaCodecInfo;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -38,6 +40,9 @@ public final class VideoEncoderSettings {
/** The default I-frame interval in seconds. */ /** The default I-frame interval in seconds. */
public static final float DEFAULT_I_FRAME_INTERVAL_SECONDS = 1.0f; public static final float DEFAULT_I_FRAME_INTERVAL_SECONDS = 1.0f;
/** A default {@link VideoEncoderSettings}. */
public static final VideoEncoderSettings DEFAULT = new Builder().build();
/** /**
* The allowed values for {@code bitrateMode}, one of * The allowed values for {@code bitrateMode}, one of
* *
@ -49,6 +54,7 @@ public final class VideoEncoderSettings {
* MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_CBR_FD}, available from API31. * MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_CBR_FD}, available from API31.
* </ul> * </ul>
*/ */
@SuppressLint("InlinedApi")
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE) @Target(TYPE_USE)
@ -205,4 +211,33 @@ public final class VideoEncoderSettings {
public Builder buildUpon() { public Builder buildUpon() {
return new Builder(this); return new Builder(this);
} }
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (!(o instanceof VideoEncoderSettings)) {
return false;
}
VideoEncoderSettings that = (VideoEncoderSettings) o;
return bitrate == that.bitrate
&& bitrateMode == that.bitrateMode
&& profile == that.profile
&& level == that.level
&& colorProfile == that.colorProfile
&& iFrameIntervalSeconds == that.iFrameIntervalSeconds;
}
@Override
public int hashCode() {
int result = 7;
result = 31 * result + bitrate;
result = 31 * result + bitrateMode;
result = 31 * result + profile;
result = 31 * result + level;
result = 31 * result + colorProfile;
result = 31 * result + Float.floatToIntBits(iFrameIntervalSeconds);
return result;
}
} }