首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检查Android MediaCodec是否支持恒定质量模式

如何检查Android MediaCodec是否支持恒定质量模式
EN

Stack Overflow用户
提问于 2017-12-08 21:21:18
回答 1查看 1.8K关注 0票数 9

我有一个屏幕录制应用程序,使用MediaCodec编码器来编码视频帧。下面是我检索视频编码器的一种方法:

代码语言:javascript
复制
videoCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);

然后我尝试确定这个编码器支持的最佳比特率模式,我的首选顺序是“恒定质量”模式,可变比特率模式,恒定比特率模式。我试着这样做:

代码语言:javascript
复制
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);
}

在我的三星Galaxy S7上运行时,最终选择了变频器模式,即不支持恒定质量模式。然而,如果我只是将BITRATE_MODE设置为恒定质量,它不仅可以工作,而且实际上比VBR模式产生更好的视频质量。

那么,如果这个编码器显然支持恒定质量模式,为什么我会从isBitrateModeSupported()得到一个假阴性?我是不是漏掉了什么?

EN

回答 1

Stack Overflow用户

发布于 2019-10-14 23:52:52

现在已经很晚了,但也许我可以帮助将来来这里的人。

至于Android26,MediaCodec类将只接受MIMETYPE_AUDIO_FLAC编解码器的BITRATE_MODE_CQ

我不知道为什么,但这是硬编码到类中的:

代码语言:javascript
复制
    /**
             * 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的情况下返回true。

这就是为什么它在android lvl 26上返回false的原因

我不知道为什么它是这样编码的。

我猜检查的一个简单方法是尝试创建具有您希望的格式的编码器,并捕获任何可能的异常

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47715246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档