Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
3d934844
authored
Apr 04, 2022
by
claincly
Committed by
Ian Baker
Apr 07, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add test to evaluate performance related encoding parameters.
PiperOrigin-RevId: 439268235
parent
ffeff692
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
177 additions
and
3 deletions
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/analysis/EncoderPerformanceAnalysisTest.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultEncoderFactory.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoEncoderSettings.java
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/analysis/EncoderPerformanceAnalysisTest.java
0 → 100644
View file @
3d934844
/*
* 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
);
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultEncoderFactory.java
View file @
3d934844
...
@@ -183,6 +183,17 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
...
@@ -183,6 +183,17 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
mediaFormat
.
setFloat
(
mediaFormat
.
setFloat
(
MediaFormat
.
KEY_I_FRAME_INTERVAL
,
supportedVideoEncoderSettings
.
iFrameIntervalSeconds
);
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
(
return
new
DefaultCodec
(
format
,
format
,
mediaFormat
,
mediaFormat
,
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoEncoderSettings.java
View file @
3d934844
...
@@ -21,8 +21,10 @@ import static java.lang.annotation.ElementType.TYPE_USE;
...
@@ -21,8 +21,10 @@ import static java.lang.annotation.ElementType.TYPE_USE;
import
android.annotation.SuppressLint
;
import
android.annotation.SuppressLint
;
import
android.media.MediaCodecInfo
;
import
android.media.MediaCodecInfo
;
import
android.media.MediaFormat
;
import
androidx.annotation.IntDef
;
import
androidx.annotation.IntDef
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.VisibleForTesting
;
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
;
...
@@ -74,6 +76,8 @@ public final class VideoEncoderSettings {
...
@@ -74,6 +76,8 @@ public final class VideoEncoderSettings {
private
int
level
;
private
int
level
;
private
int
colorProfile
;
private
int
colorProfile
;
private
float
iFrameIntervalSeconds
;
private
float
iFrameIntervalSeconds
;
private
int
operatingRate
;
private
int
priority
;
/** Creates a new instance. */
/** Creates a new instance. */
public
Builder
()
{
public
Builder
()
{
...
@@ -83,6 +87,8 @@ public final class VideoEncoderSettings {
...
@@ -83,6 +87,8 @@ public final class VideoEncoderSettings {
this
.
level
=
NO_VALUE
;
this
.
level
=
NO_VALUE
;
this
.
colorProfile
=
DEFAULT_COLOR_PROFILE
;
this
.
colorProfile
=
DEFAULT_COLOR_PROFILE
;
this
.
iFrameIntervalSeconds
=
DEFAULT_I_FRAME_INTERVAL_SECONDS
;
this
.
iFrameIntervalSeconds
=
DEFAULT_I_FRAME_INTERVAL_SECONDS
;
this
.
operatingRate
=
NO_VALUE
;
this
.
priority
=
NO_VALUE
;
}
}
private
Builder
(
VideoEncoderSettings
videoEncoderSettings
)
{
private
Builder
(
VideoEncoderSettings
videoEncoderSettings
)
{
...
@@ -92,6 +98,8 @@ public final class VideoEncoderSettings {
...
@@ -92,6 +98,8 @@ public final class VideoEncoderSettings {
this
.
level
=
videoEncoderSettings
.
level
;
this
.
level
=
videoEncoderSettings
.
level
;
this
.
colorProfile
=
videoEncoderSettings
.
colorProfile
;
this
.
colorProfile
=
videoEncoderSettings
.
colorProfile
;
this
.
iFrameIntervalSeconds
=
videoEncoderSettings
.
iFrameIntervalSeconds
;
this
.
iFrameIntervalSeconds
=
videoEncoderSettings
.
iFrameIntervalSeconds
;
this
.
operatingRate
=
videoEncoderSettings
.
operatingRate
;
this
.
priority
=
videoEncoderSettings
.
priority
;
}
}
/**
/**
...
@@ -170,10 +178,31 @@ public final class VideoEncoderSettings {
...
@@ -170,10 +178,31 @@ public final class VideoEncoderSettings {
return
this
;
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. */
/** Builds the instance. */
public
VideoEncoderSettings
build
()
{
public
VideoEncoderSettings
build
()
{
return
new
VideoEncoderSettings
(
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 {
...
@@ -189,6 +218,10 @@ public final class VideoEncoderSettings {
public
final
int
colorProfile
;
public
final
int
colorProfile
;
/** The encoding I-Frame interval in seconds. */
/** The encoding I-Frame interval in seconds. */
public
final
float
iFrameIntervalSeconds
;
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
(
private
VideoEncoderSettings
(
int
bitrate
,
int
bitrate
,
...
@@ -196,13 +229,17 @@ public final class VideoEncoderSettings {
...
@@ -196,13 +229,17 @@ public final class VideoEncoderSettings {
int
profile
,
int
profile
,
int
level
,
int
level
,
int
colorProfile
,
int
colorProfile
,
float
iFrameIntervalSeconds
)
{
float
iFrameIntervalSeconds
,
int
operatingRate
,
int
priority
)
{
this
.
bitrate
=
bitrate
;
this
.
bitrate
=
bitrate
;
this
.
bitrateMode
=
bitrateMode
;
this
.
bitrateMode
=
bitrateMode
;
this
.
profile
=
profile
;
this
.
profile
=
profile
;
this
.
level
=
level
;
this
.
level
=
level
;
this
.
colorProfile
=
colorProfile
;
this
.
colorProfile
=
colorProfile
;
this
.
iFrameIntervalSeconds
=
iFrameIntervalSeconds
;
this
.
iFrameIntervalSeconds
=
iFrameIntervalSeconds
;
this
.
operatingRate
=
operatingRate
;
this
.
priority
=
priority
;
}
}
/**
/**
...
@@ -226,7 +263,9 @@ public final class VideoEncoderSettings {
...
@@ -226,7 +263,9 @@ public final class VideoEncoderSettings {
&&
profile
==
that
.
profile
&&
profile
==
that
.
profile
&&
level
==
that
.
level
&&
level
==
that
.
level
&&
colorProfile
==
that
.
colorProfile
&&
colorProfile
==
that
.
colorProfile
&&
iFrameIntervalSeconds
==
that
.
iFrameIntervalSeconds
;
&&
iFrameIntervalSeconds
==
that
.
iFrameIntervalSeconds
&&
operatingRate
==
that
.
operatingRate
&&
priority
==
that
.
priority
;
}
}
@Override
@Override
...
@@ -238,6 +277,8 @@ public final class VideoEncoderSettings {
...
@@ -238,6 +277,8 @@ public final class VideoEncoderSettings {
result
=
31
*
result
+
level
;
result
=
31
*
result
+
level
;
result
=
31
*
result
+
colorProfile
;
result
=
31
*
result
+
colorProfile
;
result
=
31
*
result
+
Float
.
floatToIntBits
(
iFrameIntervalSeconds
);
result
=
31
*
result
+
Float
.
floatToIntBits
(
iFrameIntervalSeconds
);
result
=
31
*
result
+
operatingRate
;
result
=
31
*
result
+
priority
;
return
result
;
return
result
;
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment