Browse Source

Add cross-device decoding to the explicit debug video probe

master
evgeny 5 days ago
parent
commit
5d115c3dac
  1. 24
      tools/chatgui-android/app/src/debug/java/com/utun/chat/data/CallVideoProbe.kt
  2. 2
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt

24
tools/chatgui-android/app/src/debug/java/com/utun/chat/data/CallVideoProbe.kt

@ -5,10 +5,23 @@ import android.os.Bundle
/** Запускается только явно через adb am instrument; камера и реальные звонки не затрагиваются. */
class CallVideoProbe : Instrumentation() {
override fun onCreate(arguments: Bundle?) { super.onCreate(arguments); start() }
private var remote: String? = null
override fun onCreate(arguments: Bundle?) { remote = arguments?.getString("remote"); super.onCreate(arguments); start() }
override fun onStart() {
try {
val decoders = CallVideoCodec.probeDecoders()
remote?.let { name ->
require(name.startsWith("call-video-") && '/' !in name)
val codec = if (name.endsWith("-codec1.idr")) 1 else 2
val bytes = java.io.File(targetContext.filesDir, name).readBytes()
val actual = checkNotNull(CallVideoNative.inspect(codec, bytes))
val format = CallVideoFormat(1, actual[0].toInt(), actual[1].toInt(), codec = codec,
level = actual[2].toInt(), profile = actual[3].toInt())
val decoder = checkNotNull(decoders[codec])
CallVideoCodec.verifyDecode(format, List(4) { CallVideoCodec.Packet(1_000_000L + it * 33333, true, bytes) }, decoder.name)
finish(0, Bundle().apply { putString("remote_decoded", "$name using ${decoder.name} format=$format") })
return
}
val codecs = CallVideoCodec.probe()
check(codecs.isNotEmpty() && decoders.isNotEmpty()) { "No verified encoders or decoders" }
for ((codec, entry) in codecs) {
@ -16,6 +29,15 @@ class CallVideoProbe : Instrumentation() {
for (rate in listOf(4_000_000, 300_000, 4_000_000)) {
CallVideoCodec(f, rate, entry.name).use { it.prepare() }
}
CallVideoCodec(f, 1_000_000, entry.name).use { encoder ->
encoder.prepare(); var key: ByteArray? = null; var input = 0
val deadline = System.nanoTime() + 3_000_000_000
while (key == null && System.nanoTime() < deadline) {
if (input < 8 && encoder.submit(null, 10_000_000L + input * 33333, input == 0)) input++
key = encoder.drain().firstOrNull { it.key }?.bytes; Thread.sleep(2)
}
java.io.File(targetContext.filesDir, "call-video-local-codec$codec.idr").writeBytes(checkNotNull(key))
}
}
finish(0, Bundle().apply { putString("codecs", codecs.toString()); putString("decoders", decoders.toString()) })
} catch (e: Exception) {

2
tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt

@ -192,7 +192,7 @@ internal class CallVideoCodec(requested: CallVideoFormat, val bitrate: Int, val
}
return result
}
private fun verifyDecode(f: CallVideoFormat, packets: List<Packet>, name: String) {
internal fun verifyDecode(f: CallVideoFormat, packets: List<Packet>, name: String) {
val type = StreamVideoCodec.fromId(f.codec)
val config = type.unpackKey(packets.first().bytes).first
val decoder = MediaCodec.createByCodecName(name)

Loading…
Cancel
Save