mirror of
https://github.com/samsonjs/media.git
synced 2026-04-03 10:55:48 +00:00
Add test to evaluate performance related encoding parameters.
PiperOrigin-RevId: 439268235
This commit is contained in:
parent
ffeff69236
commit
3d93484402
3 changed files with 177 additions and 3 deletions
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.exoplayer2.transformer.mh.analysis;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaFormat;
|
||||
import android.net.Uri;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import com.google.android.exoplayer2.transformer.AndroidTestUtil;
|
||||
import com.google.android.exoplayer2.transformer.DefaultEncoderFactory;
|
||||
import com.google.android.exoplayer2.transformer.EncoderSelector;
|
||||
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.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/** Instrumentation tests for analyzing encoder performance settings. */
|
||||
@RunWith(Parameterized.class)
|
||||
public class EncoderPerformanceAnalysisTest {
|
||||
|
||||
/** A non-realtime {@link MediaFormat#KEY_PRIORITY encoder priority}. */
|
||||
private static final int MEDIA_CODEC_PRIORITY_NON_REALTIME = 0;
|
||||
/** A realtime {@link MediaFormat#KEY_PRIORITY encoder priority}. */
|
||||
private static final int MEDIA_CODEC_PRIORITY_REALTIME = 1;
|
||||
|
||||
private static final ImmutableList<String> INPUT_FILES =
|
||||
ImmutableList.of(
|
||||
AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING,
|
||||
AndroidTestUtil.MP4_REMOTE_4K60_PORTRAIT_URI_STRING);
|
||||
|
||||
private static final ImmutableList<Integer> OPERATING_RATE_SETTINGS =
|
||||
ImmutableList.of(VideoEncoderSettings.NO_VALUE, 30, Integer.MAX_VALUE);
|
||||
|
||||
private static final ImmutableList<Integer> PRIORITY_SETTINGS =
|
||||
ImmutableList.of(
|
||||
// Use NO_VALUE to skip setting priority.
|
||||
VideoEncoderSettings.NO_VALUE,
|
||||
MEDIA_CODEC_PRIORITY_NON_REALTIME,
|
||||
MEDIA_CODEC_PRIORITY_REALTIME);
|
||||
|
||||
@Parameter(0)
|
||||
public @MonotonicNonNull String fileUri;
|
||||
|
||||
@Parameter(1)
|
||||
public int operatingRate;
|
||||
|
||||
@Parameter(2)
|
||||
public int priority;
|
||||
|
||||
@Parameters(name = "analyzePerformance_{0}_OpRate={1}_Priority={2}")
|
||||
public static ImmutableList<Object[]> parameters() {
|
||||
ImmutableList.Builder<Object[]> parametersBuilder = new ImmutableList.Builder<>();
|
||||
for (int i = 0; i < INPUT_FILES.size(); i++) {
|
||||
for (int j = 0; j < OPERATING_RATE_SETTINGS.size(); j++) {
|
||||
for (int k = 0; k < PRIORITY_SETTINGS.size(); k++) {
|
||||
parametersBuilder.add(
|
||||
new Object[] {
|
||||
INPUT_FILES.get(i), OPERATING_RATE_SETTINGS.get(j), PRIORITY_SETTINGS.get(k)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return parametersBuilder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void analyzeEncoderPerformance() throws Exception {
|
||||
checkNotNull(fileUri);
|
||||
String filename = checkNotNull(Uri.parse(fileUri).getLastPathSegment());
|
||||
String testId =
|
||||
Util.formatInvariant(
|
||||
"analyzePerformance_%s_OpRate_%d_Priority_%d", filename, operatingRate, priority);
|
||||
|
||||
Map<String, Object> inputValues = new HashMap<>();
|
||||
inputValues.put("inputFilename", filename);
|
||||
inputValues.put("operatingRate", operatingRate);
|
||||
inputValues.put("priority", priority);
|
||||
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
Transformer transformer =
|
||||
new Transformer.Builder(context)
|
||||
.setRemoveAudio(true)
|
||||
.setEncoderFactory(
|
||||
new DefaultEncoderFactory(
|
||||
EncoderSelector.DEFAULT,
|
||||
new VideoEncoderSettings.Builder()
|
||||
.setEncoderPerformanceParameters(operatingRate, priority)
|
||||
.build(),
|
||||
/* enableFallback= */ false))
|
||||
.build();
|
||||
|
||||
new TransformerAndroidTestRunner.Builder(context, transformer)
|
||||
.setInputValues(inputValues)
|
||||
.build()
|
||||
.run(testId, fileUri);
|
||||
}
|
||||
}
|
||||
|
|
@ -183,6 +183,17 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||
mediaFormat.setFloat(
|
||||
MediaFormat.KEY_I_FRAME_INTERVAL, supportedVideoEncoderSettings.iFrameIntervalSeconds);
|
||||
|
||||
if (Util.SDK_INT >= 23) {
|
||||
// Setting operating rate and priority is supported from API 23.
|
||||
if (supportedVideoEncoderSettings.operatingRate != VideoEncoderSettings.NO_VALUE) {
|
||||
mediaFormat.setInteger(
|
||||
MediaFormat.KEY_OPERATING_RATE, supportedVideoEncoderSettings.operatingRate);
|
||||
}
|
||||
if (supportedVideoEncoderSettings.priority != VideoEncoderSettings.NO_VALUE) {
|
||||
mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, supportedVideoEncoderSettings.priority);
|
||||
}
|
||||
}
|
||||
|
||||
return new DefaultCodec(
|
||||
format,
|
||||
mediaFormat,
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ import static java.lang.annotation.ElementType.TYPE_USE;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaFormat;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
|
|
@ -74,6 +76,8 @@ public final class VideoEncoderSettings {
|
|||
private int level;
|
||||
private int colorProfile;
|
||||
private float iFrameIntervalSeconds;
|
||||
private int operatingRate;
|
||||
private int priority;
|
||||
|
||||
/** Creates a new instance. */
|
||||
public Builder() {
|
||||
|
|
@ -83,6 +87,8 @@ public final class VideoEncoderSettings {
|
|||
this.level = NO_VALUE;
|
||||
this.colorProfile = DEFAULT_COLOR_PROFILE;
|
||||
this.iFrameIntervalSeconds = DEFAULT_I_FRAME_INTERVAL_SECONDS;
|
||||
this.operatingRate = NO_VALUE;
|
||||
this.priority = NO_VALUE;
|
||||
}
|
||||
|
||||
private Builder(VideoEncoderSettings videoEncoderSettings) {
|
||||
|
|
@ -92,6 +98,8 @@ public final class VideoEncoderSettings {
|
|||
this.level = videoEncoderSettings.level;
|
||||
this.colorProfile = videoEncoderSettings.colorProfile;
|
||||
this.iFrameIntervalSeconds = videoEncoderSettings.iFrameIntervalSeconds;
|
||||
this.operatingRate = videoEncoderSettings.operatingRate;
|
||||
this.priority = videoEncoderSettings.priority;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -170,10 +178,31 @@ public final class VideoEncoderSettings {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets encoding operating rate and priority. The default values are {@link #NO_VALUE}.
|
||||
*
|
||||
* @param operatingRate The {@link MediaFormat#KEY_OPERATING_RATE operating rate}.
|
||||
* @param priority The {@link MediaFormat#KEY_PRIORITY priority}.
|
||||
* @return This builder.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Builder setEncoderPerformanceParameters(int operatingRate, int priority) {
|
||||
this.operatingRate = operatingRate;
|
||||
this.priority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the instance. */
|
||||
public VideoEncoderSettings build() {
|
||||
return new VideoEncoderSettings(
|
||||
bitrate, bitrateMode, profile, level, colorProfile, iFrameIntervalSeconds);
|
||||
bitrate,
|
||||
bitrateMode,
|
||||
profile,
|
||||
level,
|
||||
colorProfile,
|
||||
iFrameIntervalSeconds,
|
||||
operatingRate,
|
||||
priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,6 +218,10 @@ public final class VideoEncoderSettings {
|
|||
public final int colorProfile;
|
||||
/** The encoding I-Frame interval in seconds. */
|
||||
public final float iFrameIntervalSeconds;
|
||||
/** The encoder {@link MediaFormat#KEY_OPERATING_RATE operating rate}. */
|
||||
public final int operatingRate;
|
||||
/** The encoder {@link MediaFormat#KEY_PRIORITY priority}. */
|
||||
public final int priority;
|
||||
|
||||
private VideoEncoderSettings(
|
||||
int bitrate,
|
||||
|
|
@ -196,13 +229,17 @@ public final class VideoEncoderSettings {
|
|||
int profile,
|
||||
int level,
|
||||
int colorProfile,
|
||||
float iFrameIntervalSeconds) {
|
||||
float iFrameIntervalSeconds,
|
||||
int operatingRate,
|
||||
int priority) {
|
||||
this.bitrate = bitrate;
|
||||
this.bitrateMode = bitrateMode;
|
||||
this.profile = profile;
|
||||
this.level = level;
|
||||
this.colorProfile = colorProfile;
|
||||
this.iFrameIntervalSeconds = iFrameIntervalSeconds;
|
||||
this.operatingRate = operatingRate;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -226,7 +263,9 @@ public final class VideoEncoderSettings {
|
|||
&& profile == that.profile
|
||||
&& level == that.level
|
||||
&& colorProfile == that.colorProfile
|
||||
&& iFrameIntervalSeconds == that.iFrameIntervalSeconds;
|
||||
&& iFrameIntervalSeconds == that.iFrameIntervalSeconds
|
||||
&& operatingRate == that.operatingRate
|
||||
&& priority == that.priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -238,6 +277,8 @@ public final class VideoEncoderSettings {
|
|||
result = 31 * result + level;
|
||||
result = 31 * result + colorProfile;
|
||||
result = 31 * result + Float.floatToIntBits(iFrameIntervalSeconds);
|
||||
result = 31 * result + operatingRate;
|
||||
result = 31 * result + priority;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue