我使用MediaCodec
对来自相机的视频进行编码:
MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height);
format.setInteger(MediaFormat.KEY_BIT_RATE, 250000);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
format.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
_mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
我发现,根据我给出的分辨率,有一些最低有效比特率需要设置。如果我将比特率设置为低于该值,它将被完全忽略。如果我将比特率设置为高于这个看不见的阈值,它将按预期工作。我想做的是查询对于任何给定的分辨率,我可以为KEY_BIT_RATE
设置的最小比特率是多少。当我设置一个没有任何效果的比特率时,不会抛出任何错误或任何东西。
最低比特率是谷歌要求供应商支持的分辨率的一部分:https://source.android.com/compatibility/android-cdd.pdf.查看5.2
对于其他分辨率,行为是未定义的。文档中未列出的解决方案也可能会引入其他意外问题,因为它们不包括在谷歌认证测试(CTS)中,并且不能保证设备供应商使它们正确工作
android中没有API来检查支持的最低比特率以获得准确的分辨率
比特率取决于编解码器类型。我写了一个实用函数来计算比特率,如果它不在编解码器指定的范围内,那么这个值就会被钳制,使其与编解码器规范兼容。
/**
* https://source.android.com/compatibility/android-cdd.pdf
*/
private fun calculateBitRate(width: Int, height: Int): Int {
return when (height) {
240 -> 384_000
360 -> 1_000_000
480 -> 2_000_000
720 -> 4_000_000
1080 -> 10_000_000
else -> (4.8 * width * height).toInt()
}
}
var bitRate: Int = calculateBitRate(width, height)
val mcl = MediaCodecList(MediaCodecList.REGULAR_CODECS)
for (info in mcl.codecInfos) {
if (!info.isEncoder) {
continue
}
try {
val caps = info.getCapabilitiesForType(mime)
if (caps != null && caps.isFormatSupported(format)) {
bitRate = caps.videoCapabilities.bitrateRange.clamp(bitRate)
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate)
break
}
} catch (e: IllegalArgumentException) {
// type is not supported
}
}