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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user