[RK3288][Android6.0] MediaCodec的bitrate_mode配置问题

×Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

      • 原生代码问题
      • VBR和CBR概念
      • 参考

原生代码问题

MediaCodec中的bitrate mode有个坑,比如我在设置之前想确认下CBR是否支持,那么会调用isBitrateModeSupported()判断,这样会有问题。
MediaCodecInfo.java

public boolean isBitrateModeSupported(int mode) {
    for (Feature feat: bitrates) {
        if (mode == feat.mValue) {
            return (mBitControl & (1 << mode)) != 0;
        }
    }
    return false;
}

mode是否支持从bitrates判断

private static final Feature[] bitrates = new Feature[] {
    new Feature("VBR", BITRATE_MODE_VBR, true),
    new Feature("CBR", BITRATE_MODE_CBR, false),
    new Feature("CQ",  BITRATE_MODE_CQ,  false)
};

framework居然把它写死了!而不是从hardware或者xml中获取,而xml是写着支持的。
vendor/rockchip/common/vpu/etc/media_codecs.xml

<Encoders>
    <MediaCodec name="OMX.rk.video_encoder.avc" type="video/avc" >
        <Limit name="size" min="176x144" max="1920x1088" />
        <Limit name="alignment" value="16x8" />
        <Limit name="bitrate" range="1-40000000" />
        <Feature name="bitrate-modes" value="VBR,CBR" />
    <Limit name="concurrent-instances" max="32" />
    MediaCodec>
Encoders>

如果你写代码比较严谨,先用isBitrateModeSupported()判断CBR是否支持,那么就悲剧了。
另外,在默认情况下,如果上层没有主动设置bitrate_mode的话,返回的是VBR。
ACodec.cpp

status_t ACodec::setupAVCEncoderParameters(const sp &msg) {
......
OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
......
}
static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp &msg) {
    int32_t tmp;
    if (!msg->findInt32("bitrate-mode", &tmp)) {
        return OMX_Video_ControlRateVariable;
    }

    return static_cast(tmp);
}

VBR和CBR概念

CBR:
Constants Bits Rate, 静态比特率。
比特率在流的进行过程中基本保持恒定并且接近目标比特率,当对复杂内容编码时质量会下降。
在流式播放方案中使用CBR编码最为有效。
VBR:
Variable Bit Rate,动态比特率。
码率可以随着图像的复杂程度的不同而变化,因此其编码效率比较高,马赛克很少。
适合的应用场景是媒体存储,而不是网络传输。

参考

H264三种码率控制方法(CBR, VBR, CVBR)
静态码率(CBR)和动态码率(VBR)

你可能感兴趣的:(子类__Codec)