Skip to content

Commit 9101b94

Browse files
authored
Merge pull request #44 from Parseus/dev
Dev -> master: version 2.8.0
2 parents a1e386e + 74387ce commit 9101b94

74 files changed

Lines changed: 637 additions & 244 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.idea/misc.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ plugins {
66

77
android {
88
namespace = 'com.parseus.codecinfo'
9-
compileSdk = 35
9+
compileSdk = 36
1010
defaultConfig {
1111
applicationId "com.parseus.codecinfo"
1212
minSdkVersion 21
13-
targetSdkVersion 35
14-
versionCode 26
15-
versionName "2.7.0"
13+
targetSdkVersion 36
14+
versionCode 27
15+
versionName "2.8.0"
1616
}
1717
buildTypes {
1818
debug {
@@ -74,6 +74,16 @@ android {
7474

7575
kotlin {
7676
jvmToolchain(17)
77+
78+
compilerOptions {
79+
freeCompilerArgs.addAll(
80+
"-Xjsr305=strict",
81+
"-Xemit-jvm-type-annotations",
82+
"-Xjvm-default=all",
83+
"-Xtype-enhancement-improvements-strict-mode",
84+
"-Xjspecify-annotations=strict"
85+
)
86+
}
7787
}
7888
packagingOptions {
7989
jniLibs {

app/src/main/assets/changelog.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
<html lang="en">
22
<body>
33

4+
<h2>Version 2.8.0</h2>
5+
<ul>
6+
<li>Added features from Android 16.</li>
7+
<li>Added profiles for the IAMF codec.</li>
8+
<li>Added more known codec and device issues.</li>
9+
<li>Added 1440p to listed framerate classes.</li>
10+
<li>(Android TV) Added a share functionality from the mobile version.</li>
11+
<li>Bugfixes and general improvements.</li>
12+
</ul>
13+
414
<h2>Version 2.7.0</h2>
515
<ul>
616
<li>Changed the way changelog is shown so it should load faster.</li>

app/src/main/java/com/parseus/codecinfo/data/codecinfo/CodecUtils.kt

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ private const val AC3_MAX_SAMPLE_RATE = 48000
4848
private const val GOOGLE_RAW_DECODER = "OMX.google.raw.decoder"
4949
private 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+
5155
private 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+
403428
private 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
461486
private 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
647672
private 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
*/
10291057
private 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 {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
@file:Suppress("unused")
2+
3+
package com.parseus.codecinfo.data.codecinfo.profilelevels
4+
5+
@Suppress("EnumEntryName")
6+
enum class IAMFProfiles(val value: Int) {
7+
8+
IAMFProfileSimpleOpus(0x01010001),
9+
IAMFProfileSimpleAac(0x01010002),
10+
IAMFProfileSimpleFlac(0x01010004),
11+
IAMFProfileSimplePcm(0x01010008),
12+
IAMFProfileBaseOpus(0x01020001),
13+
IAMFProfileBaseAac(0x01020002),
14+
IAMFProfileBaseFlac(0x01020004),
15+
IAMFProfileBasePcm(0x01020008),
16+
IAMFProfileBaseEnhancedOpus(0x01040001),
17+
IAMFProfileBaseEnhancedAac(0x01040002),
18+
IAMFProfileBaseEnhancedFlac(0x01040004),
19+
IAMFProfileBaseEnhancedPcm(0x01040008);
20+
21+
companion object {
22+
fun from(findValue: Int): String? = entries.find { it.value == findValue }?.name
23+
}
24+
25+
}

app/src/main/java/com/parseus/codecinfo/data/drm/DrmUtils.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,23 @@ fun getDetailedDrmInfo(context: Context, uuid: UUID, drmVendor: DrmVendor?): Lis
7878
if (Build.VERSION.SDK_INT >= 28) {
7979
val connectedHdcpLevel = try {
8080
mediaDrm.connectedHdcpLevel
81-
} catch (e: Exception) {
81+
} catch (_: Exception) {
8282
MediaDrm.HDCP_LEVEL_UNKNOWN
8383
}
8484
addReadableHdcpLevel(context, connectedHdcpLevel,
8585
context.getString(R.string.drm_property_hdcp_level), drmPropertyList)
8686

8787
val maxHdcpLevel = try {
8888
mediaDrm.maxHdcpLevel
89-
} catch (e: Exception) {
89+
} catch (_: Exception) {
9090
MediaDrm.HDCP_LEVEL_UNKNOWN
9191
}
9292
addReadableHdcpLevel(context, maxHdcpLevel,
9393
context.getString(R.string.drm_property_max_hdcp_level), drmPropertyList)
9494

9595
val maxSessionCount = try {
9696
mediaDrm.maxSessionCount
97-
} catch (e: Exception) {
97+
} catch (_: Exception) {
9898
0
9999
}
100100
if (maxSessionCount > 0) {
@@ -162,7 +162,7 @@ private fun getDrmDescriptionFromUuid(uuid: UUID, context: Context) = try {
162162
mediaDrm.closeDrmInstance()
163163

164164
drmName
165-
} catch (t: Throwable) {
165+
} catch (_: Throwable) {
166166
context.getString(R.string.unknown)
167167
}
168168

app/src/main/java/com/parseus/codecinfo/data/drm/DrmVendor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ enum class DrmVendor(val uuid: UUID,
7676

7777
val WIDEVINE_BYTE_ARRAY_PROPERTIES = mapOf(
7878
R.string.drm_property_provisioning_id to "provisioningUniqueId",
79-
R.string.drm_property_service_certificate to "serviceCertificate"
79+
R.string.drm_property_service_certificate to "serviceCertificate",
80+
R.string.drm_property_provisioning_service_certificate to "provisioningServiceCertificate",
81+
R.string.drm_property_metrics to "metrics"
8082
)
8183
}
8284

app/src/main/java/com/parseus/codecinfo/data/knownproblems/KnownProblem.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ data class KnownProblem(
3434
hardwares?.forEach {
3535
if ((it.op == "equals" && hardware == it.value)
3636
|| (it.op == "startsWith" && hardware.startsWith(it.value))) {
37-
hardwareAffected = Build.HARDWARE.equals(it.value, true)
37+
hardwareAffected = hardware.equals(it.value, true)
3838
}
3939

4040
// Second case: devices that have no additional version requirement.
@@ -79,16 +79,16 @@ data class KnownProblem(
7979
}
8080
}
8181

82+
var socModelAffected = false
8283
if (Build.VERSION.SDK_INT >= 31) {
8384
val socModel = Build.SOC_MODEL
84-
var socModelAffected = false
8585
socModels?.forEach {
8686
if ((it.op == "equals" && socModel == it.value)
8787
|| (it.op == "startsWith" && socModel.startsWith(it.value))) {
88-
socModelAffected = Build.HARDWARE.equals(it.value, true)
88+
socModelAffected = socModel.equals(it.value, true)
8989
}
9090

91-
// Fifth case: SoC models that have no additional version requirement.
91+
// Fifth case: SoCs that have no additional version requirement.
9292
if (socModelAffected && versions == null) {
9393
return true
9494
}
@@ -115,11 +115,13 @@ data class KnownProblem(
115115
}
116116

117117
if (((devices != null && deviceAffected) || (models != null && modelAffected)
118-
|| (hardwares != null && hardwareAffected)) && versionAffected) {
119-
// Fifth case: both device/model/hardware and version match.
118+
|| (hardwares != null && hardwareAffected) || (socModels != null && socModelAffected))
119+
&& versionAffected) {
120+
// Sixth case: both device/model/hardware/SoC and version match.
120121
return true
121-
} else if (devices == null && models == null && versionAffected) {
122-
// Sixth case: version matches regardless of the device/model/hardware.
122+
} else if (devices == null && models == null && hardwares == null && socModels == null
123+
&& versionAffected) {
124+
// Seventh case: version matches regardless of the device/model/hardware/SoC.
123125
return true
124126
}
125127
}

app/src/main/java/com/parseus/codecinfo/utils/Extensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,5 @@ fun MediaCodecInfo.isAudioCodec(): Boolean {
6464
return supportedTypes.joinToString().contains("audio")
6565
}
6666

67-
tailrec fun Context.getActivity(): Activity? = this as? Activity
67+
fun Context.getActivity(): Activity? = this as? Activity
6868
?: (this as? ContextWrapper)?.baseContext?.getActivity()

app/src/mobile/java/com/parseus/codecinfo/utils/ShareUtils.kt renamed to app/src/main/java/com/parseus/codecinfo/utils/ShareUtils.kt

File renamed without changes.

0 commit comments

Comments
 (0)