diff --git a/tools/chatgui-android/app/src/debug/java/com/utun/chat/data/CallVideoProbe.kt b/tools/chatgui-android/app/src/debug/java/com/utun/chat/data/CallVideoProbe.kt index 8ee5b4c9..0c7a7fdc 100644 --- a/tools/chatgui-android/app/src/debug/java/com/utun/chat/data/CallVideoProbe.kt +++ b/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) { diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt index a09299ab..e889bdf3 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt +++ b/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, name: String) { + internal fun verifyDecode(f: CallVideoFormat, packets: List, name: String) { val type = StreamVideoCodec.fromId(f.codec) val config = type.unpackKey(packets.first().bytes).first val decoder = MediaCodec.createByCodecName(name)