How to check if Android MediaCodec supports Constant Quality mode

I have a screen recording application that uses a MediaCodec encoder to encode video frames. Here is one way to get a video encoder:

videoCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);

Then I try to determine the best bitrate mode that this encoder supports, and my order of preference is the "Constant Quality" mode, the "Bitrate variable" mode, the "Constant bit" mode. Here is how I am trying to do this:

MediaCodecInfo.CodecCapabilities capabilities = videoCodec.getCodecInfo().getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_AVC);
MediaCodecInfo.EncoderCapabilities encoderCapabilities = capabilities.getEncoderCapabilities();

if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
    Timber.i("Setting bitrate mode to constant quality");
    videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ);
} else if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR)) {
    Timber.w("Setting bitrate mode to variable bitrate");
    videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
} else if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR)) {
    Timber.w("Setting bitrate mode to constant bitrate");
    videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
}

Doing this on my Samsung Galaxy S7 ends with a choice of VBR mode, i.e. Constant Quality mode is apparently not supported. However, if I just set BITRATE_MODE to Constant Quality, it not only works, but also produces higher quality video than VBR mode.

, Constant Quality, -, , isBitrateModeSupported()? - ?

+8
2

MediaCodec Samsung , . , , , , - . :

if(android.os.Build.MANUFACTURER.toLowerCase().equals("samsumg"))
// your code
0

, , , , .

Android 26, MediaCodec BITRATE_MODE_CQ MIMETYPE_AUDIO_FLAC.

, :

    /**
             * Query whether a bitrate mode is supported.
             */
            public boolean isBitrateModeSupported(int mode) {
                for (Feature feat: bitrates) {
                    if (mode == feat.mValue) {
                        return (mBitControl & (1 << mode)) != 0;
                    }
                }
                return false;
            }

private void applyLevelLimits() {
            String mime = mParent.getMimeType();
            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
                mComplexityRange = Range.create(0, 8);
                mBitControl = (1 << BITRATE_MODE_CQ);
            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)
                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)
                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
                mBitControl = (1 << BITRATE_MODE_CBR);
            }
        }

, BITRATE_MODE_CQ 0 isBitrateModeSupported , MIMETYPE_AUDIO_FLAC.

, Android lvl 26
, .

, - .

0

Source: https://habr.com/ru/post/1690435/


All Articles