@@ -194,26 +194,32 @@ class AvcServer(private val bitrate: Int, private val scale: Float, private val
194194
195195 private fun streamAvcFrames () {
196196 val displayInfo = DisplayUtils .getDisplayInfo()
197- val scaledWidth = (displayInfo.width * scale).toInt()
198- val scaledHeight = (displayInfo.height * scale).toInt()
197+
198+ // Check codec capabilities before attempting to configure
199+ val codec = MediaCodec .createEncoderByType(MediaFormat .MIMETYPE_VIDEO_AVC )
200+ val codecInfo = codec.codecInfo
201+ val capabilities = codecInfo.getCapabilitiesForType(MediaFormat .MIMETYPE_VIDEO_AVC )
202+ val videoCapabilities = capabilities.videoCapabilities
203+
204+ // H.264 encoders only accept dimensions that are a multiple of their
205+ // alignment (usually 2). A raw (display * scale).toInt() can be odd —
206+ // e.g. Pixel 10 Pro's 2410-high display at scale 0.5 gives 1205 — and
207+ // isSizeSupported() then rejects the size outright, killing the stream.
208+ // Round each dimension down to the codec's alignment.
209+ val widthAlign = maxOf(videoCapabilities.widthAlignment, 2 )
210+ val heightAlign = maxOf(videoCapabilities.heightAlignment, 2 )
211+ val scaledWidth = ((displayInfo.width * scale).toInt() / widthAlign) * widthAlign
212+ val scaledHeight = ((displayInfo.height * scale).toInt() / heightAlign) * heightAlign
199213
200214 Log .d(TAG , " Starting AVC stream: ${displayInfo.width} x${displayInfo.height} -> ${scaledWidth} x${scaledHeight} " )
201215 Log .d(TAG , " Configuration: bitrate=$bitrate , fps=$fps , I-frame interval=${I_FRAME_INTERVAL } s" )
202216 Log .d(TAG , " Scaled dimensions: width=$scaledWidth , height=$scaledHeight " )
203217
204218 // Validate dimensions
205219 if (scaledWidth <= 0 || scaledHeight <= 0 ) {
220+ codec.release()
206221 throw IllegalArgumentException (" Invalid dimensions: ${scaledWidth} x${scaledHeight} " )
207222 }
208- if (scaledWidth % 2 != 0 || scaledHeight % 2 != 0 ) {
209- Log .w(TAG , " Warning: Dimensions not divisible by 2, may cause issues: ${scaledWidth} x${scaledHeight} " )
210- }
211-
212- // Check codec capabilities before attempting to configure
213- val codec = MediaCodec .createEncoderByType(MediaFormat .MIMETYPE_VIDEO_AVC )
214- val codecInfo = codec.codecInfo
215- val capabilities = codecInfo.getCapabilitiesForType(MediaFormat .MIMETYPE_VIDEO_AVC )
216- val videoCapabilities = capabilities.videoCapabilities
217223
218224 Log .d(TAG , " Codec capabilities:" )
219225 Log .d(TAG , " Supported widths: ${videoCapabilities.supportedWidths} " )
0 commit comments