6

I'm using MediaCodec to encode video from the camera:

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);

What I've found is that depending on the resolution I give it there is some minimum valid bit rate to set. If I set a bit rate under that amount, it's entirely ignored. If I set a bit rate above this invisible threshold it works as intended. What I would like to do is query what the minimum bit rate I can set for KEY_BIT_RATE is for any given resolution. No errors are thrown or anything when I set a bit rate that doesn't have any effect.

Marlon
  • 1,473
  • 11
  • 13
David
  • 27,652
  • 18
  • 89
  • 138

2 Answers2

3

Minimal bitrate is a part of google requirements for resolutions that are required to be supported by vendors: https://source.android.com/compatibility/android-cdd.pdf. Look at 5.2

For other resolutions the behavior is undefined. Resolutions not listed in the doc can also introduce other unexpected issues because are not included in Google certification tests (CTS) and there is no guarantee that device vendors make them working correctly

And there is no API in android to check minimal supported bitrate for exact resolution

Emmanuel
  • 16,791
  • 6
  • 48
  • 74
Marlon
  • 1,473
  • 11
  • 13
  • 2
    This doesn't seem to really answer the question. The CDD says that devices must support encoding at a minimum bitrate, but that does not mean devices are not allowed to support lower bitrates than the minimum required. The minimum requirement is there so it is guaranteed that a certain level of quality can be met. – cyngus Jun 27 '15 at 01:24
  • Agree that document describes requirements for hardware devices, not requirements for applications. – Ernest Poletaev Jan 19 '16 at 11:40
0

Bit rate is depends on the codec type. I wrote a utility function to calculate bit rate and if it's not within the range specified by codec then the value is clamped to make it compatible with the codec specifications.

/**
 * 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
    }
}
UdaraWanasinghe
  • 2,622
  • 2
  • 21
  • 27