Skip to content

Commit 4cfc0d3

Browse files
author
Krzysztof Nawrot
authored
Merge pull request #29 from Parseus/dev
Dev -> master: version 2.6.0
2 parents 6a9ef57 + b06fffb commit 4cfc0d3

62 files changed

Lines changed: 716 additions & 159 deletions

Some content is hidden

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

.idea/gradle.xml

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/Project_Default.xml

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

.idea/migrations.xml

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

TODO.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Missing color formats
2+
- OMX.IMG.VIDEO.TOPAZ.Encoder - color formats 0x7F000005-12 (although 1-3 are probably incorrect, too)
3+
- MediaTek S900/MT9950 - 0x7F000101-3

app/build.gradle

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
plugins {
2-
id 'com.android.application'
3-
id 'org.jetbrains.kotlin.android'
4-
id 'com.google.devtools.ksp' version '1.9.10-1.0.13'
2+
alias libs.plugins.agp
3+
alias libs.plugins.kotlin
4+
alias libs.plugins.ksp
55
}
66

77
android {
@@ -11,8 +11,8 @@ android {
1111
applicationId "com.parseus.codecinfo"
1212
minSdkVersion 21
1313
targetSdkVersion 34
14-
versionCode 24
15-
versionName "2.5.1"
14+
versionCode 25
15+
versionName "2.6.0"
1616
resConfigs 'en'
1717
}
1818
buildTypes {
@@ -26,9 +26,17 @@ android {
2626
minifyEnabled true
2727
shrinkResources true
2828
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
29+
30+
packagingOptions {
31+
resources.excludes += "DebugProbesKt.bin"
32+
}
2933
}
3034
}
3135

36+
buildFeatures {
37+
buildConfig = true
38+
}
39+
3240
flavorDimensions = ["app", "platform"]
3341

3442
productFlavors {
@@ -91,36 +99,36 @@ configurations {
9199
}
92100

93101
dependencies {
94-
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
95-
96-
implementation 'androidx.appcompat:appcompat:1.7.0-alpha03'
97-
implementation "androidx.core:core-ktx:1.12.0"
98-
implementation 'androidx.fragment:fragment-ktx:1.7.0-alpha04'
99-
implementation 'androidx.preference:preference-ktx:1.2.1'
100-
implementation 'androidx.recyclerview:recyclerview:1.3.1'
101-
102-
implementation "com.squareup.leakcanary:plumber-android:$leakCanary_version"
103-
implementation "com.squareup.moshi:moshi:$moshi_version"
104-
ksp "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
105-
implementation "com.squareup.okio:okio:3.5.0"
106-
107-
debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakCanary_version"
108-
109-
tvImplementation 'androidx.leanback:leanback:1.2.0-alpha03'
110-
tvImplementation 'androidx.leanback:leanback-preference:1.2.0-alpha03'
111-
112-
standardMobileImplementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3'
113-
114-
mobileImplementation 'androidx.constraintlayout:constraintlayout:2.1.4'
115-
mobileImplementation 'androidx.core:core-splashscreen:1.1.0-alpha02'
116-
mobileImplementation 'androidx.palette:palette-ktx:1.0.0'
117-
mobileImplementation 'androidx.webkit:webkit:1.8.0'
118-
mobileImplementation 'com.github.KieronQuinn:MonetCompat:0.4.1'
119-
mobileImplementation 'com.github.marcoscgdev:Licenser:2.0.0'
120-
mobileImplementation 'com.google.android.material:material:1.11.0-alpha02'
121-
122-
nonFreeMobileImplementation 'com.google.android.play:app-update:2.1.0'
123-
nonFreeMobileImplementation 'com.google.android.play:app-update-ktx:2.1.0'
124-
nonFreeMobileImplementation 'com.google.android.play:review:2.0.1'
125-
nonFreeMobileImplementation 'com.google.android.play:review-ktx:2.0.1'
102+
implementation libs.coroutines
103+
104+
implementation libs.androidx.appcompat
105+
implementation libs.androidx.core
106+
implementation libs.androidx.fragment
107+
implementation libs.androidx.preference
108+
implementation libs.androidx.recyclerview
109+
110+
implementation libs.plumber.android
111+
implementation libs.moshi
112+
ksp libs.moshi.codegen
113+
implementation libs.okio
114+
115+
debugImplementation libs.leakcanary.android
116+
117+
tvImplementation libs.androidx.leanback
118+
tvImplementation libs.androidx.leanback.preference
119+
120+
standardMobileImplementation libs.hiddenapibypass
121+
122+
mobileImplementation libs.androidx.constraintlayout
123+
mobileImplementation libs.androidx.core.splashscreen
124+
mobileImplementation libs.androidx.palette
125+
mobileImplementation libs.androidx.webkit
126+
mobileImplementation libs.monetcompat
127+
mobileImplementation libs.licenser
128+
mobileImplementation libs.material
129+
130+
nonFreeMobileImplementation libs.app.update
131+
nonFreeMobileImplementation libs.app.update.ktx
132+
nonFreeMobileImplementation libs.review
133+
nonFreeMobileImplementation libs.review.ktx
126134
}

app/proguard-rules.pro

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
2-
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
2+
public static void checkExpressionValueIsNotNull(java.lang.Object, java.lang.String);
3+
public static void checkFieldIsNotNull(java.lang.Object, java.lang.String);
4+
public static void checkFieldIsNotNull(java.lang.Object, java.lang.String, java.lang.String);
5+
public static void checkNotNull(java.lang.Object);
6+
public static void checkNotNull(java.lang.Object, java.lang.String);
7+
public static void checkNotNullExpressionValue(java.lang.Object, java.lang.String);
8+
public static void checkNotNullParameter(java.lang.Object, java.lang.String);
9+
public static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
10+
public static void checkReturnedValueIsNotNull(java.lang.Object, java.lang.String);
11+
public static void checkReturnedValueIsNotNull(java.lang.Object, java.lang.String, java.lang.String);
312
}
413

514
-keepattributes SourceFile, LineNumberTable

app/src/main/assets/changelog.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
<html>
22
<body>
33

4+
<h2>Version 2.6.0</h2>
5+
<p>Added an option to save info for a selected codec/DRM to Logcat.</p>
6+
<p>Added querying for a resource rating tier and decrypt hash function for Widevine.</p>
7+
<p>Added more known codec and device issues.</p>
8+
<p>Added 12 more color formats from Samsung.</p>
9+
<p>Viewing info for an already seen codec/DRM should be much faster now.</p>
10+
<p>Improved reporting of the max resolution for codecs on devices that underreport it.</p>
11+
<p>Bugfixes and general improvements.</p>
12+
413
<h2>Version 2.5.1</h2>
514
<p>Removed support for Android 4.4 and older.</p>
615
<p>Removed support for legacy gestures on a few very old Samsung phones.</p>

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

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import android.media.MediaCodecList
1010
import android.media.MediaFormat
1111
import android.os.Build
1212
import android.os.Build.VERSION.SDK_INT
13+
import android.util.Log
1314
import android.util.Range
1415
import androidx.annotation.RequiresApi
1516
import androidx.annotation.StringRes
@@ -46,6 +47,14 @@ private const val AC3_MAX_SAMPLE_RATE = 48000
4647
private const val GOOGLE_RAW_DECODER = "OMX.google.raw.decoder"
4748
private const val MEDIATEK_RAW_DECODER = "OMX.MTK.AUDIO.DECODER.RAW"
4849

50+
private val incorrectMpeg4ResolutionModelList = listOf(
51+
"Nokia 1",
52+
"moto c",
53+
"infinix x650",
54+
"LG-X230",
55+
"twist 2 pro"
56+
)
57+
4958
private val platformSupportedTypes = arrayOf(
5059
"audio/3gpp",
5160
"audio/amr-mb",
@@ -98,6 +107,7 @@ private var mediaCodecInfos: Array<MediaCodecInfo> = emptyArray()
98107
val audioCodecList: MutableList<CodecSimpleInfo> = mutableListOf()
99108
val videoCodecList: MutableList<CodecSimpleInfo> = mutableListOf()
100109

110+
val detailedCodecInfos: MutableMap<String, List<DetailsProperty>> = mutableMapOf()
101111

102112
fun getSimpleCodecInfoList(context: Context, isAudio: Boolean): MutableList<CodecSimpleInfo> {
103113
if (isAudio && audioCodecList.isNotEmpty()) {
@@ -209,7 +219,19 @@ fun getSimpleCodecInfoList(context: Context, isAudio: Boolean): MutableList<Code
209219
return codecSimpleInfoList
210220
}
211221

222+
fun isDetailedCodecInfoCached(codecId: String, codecName: String): Boolean {
223+
val combinedCodecName = "$codecId/$codecName"
224+
return detailedCodecInfos[combinedCodecName] != null
225+
}
226+
212227
fun getDetailedCodecInfo(context: Context, codecId: String, codecName: String): List<DetailsProperty> {
228+
val combinedCodecName = "$codecId/$codecName"
229+
if (detailedCodecInfos[combinedCodecName] != null) {
230+
return detailedCodecInfos[combinedCodecName]!!.also {
231+
saveToLogcat(context, codecId, codecName, it)
232+
}
233+
}
234+
213235
val mediaCodecInfo = mediaCodecInfos.find { it.name == codecName } ?: return emptyList()
214236

215237
// Google uses the same decoder for both DP and non-DP content for MPEG-4,
@@ -335,7 +357,11 @@ fun getDetailedCodecInfo(context: Context, codecId: String, codecName: String):
335357
propertyList.add(DetailsProperty(propertyList.size.toLong(), profileString, it))
336358
}
337359

338-
return propertyList
360+
detailedCodecInfos[combinedCodecName] = propertyList
361+
362+
return propertyList.also {
363+
saveToLogcat(context, codecId, codecName, it)
364+
}
339365
}
340366

341367
@RequiresApi(30)
@@ -698,12 +724,17 @@ private fun getMaxResolution(codecId: String, videoCapabilities: MediaCodecInfo.
698724
// capabilities. The supported height reported for H265@3840x2160 is 2144,
699725
// and H264@1920x1080 is 1072.
700726
// Cross reference with CamcorderProfile to ensure a resolution is supported.
727+
// Several other devices also indicate a wrong resolution (174x174) for MPEG-4 SP.
728+
// On Huawei Mate 9, HEVC reports only H265@3840x2112 instead of full 4K.
701729
if (maxHeight == 1072 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {
702730
defaultResolution[0] = 1920
703731
defaultResolution[1] = 1080
704-
} else if (maxHeight == 2144 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)) {
732+
} else if ((maxHeight == 2144 || (maxHeight == 2112 && Build.MODEL == "mha-l29")) && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)) {
705733
defaultResolution[0] = 3840
706734
defaultResolution[1] = 2160
735+
} else if (needsMaxResolutionFixForMPEG4(codecId)) {
736+
defaultResolution[0] = 1280
737+
defaultResolution[1] = 720
707738
}
708739

709740
return if (!areCapabilitiesUnknown(videoCapabilities)) {
@@ -760,20 +791,35 @@ private fun getFrameRatePerResolutions(context: Context, codecId: String,
760791
return@forEachIndexed
761792
}
762793

763-
if (videoCapabilities.isSizeSupported(resolution[0], resolution[1])) {
764-
maxFrameRate = getSupportedFrameRatesFor(codecId, videoCapabilities, resolution[0], resolution[1]).upper
794+
try {
795+
if (isSizeSupported(videoCapabilities, resolution[0], resolution[1])) {
796+
maxFrameRate = getSupportedFrameRatesFor(codecId, videoCapabilities, resolution[0], resolution[1]).upper
765797

766-
if (option == 0) {
767-
capabilities.append("${framerateClasses[index]}: ${"%.1f".format(maxFrameRate)} $fpsString\n")
768-
} else {
769-
capabilities.append("${resolution[0]}x${resolution[1]}: ${"%.1f".format(maxFrameRate)} $fpsString\n")
798+
if (option == 0) {
799+
capabilities.append("${framerateClasses[index]}: ${"%.1f".format(maxFrameRate)} $fpsString\n")
800+
} else {
801+
capabilities.append("${resolution[0]}x${resolution[1]}: ${"%.1f".format(maxFrameRate)} $fpsString\n")
802+
}
770803
}
771-
}
804+
} catch (_: Throwable) {}
772805
}
773806

774807
return capabilities.toString().dropLast(1) // Remove the last \n
775808
}
776809

810+
private fun isSizeSupported(videoCapabilities: MediaCodecInfo.VideoCapabilities, width: Int, height: Int): Boolean {
811+
if (videoCapabilities.isSizeSupported(width, height)) return true
812+
813+
if (width == 1920 && height == 1080) {
814+
return CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)
815+
}
816+
if (width == 3840 && height == 2160) {
817+
return CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)
818+
}
819+
820+
return false
821+
}
822+
777823
@SuppressLint("NewApi")
778824
private fun getProfileLevels(context: Context, codecId: String, codecName: String,
779825
capabilities: MediaCodecInfo.CodecCapabilities): String? {
@@ -1064,4 +1110,15 @@ private fun needsHevc10BitProfileExcluded(codecId: String, profile: Int): Boolea
10641110
// See https://github.com/google/ExoPlayer/issues/3537 for more info.
10651111
return "video/hevc" == codecId && HEVCProfiles.HEVCProfileMain10.value == profile
10661112
&& ("sailfish" == Build.DEVICE || "marlin" == Build.DEVICE)
1113+
}
1114+
1115+
private fun needsMaxResolutionFixForMPEG4(codecId: String) = "video/mp4v-es" == codecId && Build.MODEL in incorrectMpeg4ResolutionModelList
1116+
1117+
private fun saveToLogcat(context: Context, codecId: String, codecName: String, detailsList: List<DetailsProperty>) {
1118+
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
1119+
val saveDetailsToLogcat = prefs.getBoolean("save_details_to_logcat", false)
1120+
if (saveDetailsToLogcat) {
1121+
Log.i("CodecUtils", "Codec MIME type: $codecId, codec name: $codecName")
1122+
Log.i("CodecUtils", detailsList.joinToString("\n"))
1123+
}
10671124
}

app/src/main/java/com/parseus/codecinfo/data/codecinfo/colorformats/BroadcomColorFormat.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ enum class BroadcomColorFormat(val value: Int) {
3535
OMX_COLOR_FormatRawGrey14bit16bpp(0x7F00001D);
3636

3737
companion object {
38-
fun from(findValue: Int) = values().find { it.value == findValue }?.name
38+
fun from(findValue: Int) = entries.find { it.value == findValue }?.name
3939
}
4040

4141
}

app/src/main/java/com/parseus/codecinfo/data/codecinfo/colorformats/IMGColorFormat.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ enum class IMGColorFormat(val value: Int) {
1010
OMX_COLOR_FormatCMYK(0x7F000004);
1111

1212
companion object {
13-
fun from(findValue: Int) = values().find { it.value == findValue }?.name
13+
fun from(findValue: Int) = entries.find { it.value == findValue }?.name
1414
}
1515

1616
}

0 commit comments

Comments
 (0)