fix(android): don't letterbox against the configure placeholder

H264Decoder.outputSize() reported the 320x240 configure() placeholder
until the codec parsed the in-band SPS, so fitVideo sized the view to
1488x1116 (1.33 aspect) and the first rendered frame(s) of 2.4 content
were visibly squished before the real size corrected it ~40ms later.
Report no size until INFO_OUTPUT_FORMAT_CHANGED delivers the real one:
the first frame renders into the fullscreen surface and the correct
letterbox follows immediately. Validated live on the Fairphone 6 (the
placeholder 'video size' line is gone from logcat; 25/25 JVM tests).
This commit is contained in:
2026-09-10 12:36:15 +02:00
parent 9a24933203
commit 4f93c7cd20
2 changed files with 21 additions and 1 deletions
@@ -18,6 +18,11 @@ class H264Decoder {
private var codec: MediaCodec? = null
private var configured = false
// True once the codec parsed the in-band SPS (INFO_OUTPUT_FORMAT_CHANGED).
// Before that, outputFormat still carries the configure() placeholder and
// must not drive layout — sizing the view to it squishes the first frame(s).
@Volatile
private var realFormatSeen = false
@Volatile
private var renderSurface: Surface? = null
@@ -57,6 +62,7 @@ class H264Decoder {
throw e
}
configured = true
realFormatSeen = false
}
/** Points the decoder at a (possibly new) render surface. */
@@ -117,6 +123,7 @@ class H264Decoder {
}
index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED -> {
// The codec parsed the SPS size; outputFormat is ready.
realFormatSeen = true
android.util.Log.i(
"H264Decoder", "output format: " +
c.outputFormat.getInteger(MediaFormat.KEY_WIDTH) +
@@ -141,10 +148,11 @@ class H264Decoder {
}
}
/** The decoded resolution once the first keyframe has configured the codec. */
/** The decoded resolution, once the first keyframe configured the codec. */
@Synchronized
fun outputSize(): Pair<Int, Int>? {
val c = codec ?: return null
if (!realFormatSeen) return null // still the configure() placeholder
return try {
val format = c.outputFormat
val width = format.getInteger(MediaFormat.KEY_WIDTH)