@@ -48,6 +48,10 @@ private const val AC3_MAX_SAMPLE_RATE = 48000
4848private const val GOOGLE_RAW_DECODER = " OMX.google.raw.decoder"
4949private const val MEDIATEK_RAW_DECODER = " OMX.MTK.AUDIO.DECODER.RAW"
5050
51+ // Source:
52+ // https://android.googlesource.com/platform/frameworks/base/+/master/media/java/android/media/MediaCodecInfo.java#1883
53+ private const val SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2
54+
5155private val incorrectMpeg4ResolutionModelList = listOf (
5256 " Nokia 1" ,
5357 " moto c" ,
@@ -78,6 +82,7 @@ private val framerateResolutions = arrayOf(
7882 intArrayOf(720 , 576 ),
7983 intArrayOf(1280 , 720 ),
8084 intArrayOf(1920 , 1080 ),
85+ intArrayOf(2560 , 1440 ),
8186 intArrayOf(3840 , 2160 ),
8287 intArrayOf(7680 , 4320 )
8388)
@@ -89,6 +94,7 @@ private val framerateClasses = arrayOf(
8994 " 576p" ,
9095 " 720p" ,
9196 " 1080p" ,
97+ " 1440p" ,
9298 " 4K" ,
9399 " 8K"
94100)
@@ -122,7 +128,7 @@ fun getSimpleCodecInfoList(context: Context, isAudio: Boolean): MutableList<Code
122128 if (mediaCodecInfos.isEmpty()) {
123129 mediaCodecInfos = try {
124130 MediaCodecList (MediaCodecList .ALL_CODECS ).codecInfos
125- } catch (e : Exception ) {
131+ } catch (_ : Exception ) {
126132 // Some devices (like Xiaomi Redmi Note 4) seem to
127133 // throw an exception when trying to list codecs.
128134 // Return an empty list to inform the user abput it.
@@ -171,7 +177,7 @@ fun getSimpleCodecInfoList(context: Context, isAudio: Boolean): MutableList<Code
171177 mediaCodecInfo.supportedTypes.forEachIndexed{ index, codecId ->
172178 try {
173179 mediaCodecInfo.getCapabilitiesForType(codecId)
174- } catch (e : Exception ) {
180+ } catch (_ : Exception ) {
175181 // Some devices (e.g. Kindle Fire HD) can report a codec in the supported list
176182 // but don't really implement it (or it's buggy). In this case just skip this.
177183 return @forEachIndexed
@@ -199,7 +205,7 @@ fun getSimpleCodecInfoList(context: Context, isAudio: Boolean): MutableList<Code
199205
200206 val sortType = try {
201207 prefs.getString(" sort_type" , " 0" )!! .toInt()
202- } catch (e : Exception ) {
208+ } catch (_ : Exception ) {
203209 prefs.getInt(" sort_type" , 0 )
204210 }
205211 val comparator: Comparator <CodecSimpleInfo > = when (sortType) {
@@ -274,6 +280,10 @@ fun getDetailedCodecInfo(context: Context, codecId: String, codecName: String):
274280 capabilities.maxSupportedInstances.toString()))
275281 }
276282
283+ if (SDK_INT >= 36 ) {
284+ addSecurityModel(context, mediaCodecInfo, propertyList)
285+ }
286+
277287 if (isAudio) {
278288 getAudioCapabilities(context, codecId, codecName, capabilities, propertyList)
279289 } else {
@@ -324,7 +334,7 @@ fun getDetailedCodecInfo(context: Context, codecId: String, codecName: String):
324334 }
325335
326336 if (isEncoder) {
327- val encoderCapabilities = capabilities.encoderCapabilities
337+ val encoderCapabilities = capabilities.encoderCapabilities!!
328338 var bitrateModesString =
329339 " ${context.getString(R .string.cbr)} : " +
330340 " ${encoderCapabilities.isBitrateModeSupported(MediaCodecInfo .EncoderCapabilities .BITRATE_MODE_CBR )} " +
@@ -357,7 +367,8 @@ fun getDetailedCodecInfo(context: Context, codecId: String, codecName: String):
357367 } catch (_: Throwable ) {}
358368 }
359369
360- val profileString = if (codecId.contains(" mp4a-latm" ) || codecId.contains(" wma" )) {
370+ val profileString = if (codecId.contains(" mp4a-latm" ) || codecId.contains(" wma" )
371+ || codecId.contains(" iamf" )) {
361372 context.getString(R .string.profiles)
362373 } else {
363374 context.getString(R .string.profile_levels)
@@ -400,6 +411,20 @@ private fun addLowLatencyFeatureIfSupported(context: Context,
400411 }
401412}
402413
414+ @SuppressLint(" SwitchIntDef" )
415+ @RequiresApi(36 )
416+ private fun addSecurityModel (context : Context , codecInfo : MediaCodecInfo ,
417+ propertyList : MutableList <DetailsProperty >) {
418+ val securityModelString = when (val securityModel = codecInfo.securityModel) {
419+ MediaCodecInfo .SECURITY_MODEL_SANDBOXED -> context.getString(R .string.security_model_sandboxed)
420+ MediaCodecInfo .SECURITY_MODEL_MEMORY_SAFE -> context.getString(R .string.security_model_memory_safe)
421+ SECURITY_MODEL_TRUSTED_CONTENT_ONLY -> context.getString(R .string.security_model_trusted_content_only)
422+ else -> " ${context.getString(R .string.unknown)} ($securityModel )"
423+ }
424+ propertyList.add(DetailsProperty (propertyList.size.toLong(),
425+ context.getString(R .string.security_model), securityModelString))
426+ }
427+
403428private fun handleQualityRange (encoderCapabilities : MediaCodecInfo .EncoderCapabilities ,
404429 defaultMediaFormat : MediaFormat ,
405430 propertyList : MutableList <DetailsProperty >,
@@ -413,7 +438,7 @@ private fun handleQualityRange(encoderCapabilities: MediaCodecInfo.EncoderCapabi
413438 val qualityRangeMethod = encoderCapabilities::class .java
414439 .getDeclaredMethod(" getQualityRange" )
415440 qualityRangeMethod.invoke(encoderCapabilities) as Range <Int >
416- } catch (e : Exception ) {
441+ } catch (_ : Exception ) {
417442 null
418443 }
419444 }
@@ -461,7 +486,7 @@ private fun handleComplexityRange(encoderCapabilities: MediaCodecInfo.EncoderCap
461486private fun getAudioCapabilities (context : Context , codecId : String , codecName : String ,
462487 capabilities : MediaCodecInfo .CodecCapabilities ,
463488 propertyList : MutableList <DetailsProperty >) {
464- val audioCapabilities = capabilities.audioCapabilities
489+ val audioCapabilities = capabilities.audioCapabilities!!
465490
466491 var minChannelCount = 1
467492 val maxChannelCount = adjustMaxInputChannelCount(codecId, codecName,
@@ -647,7 +672,7 @@ private fun adjustMaxInputChannelCount(codecId: String, codecName: String, maxCh
647672private fun getVideoCapabilities (context : Context , codecId : String , codecName : String ,
648673 capabilities : MediaCodecInfo .CodecCapabilities ,
649674 propertyList : MutableList <DetailsProperty >) {
650- val videoCapabilities = capabilities.videoCapabilities
675+ val videoCapabilities = capabilities.videoCapabilities!!
651676
652677 val maxResolution = getMaxResolution(codecId, videoCapabilities)
653678 propertyList.add(DetailsProperty (propertyList.size.toLong(),
@@ -909,6 +934,9 @@ private fun getProfileLevels(context: Context, codecId: String, codecName: Strin
909934 profile = HEVCProfiles .from(it.profile)
910935 level = HEVCLevels .from(it.level)
911936 }
937+ codecId.contains(" iamf" ) -> {
938+ profile = IAMFProfiles .from(it.profile)
939+ }
912940 codecId.endsWith(" mpeg" ) || codecId.contains(" mpeg2" ) -> {
913941 var extension = " "
914942
@@ -1027,7 +1055,7 @@ private fun MutableList<DetailsProperty>.addFeature(context: Context,
10271055 * Needed on M and older to get correct information about VP9 support.
10281056 */
10291057private fun getMaxVP9ProfileLevel (capabilities : MediaCodecInfo .CodecCapabilities ): Int {
1030- val maxBitrate = capabilities.videoCapabilities.bitrateRange.upper
1058+ val maxBitrate = capabilities.videoCapabilities!! .bitrateRange.upper
10311059
10321060 // https://www.webmproject.org/vp9/levels
10331061 return when {
0 commit comments