Fix assertion error when using high quality targeting API.
Add test that verifies SSIM with API enabled. #minor-release PiperOrigin-RevId: 460692420
This commit is contained in:
parent
bd8723e35a
commit
f903869eb8
@ -23,10 +23,12 @@ import android.net.Uri;
|
|||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.transformer.AndroidTestUtil;
|
import androidx.media3.transformer.AndroidTestUtil;
|
||||||
|
import androidx.media3.transformer.DefaultEncoderFactory;
|
||||||
import androidx.media3.transformer.TransformationRequest;
|
import androidx.media3.transformer.TransformationRequest;
|
||||||
import androidx.media3.transformer.TransformationTestResult;
|
import androidx.media3.transformer.TransformationTestResult;
|
||||||
import androidx.media3.transformer.Transformer;
|
import androidx.media3.transformer.Transformer;
|
||||||
import androidx.media3.transformer.TransformerAndroidTestRunner;
|
import androidx.media3.transformer.TransformerAndroidTestRunner;
|
||||||
|
import androidx.media3.transformer.VideoEncoderSettings;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -36,9 +38,10 @@ import org.junit.runner.RunWith;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public final class TranscodeQualityTest {
|
public final class TranscodeQualityTest {
|
||||||
@Test
|
@Test
|
||||||
public void transformWithDecodeEncode_ssimIsGreaterThan90Percent() throws Exception {
|
public void transformHighQualityTargetingAvcToAvc1920x1080_ssimIsGreaterThan95Percent()
|
||||||
|
throws Exception {
|
||||||
Context context = ApplicationProvider.getApplicationContext();
|
Context context = ApplicationProvider.getApplicationContext();
|
||||||
String testId = "transformWithDecodeEncode_ssim";
|
String testId = "transformHighQualityTargetingAvcToAvc1920x1080_ssim";
|
||||||
|
|
||||||
if (AndroidTestUtil.skipAndLogIfInsufficientCodecSupport(
|
if (AndroidTestUtil.skipAndLogIfInsufficientCodecSupport(
|
||||||
context,
|
context,
|
||||||
@ -52,7 +55,13 @@ public final class TranscodeQualityTest {
|
|||||||
new Transformer.Builder(context)
|
new Transformer.Builder(context)
|
||||||
.setTransformationRequest(
|
.setTransformationRequest(
|
||||||
new TransformationRequest.Builder().setVideoMimeType(MimeTypes.VIDEO_H264).build())
|
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)
|
.setRemoveAudio(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -241,27 +241,27 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
mimeType, encoderSupportedFormat.width, encoderSupportedFormat.height);
|
mimeType, encoderSupportedFormat.width, encoderSupportedFormat.height);
|
||||||
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, round(encoderSupportedFormat.frameRate));
|
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, round(encoderSupportedFormat.frameRate));
|
||||||
|
|
||||||
int bitrate;
|
|
||||||
|
|
||||||
if (supportedVideoEncoderSettings.enableHighQualityTargeting) {
|
if (supportedVideoEncoderSettings.enableHighQualityTargeting) {
|
||||||
bitrate =
|
int bitrate =
|
||||||
new DeviceMappedEncoderBitrateProvider()
|
new DeviceMappedEncoderBitrateProvider()
|
||||||
.getBitrate(
|
.getBitrate(
|
||||||
encoderInfo.getName(),
|
encoderInfo.getName(),
|
||||||
encoderSupportedFormat.width,
|
encoderSupportedFormat.width,
|
||||||
encoderSupportedFormat.height,
|
encoderSupportedFormat.height,
|
||||||
encoderSupportedFormat.frameRate);
|
encoderSupportedFormat.frameRate);
|
||||||
} else if (supportedVideoEncoderSettings.bitrate != VideoEncoderSettings.NO_VALUE) {
|
encoderSupportedFormat =
|
||||||
bitrate = supportedVideoEncoderSettings.bitrate;
|
encoderSupportedFormat.buildUpon().setAverageBitrate(bitrate).build();
|
||||||
} else {
|
} else if (encoderSupportedFormat.bitrate == Format.NO_VALUE) {
|
||||||
bitrate =
|
int bitrate =
|
||||||
getSuggestedBitrate(
|
getSuggestedBitrate(
|
||||||
encoderSupportedFormat.width,
|
encoderSupportedFormat.width,
|
||||||
encoderSupportedFormat.height,
|
encoderSupportedFormat.height,
|
||||||
encoderSupportedFormat.frameRate);
|
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);
|
mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, supportedVideoEncoderSettings.bitrateMode);
|
||||||
|
|
||||||
if (supportedVideoEncoderSettings.profile != VideoEncoderSettings.NO_VALUE
|
if (supportedVideoEncoderSettings.profile != VideoEncoderSettings.NO_VALUE
|
||||||
@ -391,11 +391,23 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(b/238094555): Check encoder supports bitrate targeted by high quality.
|
||||||
MediaCodecInfo pickedEncoderInfo = filteredEncoderInfos.get(0);
|
MediaCodecInfo pickedEncoderInfo = filteredEncoderInfos.get(0);
|
||||||
int closestSupportedBitrate =
|
int closestSupportedBitrate =
|
||||||
EncoderUtil.getSupportedBitrateRange(pickedEncoderInfo, mimeType).clamp(requestedBitrate);
|
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
|
if (videoEncoderSettings.profile == VideoEncoderSettings.NO_VALUE
|
||||||
|| videoEncoderSettings.level == VideoEncoderSettings.NO_VALUE
|
|| videoEncoderSettings.level == VideoEncoderSettings.NO_VALUE
|
||||||
@ -406,16 +418,10 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
VideoEncoderSettings.NO_VALUE, VideoEncoderSettings.NO_VALUE);
|
VideoEncoderSettings.NO_VALUE, VideoEncoderSettings.NO_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Format encoderSupportedFormat =
|
|
||||||
requestedFormat
|
|
||||||
.buildUpon()
|
|
||||||
.setSampleMimeType(mimeType)
|
|
||||||
.setWidth(finalResolution.getWidth())
|
|
||||||
.setHeight(finalResolution.getHeight())
|
|
||||||
.setAverageBitrate(closestSupportedBitrate)
|
|
||||||
.build();
|
|
||||||
return new VideoEncoderQueryResult(
|
return new VideoEncoderQueryResult(
|
||||||
pickedEncoderInfo, encoderSupportedFormat, supportedEncodingSettingBuilder.build());
|
pickedEncoderInfo,
|
||||||
|
encoderSupportedFormatBuilder.build(),
|
||||||
|
supportedEncodingSettingBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a list of encoders that support the requested resolution most closely. */
|
/** Returns a list of encoders that support the requested resolution most closely. */
|
||||||
@ -650,7 +656,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
private static int getSuggestedBitrate(int width, int height, float frameRate) {
|
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.
|
// Assume medium motion factor.
|
||||||
// 1080p60 -> 16.6Mbps, 720p30 -> 3.7Mbps.
|
// 1080p60 -> 16.6Mbps, 720p30 -> 3.7Mbps.
|
||||||
return (int) (width * height * frameRate * 0.07 * 2);
|
return (int) (width * height * frameRate * 0.07 * 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user