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
61a20d5f
authored
Apr 06, 2022
by
claincly
Committed by
Ian Baker
Apr 07, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add test to query device capabilities.
PiperOrigin-RevId: 439861685
parent
b5eba24e
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
306 additions
and
40 deletions
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/AndroidTestUtil.java
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/analysis/EncoderCapabilityAnalysisTest.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultEncoderFactory.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/EncoderUtil.java
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/AndroidTestUtil.java
View file @
61a20d5f
...
...
@@ -21,6 +21,7 @@ import android.content.Context;
import
android.os.Build
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.Util
;
import
java.io.File
;
import
java.io.FileWriter
;
import
java.io.IOException
;
...
...
@@ -126,14 +127,16 @@ public final class AndroidTestUtil {
* @param testId A unique identifier for the transformer test run.
* @param testJson A {@link JSONObject} containing a summary of the test run.
*/
/* package */
static
void
writeTestSummaryToFile
(
Context
context
,
String
testId
,
JSONObject
testJson
)
throws
IOException
,
JSONException
{
public
static
void
writeTestSummaryToFile
(
Context
context
,
String
testId
,
JSONObject
testJson
)
throws
IOException
,
JSONException
{
testJson
.
put
(
"testId"
,
testId
).
put
(
"device"
,
getDeviceDetailsAsJsonObject
());
String
analysisContents
=
testJson
.
toString
(
/* indentSpaces= */
2
);
// Log contents as well as writing to file, for easier visibility on individual device testing.
Log
.
i
(
testId
,
analysisContents
);
for
(
String
line
:
Util
.
split
(
analysisContents
,
"\n"
))
{
Log
.
i
(
testId
,
line
);
}
File
analysisFile
=
createExternalCacheFile
(
context
,
/* fileName= */
testId
+
"-result.txt"
);
try
(
FileWriter
fileWriter
=
new
FileWriter
(
analysisFile
))
{
...
...
library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/mh/analysis/EncoderCapabilityAnalysisTest.java
0 → 100644
View file @
61a20d5f
/*
* 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
android
.
media
.
MediaCodecInfo
.
EncoderCapabilities
.
BITRATE_MODE_CBR
;
import
static
android
.
media
.
MediaCodecInfo
.
EncoderCapabilities
.
BITRATE_MODE_CBR_FD
;
import
static
android
.
media
.
MediaCodecInfo
.
EncoderCapabilities
.
BITRATE_MODE_CQ
;
import
static
android
.
media
.
MediaCodecInfo
.
EncoderCapabilities
.
BITRATE_MODE_VBR
;
import
android.media.MediaCodecInfo
;
import
android.util.Pair
;
import
android.util.Range
;
import
android.util.Size
;
import
androidx.annotation.Nullable
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.transformer.AndroidTestUtil
;
import
com.google.android.exoplayer2.transformer.EncoderUtil
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableSet
;
import
java.util.ArrayList
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.json.JSONObject
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** An analysis test to log encoder capabilities on a device. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
EncoderCapabilityAnalysisTest
{
// TODO(b/228167357): Remove after bumping compileApiVersion to 33.
/** Re-definition of {@code MediaCodecInfo.CodecCapabilities.FEATURE_HdrEditing} in API33. */
private
static
final
String
FEATURE_HdrEditing
=
"hdr-editing"
;
/**
* Re-definition of {@code MediaCodecInfo.CodecCapabilities.FEATURE_EncodingStatistics} in API33.
*/
private
static
final
String
FEATURE_EncodingStatistics
=
"encoding-statistics"
;
@Test
public
void
logEncoderCapabilities
()
throws
Exception
{
ImmutableSet
<
String
>
supportedVideoMimeTypes
=
EncoderUtil
.
getSupportedVideoMimeTypes
();
// Map from MIME type to a list of maps from capability name to value.
LinkedHashMap
<
String
,
List
<
Map
<
String
,
Object
>>>
mimeTypeToEncoderInfo
=
new
LinkedHashMap
<>();
for
(
String
mimeType
:
supportedVideoMimeTypes
)
{
ImmutableList
<
MediaCodecInfo
>
encoderInfos
=
EncoderUtil
.
getSupportedEncoders
(
mimeType
);
ArrayList
<
Map
<
String
,
Object
>>
encoderCapabilitiesForMimeType
=
new
ArrayList
<>();
for
(
MediaCodecInfo
encoderInfo
:
encoderInfos
)
{
LinkedHashMap
<
String
,
Object
>
capabilities
=
new
LinkedHashMap
<>();
capabilities
.
put
(
"encoder_name"
,
encoderInfo
.
getName
());
capabilities
.
put
(
"is_software_encoder"
,
!
EncoderUtil
.
isHardwareAccelerated
(
encoderInfo
,
mimeType
));
// Bitrate modes.
capabilities
.
put
(
"supports_vbr"
,
EncoderUtil
.
isBitrateModeSupported
(
encoderInfo
,
mimeType
,
BITRATE_MODE_VBR
));
capabilities
.
put
(
"supports_cbr"
,
EncoderUtil
.
isBitrateModeSupported
(
encoderInfo
,
mimeType
,
BITRATE_MODE_CBR
));
capabilities
.
put
(
"supports_cq"
,
EncoderUtil
.
isBitrateModeSupported
(
encoderInfo
,
mimeType
,
BITRATE_MODE_CQ
));
capabilities
.
put
(
"supports_cbr_fd"
,
EncoderUtil
.
isBitrateModeSupported
(
encoderInfo
,
mimeType
,
BITRATE_MODE_CBR_FD
));
capabilities
.
put
(
"supported_bitrate_range"
,
rangeToString
(
EncoderUtil
.
getSupportedBitrateRange
(
encoderInfo
,
mimeType
)));
// Resolution support.
Pair
<
Range
<
Integer
>,
Range
<
Integer
>>
supportedResolutionRanges
=
EncoderUtil
.
getSupportedResolutionRanges
(
encoderInfo
,
mimeType
);
capabilities
.
put
(
"supported_widths_range"
,
rangeToString
(
supportedResolutionRanges
.
first
));
capabilities
.
put
(
"supported_heights_range"
,
rangeToString
(
supportedResolutionRanges
.
second
));
checkResolutionSupport
(
encoderInfo
,
mimeType
,
capabilities
,
/* width= */
1280
,
/* height= */
720
);
checkResolutionSupport
(
encoderInfo
,
mimeType
,
capabilities
,
/* width= */
1920
,
/* height= */
1080
);
checkResolutionSupport
(
encoderInfo
,
mimeType
,
capabilities
,
/* width= */
2560
,
/* height= */
1440
);
checkResolutionSupport
(
encoderInfo
,
mimeType
,
capabilities
,
/* width= */
3840
,
/* height= */
2160
);
checkProfileLevelSupport
(
encoderInfo
,
mimeType
,
capabilities
);
capabilities
.
put
(
"supported_color_profiles"
,
EncoderUtil
.
getSupportedColorFormats
(
encoderInfo
,
mimeType
));
capabilities
.
put
(
"max_supported_instances"
,
Util
.
SDK_INT
>=
23
?
EncoderUtil
.
getMaxSupportedInstances
(
encoderInfo
,
mimeType
)
:
-
1
);
capabilities
.
put
(
"supports_qp_bounds"
,
Util
.
SDK_INT
>=
31
&&
EncoderUtil
.
isFeatureSupported
(
encoderInfo
,
mimeType
,
MediaCodecInfo
.
CodecCapabilities
.
FEATURE_QpBounds
));
capabilities
.
put
(
"supports_hdr_editing"
,
Util
.
SDK_INT
>=
33
&&
EncoderUtil
.
isFeatureSupported
(
encoderInfo
,
mimeType
,
FEATURE_HdrEditing
));
capabilities
.
put
(
"supports_encoding_statistics"
,
Util
.
SDK_INT
>=
33
&&
EncoderUtil
.
isFeatureSupported
(
encoderInfo
,
mimeType
,
FEATURE_EncodingStatistics
));
encoderCapabilitiesForMimeType
.
add
(
capabilities
);
}
mimeTypeToEncoderInfo
.
put
(
mimeType
,
encoderCapabilitiesForMimeType
);
}
JSONObject
resultJson
=
new
JSONObject
();
resultJson
.
put
(
"encoder_capabilities"
,
JSONObject
.
wrap
(
mimeTypeToEncoderInfo
));
AndroidTestUtil
.
writeTestSummaryToFile
(
ApplicationProvider
.
getApplicationContext
(),
/* testId= */
"encoderCapabilityAnalysisTest"
,
resultJson
);
}
private
static
void
checkResolutionSupport
(
MediaCodecInfo
encoder
,
String
mimeType
,
Map
<
String
,
Object
>
capabilities
,
int
width
,
int
height
)
{
Range
<
Integer
>
supportedWidths
=
EncoderUtil
.
getSupportedResolutionRanges
(
encoder
,
mimeType
).
first
;
@Nullable
Range
<
Integer
>
supportedHeights
=
null
;
if
(
supportedWidths
.
contains
(
width
))
{
supportedHeights
=
EncoderUtil
.
getSupportedHeights
(
encoder
,
mimeType
,
width
);
}
capabilities
.
put
(
Util
.
formatInvariant
(
"supported_heights_for_%d"
,
width
),
rangeToString
(
supportedHeights
));
@Nullable
Size
supportedResolution
=
EncoderUtil
.
getSupportedResolution
(
encoder
,
mimeType
,
width
,
height
);
if
(
supportedResolution
==
null
)
{
supportedResolution
=
new
Size
(
/* width= */
0
,
/* height= */
0
);
}
capabilities
.
put
(
Util
.
formatInvariant
(
"supports_%dx%d"
,
width
,
height
),
(
supportedResolution
.
getWidth
()
==
width
&&
supportedResolution
.
getHeight
()
==
height
));
capabilities
.
put
(
Util
.
formatInvariant
(
"fallback_%dx%d"
,
width
,
height
),
sizeToString
(
supportedResolution
));
}
private
static
void
checkProfileLevelSupport
(
MediaCodecInfo
encoder
,
String
mimeType
,
Map
<
String
,
Object
>
capabilities
)
{
LinkedHashMap
<
String
,
String
>
profileToHighestSupportedLevel
=
new
LinkedHashMap
<>();
ImmutableSet
<
Integer
>
supportedEncodingProfiles
=
EncoderUtil
.
findSupportedEncodingProfiles
(
encoder
,
mimeType
);
for
(
int
profile
:
supportedEncodingProfiles
)
{
profileToHighestSupportedLevel
.
put
(
String
.
valueOf
(
profile
),
String
.
valueOf
(
EncoderUtil
.
findHighestSupportedEncodingLevel
(
encoder
,
mimeType
,
profile
)));
}
capabilities
.
put
(
"supported_profile_levels"
,
profileToHighestSupportedLevel
);
}
private
static
String
rangeToString
(
@Nullable
Range
<
Integer
>
range
)
{
return
range
==
null
?
"0-0"
:
Util
.
formatInvariant
(
"%d-%d"
,
range
.
getLower
(),
range
.
getUpper
());
}
private
static
String
sizeToString
(
@Nullable
Size
size
)
{
return
size
==
null
?
"0x0"
:
Util
.
formatInvariant
(
"%dx%d"
,
size
.
getWidth
(),
size
.
getHeight
());
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultEncoderFactory.java
View file @
61a20d5f
...
...
@@ -267,7 +267,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
MediaCodecInfo
pickedEncoder
=
filteredEncoders
.
get
(
0
);
int
closestSupportedBitrate
=
EncoderUtil
.
get
ClosestSupportedBitrate
(
pickedEncoder
,
mimeType
,
requestedBitrate
);
EncoderUtil
.
get
SupportedBitrateRange
(
pickedEncoder
,
mimeType
).
clamp
(
requestedBitrate
);
VideoEncoderSettings
.
Builder
supportedEncodingSettingBuilder
=
videoEncoderSettings
.
buildUpon
().
setBitrate
(
closestSupportedBitrate
);
...
...
@@ -320,7 +320,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
encoders
,
/* cost= */
(
encoderInfo
)
->
{
int
achievableBitrate
=
EncoderUtil
.
get
ClosestSupportedBitrate
(
encoderInfo
,
mimeType
,
requestedBitrate
);
EncoderUtil
.
get
SupportedBitrateRange
(
encoderInfo
,
mimeType
).
clamp
(
requestedBitrate
);
return
abs
(
achievableBitrate
-
requestedBitrate
);
},
/* filterName= */
"bitrate"
);
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/EncoderUtil.java
View file @
61a20d5f
...
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Assertions
.
checkNotNull
;
import
static
java
.
lang
.
Math
.
max
;
import
static
java
.
lang
.
Math
.
round
;
...
...
@@ -23,6 +24,8 @@ import android.media.MediaCodec;
import
android.media.MediaCodecInfo
;
import
android.media.MediaCodecList
;
import
android.media.MediaFormat
;
import
android.util.Pair
;
import
android.util.Range
;
import
android.util.Size
;
import
androidx.annotation.DoNotInline
;
import
androidx.annotation.Nullable
;
...
...
@@ -32,9 +35,12 @@ import com.google.android.exoplayer2.util.MediaFormatUtil;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.common.base.Ascii
;
import
com.google.common.base.Supplier
;
import
com.google.common.base.Suppliers
;
import
com.google.common.collect.ImmutableList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
com.google.common.collect.ImmutableListMultimap
;
import
com.google.common.collect.ImmutableSet
;
import
com.google.common.primitives.Ints
;
/** Utility methods for {@link MediaCodec} encoders. */
public
final
class
EncoderUtil
{
...
...
@@ -42,26 +48,47 @@ public final class EncoderUtil {
/** A value to indicate the encoding level is not set. */
public
static
final
int
LEVEL_UNSET
=
Format
.
NO_VALUE
;
private
static
final
List
<
MediaCodecInfo
>
encoders
=
new
ArrayList
<>();
private
static
final
Supplier
<
ImmutableListMultimap
<
String
,
MediaCodecInfo
>>
MIME_TYPE_TO_ENCODERS
=
Suppliers
.
memoize
(
EncoderUtil:
:
populateEncoderInfos
);
/**
* Returns a list of {@linkplain MediaCodecInfo encoders} that support the given {@code mimeType},
* or an empty list if there is none.
*/
public
static
ImmutableList
<
MediaCodecInfo
>
getSupportedEncoders
(
String
mimeType
)
{
maybePopulateEncoderInfos
();
ImmutableList
.
Builder
<
MediaCodecInfo
>
availableEncoders
=
new
ImmutableList
.
Builder
<>();
for
(
int
i
=
0
;
i
<
encoders
.
size
();
i
++)
{
MediaCodecInfo
encoderInfo
=
encoders
.
get
(
i
);
String
[]
supportedMimeTypes
=
encoderInfo
.
getSupportedTypes
();
for
(
String
supportedMimeType
:
supportedMimeTypes
)
{
if
(
Ascii
.
equalsIgnoreCase
(
supportedMimeType
,
mimeType
))
{
availableEncoders
.
add
(
encoderInfo
);
}
}
}
return
availableEncoders
.
build
();
return
checkNotNull
(
MIME_TYPE_TO_ENCODERS
.
get
()).
get
(
Ascii
.
toLowerCase
(
mimeType
));
}
/** Returns a list of video {@linkplain MimeTypes MIME types} that can be encoded. */
public
static
ImmutableSet
<
String
>
getSupportedVideoMimeTypes
()
{
return
checkNotNull
(
MIME_TYPE_TO_ENCODERS
.
get
()).
keySet
();
}
/**
* Returns a {@link Range} of supported heights for the given {@link MediaCodecInfo encoder},
* {@linkplain MimeTypes MIME type} and {@code width}.
*
* @throws IllegalArgumentException When the width is not in the range of {@linkplain
* #getSupportedResolutionRanges supported widths}.
*/
public
static
Range
<
Integer
>
getSupportedHeights
(
MediaCodecInfo
encoderInfo
,
String
mimeType
,
int
width
)
{
return
encoderInfo
.
getCapabilitiesForType
(
mimeType
)
.
getVideoCapabilities
()
.
getSupportedHeightsFor
(
width
);
}
/**
* Returns a {@link Pair} of supported width and height {@link Range ranges} for the given {@link
* MediaCodecInfo encoder} and {@linkplain MimeTypes MIME type}.
*/
public
static
Pair
<
Range
<
Integer
>,
Range
<
Integer
>>
getSupportedResolutionRanges
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
MediaCodecInfo
.
VideoCapabilities
videoCapabilities
=
encoderInfo
.
getCapabilitiesForType
(
mimeType
).
getVideoCapabilities
();
return
Pair
.
create
(
videoCapabilities
.
getSupportedWidths
(),
videoCapabilities
.
getSupportedHeights
());
}
/**
...
...
@@ -131,6 +158,22 @@ public final class EncoderUtil {
}
/**
* Returns a {@link ImmutableSet set} of supported {@linkplain MediaCodecInfo.CodecProfileLevel
* encoding profiles} for the given {@linkplain MediaCodecInfo encoder} and {@linkplain MimeTypes
* MIME type}.
*/
public
static
ImmutableSet
<
Integer
>
findSupportedEncodingProfiles
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
MediaCodecInfo
.
CodecProfileLevel
[]
profileLevels
=
encoderInfo
.
getCapabilitiesForType
(
mimeType
).
profileLevels
;
ImmutableSet
.
Builder
<
Integer
>
supportedProfilesBuilder
=
new
ImmutableSet
.
Builder
<>();
for
(
MediaCodecInfo
.
CodecProfileLevel
profileLevel
:
profileLevels
)
{
supportedProfilesBuilder
.
add
(
profileLevel
.
profile
);
}
return
supportedProfilesBuilder
.
build
();
}
/**
* Finds the highest supported encoding level given a profile.
*
* @param encoderInfo The {@link MediaCodecInfo encoderInfo}.
...
...
@@ -180,17 +223,10 @@ public final class EncoderUtil {
return
mediaCodecName
;
}
/**
* Finds the {@linkplain MediaCodecInfo encoder}'s closest supported bitrate from the given
* bitrate.
*/
public
static
int
getClosestSupportedBitrate
(
MediaCodecInfo
encoderInfo
,
String
mimeType
,
int
bitrate
)
{
return
encoderInfo
.
getCapabilitiesForType
(
mimeType
)
.
getVideoCapabilities
()
.
getBitrateRange
()
.
clamp
(
bitrate
);
/** Returns the range of supported bitrates for the given {@linkplain MimeTypes MIME type}. */
public
static
Range
<
Integer
>
getSupportedBitrateRange
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
return
encoderInfo
.
getCapabilitiesForType
(
mimeType
).
getVideoCapabilities
().
getBitrateRange
();
}
/** Returns whether the bitrate mode is supported by the encoder. */
...
...
@@ -202,6 +238,17 @@ public final class EncoderUtil {
.
isBitrateModeSupported
(
bitrateMode
);
}
/**
* Returns a {@link ImmutableList list} of supported {@linkplain
* MediaCodecInfo.CodecCapabilities#colorFormats color formats} for the given {@linkplain
* MediaCodecInfo encoder} and {@linkplain MimeTypes MIME type}.
*/
public
static
ImmutableList
<
Integer
>
getSupportedColorFormats
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
return
ImmutableList
.
copyOf
(
Ints
.
asList
(
encoderInfo
.
getCapabilitiesForType
(
mimeType
).
colorFormats
));
}
/** Checks if a {@linkplain MediaCodecInfo codec} is hardware-accelerated. */
public
static
boolean
isHardwareAccelerated
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
// TODO(b/214964116): Merge into MediaCodecUtil.
...
...
@@ -213,6 +260,18 @@ public final class EncoderUtil {
return
!
isSoftwareOnly
(
encoderInfo
,
mimeType
);
}
/** Returns whether a given feature is supported. */
public
static
boolean
isFeatureSupported
(
MediaCodecInfo
encoderInfo
,
String
mimeType
,
String
featureName
)
{
return
encoderInfo
.
getCapabilitiesForType
(
mimeType
).
isFeatureSupported
(
featureName
);
}
/** Returns the number of max number of the supported concurrent codec instances. */
@RequiresApi
(
23
)
public
static
int
getMaxSupportedInstances
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
return
encoderInfo
.
getCapabilitiesForType
(
mimeType
).
getMaxSupportedInstances
();
}
private
static
boolean
isSoftwareOnly
(
MediaCodecInfo
encoderInfo
,
String
mimeType
)
{
if
(
Util
.
SDK_INT
>=
29
)
{
return
Api29
.
isSoftwareOnly
(
encoderInfo
);
...
...
@@ -256,18 +315,25 @@ public final class EncoderUtil {
:
alignment
*
Math
.
round
((
float
)
size
/
alignment
);
}
private
static
synchronized
void
maybePopulateEncoderInfos
()
{
if
(
encoders
.
isEmpty
())
{
MediaCodecList
mediaCodecList
=
new
MediaCodecList
(
MediaCodecList
.
ALL_CODECS
);
MediaCodecInfo
[]
allCodecInfos
=
mediaCodecList
.
getCodecInfos
();
private
static
ImmutableListMultimap
<
String
,
MediaCodecInfo
>
populateEncoderInfos
()
{
ImmutableListMultimap
.
Builder
<
String
,
MediaCodecInfo
>
encoderInfosBuilder
=
new
ImmutableListMultimap
.
Builder
<>();
for
(
MediaCodecInfo
mediaCodecInfo
:
allCodecInfos
)
{
if
(!
mediaCodecInfo
.
isEncoder
())
{
continue
;
MediaCodecList
mediaCodecList
=
new
MediaCodecList
(
MediaCodecList
.
ALL_CODECS
);
MediaCodecInfo
[]
allCodecInfos
=
mediaCodecList
.
getCodecInfos
();
for
(
MediaCodecInfo
mediaCodecInfo
:
allCodecInfos
)
{
if
(!
mediaCodecInfo
.
isEncoder
())
{
continue
;
}
String
[]
supportedMimeTypes
=
mediaCodecInfo
.
getSupportedTypes
();
for
(
String
mimeType
:
supportedMimeTypes
)
{
if
(
MimeTypes
.
isVideo
(
mimeType
))
{
encoderInfosBuilder
.
put
(
Ascii
.
toLowerCase
(
mimeType
),
mediaCodecInfo
);
}
encoders
.
add
(
mediaCodecInfo
);
}
}
return
encoderInfosBuilder
.
build
();
}
@RequiresApi
(
29
)
...
...
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