Skip to content

Commit

Permalink
Fix assertion error when using high quality targeting API.
Browse files Browse the repository at this point in the history
Add test that verifies SSIM with API enabled.

#minor-release

PiperOrigin-RevId: 460692420
  • Loading branch information
Samrobbo authored and rohitjoins committed Jul 13, 2022
1 parent 6043739 commit 6ec18c8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 23 deletions.
Expand Up @@ -24,10 +24,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.transformer.AndroidTestUtil;
import com.google.android.exoplayer2.transformer.DefaultEncoderFactory;
import com.google.android.exoplayer2.transformer.TransformationRequest;
import com.google.android.exoplayer2.transformer.TransformationTestResult;
import com.google.android.exoplayer2.transformer.Transformer;
import com.google.android.exoplayer2.transformer.TransformerAndroidTestRunner;
import com.google.android.exoplayer2.transformer.VideoEncoderSettings;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -36,9 +38,10 @@
@RunWith(AndroidJUnit4.class)
public final class TranscodeQualityTest {
@Test
public void transformWithDecodeEncode_ssimIsGreaterThan90Percent() throws Exception {
public void transformHighQualityTargetingAvcToAvc1920x1080_ssimIsGreaterThan95Percent()
throws Exception {
Context context = ApplicationProvider.getApplicationContext();
String testId = "transformWithDecodeEncode_ssim";
String testId = "transformHighQualityTargetingAvcToAvc1920x1080_ssim";

if (AndroidTestUtil.skipAndLogIfInsufficientCodecSupport(
context,
Expand All @@ -52,7 +55,13 @@ public void transformWithDecodeEncode_ssimIsGreaterThan90Percent() throws Except
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setVideoMimeType(MimeTypes.VIDEO_H264).build())
.setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context))
.setEncoderFactory(
new DefaultEncoderFactory.Builder(context)
.setRequestedVideoEncoderSettings(
new VideoEncoderSettings.Builder()
.setEnableHighQualityTargeting(true)
.build())
.build())
.setRemoveAudio(true)
.build();

Expand Down
Expand Up @@ -239,27 +239,27 @@ public Codec createForVideoEncoding(Format format, List<String> allowedMimeTypes
mimeType, encoderSupportedFormat.width, encoderSupportedFormat.height);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, round(encoderSupportedFormat.frameRate));

int bitrate;

if (supportedVideoEncoderSettings.enableHighQualityTargeting) {
bitrate =
int bitrate =
new DeviceMappedEncoderBitrateProvider()
.getBitrate(
encoderInfo.getName(),
encoderSupportedFormat.width,
encoderSupportedFormat.height,
encoderSupportedFormat.frameRate);
} else if (supportedVideoEncoderSettings.bitrate != VideoEncoderSettings.NO_VALUE) {
bitrate = supportedVideoEncoderSettings.bitrate;
} else {
bitrate =
encoderSupportedFormat =
encoderSupportedFormat.buildUpon().setAverageBitrate(bitrate).build();
} else if (encoderSupportedFormat.bitrate == Format.NO_VALUE) {
int bitrate =
getSuggestedBitrate(
encoderSupportedFormat.width,
encoderSupportedFormat.height,
encoderSupportedFormat.frameRate);
encoderSupportedFormat =
encoderSupportedFormat.buildUpon().setAverageBitrate(bitrate).build();
}

mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, encoderSupportedFormat.averageBitrate);
mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, supportedVideoEncoderSettings.bitrateMode);

if (supportedVideoEncoderSettings.profile != VideoEncoderSettings.NO_VALUE
Expand Down Expand Up @@ -389,11 +389,23 @@ private static VideoEncoderQueryResult findEncoderWithClosestFormatSupport(
return null;
}

// TODO(b/238094555): Check encoder supports bitrate targeted by high quality.
MediaCodecInfo pickedEncoderInfo = filteredEncoderInfos.get(0);
int closestSupportedBitrate =
EncoderUtil.getSupportedBitrateRange(pickedEncoderInfo, mimeType).clamp(requestedBitrate);
VideoEncoderSettings.Builder supportedEncodingSettingBuilder =
videoEncoderSettings.buildUpon().setBitrate(closestSupportedBitrate);

VideoEncoderSettings.Builder supportedEncodingSettingBuilder = videoEncoderSettings.buildUpon();
Format.Builder encoderSupportedFormatBuilder =
requestedFormat
.buildUpon()
.setSampleMimeType(mimeType)
.setWidth(finalResolution.getWidth())
.setHeight(finalResolution.getHeight());

if (!videoEncoderSettings.enableHighQualityTargeting) {
supportedEncodingSettingBuilder.setBitrate(closestSupportedBitrate);
encoderSupportedFormatBuilder.setAverageBitrate(closestSupportedBitrate);
}

if (videoEncoderSettings.profile == VideoEncoderSettings.NO_VALUE
|| videoEncoderSettings.level == VideoEncoderSettings.NO_VALUE
Expand All @@ -404,16 +416,10 @@ private static VideoEncoderQueryResult findEncoderWithClosestFormatSupport(
VideoEncoderSettings.NO_VALUE, VideoEncoderSettings.NO_VALUE);
}

Format encoderSupportedFormat =
requestedFormat
.buildUpon()
.setSampleMimeType(mimeType)
.setWidth(finalResolution.getWidth())
.setHeight(finalResolution.getHeight())
.setAverageBitrate(closestSupportedBitrate)
.build();
return new VideoEncoderQueryResult(
pickedEncoderInfo, encoderSupportedFormat, supportedEncodingSettingBuilder.build());
pickedEncoderInfo,
encoderSupportedFormatBuilder.build(),
supportedEncodingSettingBuilder.build());
}

/** Returns a list of encoders that support the requested resolution most closely. */
Expand Down Expand Up @@ -648,7 +654,7 @@ private static boolean mimeTypeIsSupported(
* </ul>
*/
private static int getSuggestedBitrate(int width, int height, float frameRate) {
// TODO(b/210591626) Refactor into a BitrateProvider.
// TODO(b/238094555) Refactor into a BitrateProvider.
// Assume medium motion factor.
// 1080p60 -> 16.6Mbps, 720p30 -> 3.7Mbps.
return (int) (width * height * frameRate * 0.07 * 2);
Expand Down

0 comments on commit 6ec18c8

Please sign in to comment.