[RK3288][Android6.0] The bitrate_mode configuration problem of MediaCodec

×Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

native code issues

There is a pit in the bitrate mode in MediaCodec. For example, if I want to confirm whether CBR is supported before setting, I will call isBitrateModeSupported() to judge, which will cause problems.
MediaCodecInfo.java

public  boolean  isBitrateModeSupported ( int mode) {
     for (Feature feat: bitrates) {
         if (mode == feat.mValue) {
             return (mBitControl & ( 1 << mode)) != 0 ;
        }
    }
    return  false ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Whether mode supports judgment from 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 )
};
  • 1
  • 2
  • 3
  • 4
  • 5

The framework actually wrote it to death! Instead of getting it from hardware or xml, and xml is written to support.
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 >
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

If you write code more rigorously, first use isBitrateModeSupported() to judge whether CBR is supported, then it will be a tragedy.
In addition, by default, if the upper layer does not actively set bitrate_mode, VBR is returned.
ACodec.cpp

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

    return  static_cast <OMX_VIDEO_CONTROLRATETYPE>(tmp);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

VBR and CBR concepts

CBR:
Constants Bits Rate, static bit rate.
The bitrate remains essentially constant and close to the target bitrate over the course of the stream, with a drop in quality when encoding complex content.
It is most efficient to use CBR encoding in streaming scenarios.
VBR:
Variable Bit Rate, dynamic bit rate.
The code rate can vary with the complexity of the image, so its coding efficiency is relatively high, and there are few mosaics.
A suitable application scenario is media storage, not network transmission.

refer to

H264 three rate control methods (CBR, VBR, CVBR)
static code rate (CBR) and dynamic code rate (VBR)

Related: [RK3288][Android6.0] The bitrate_mode configuration problem of MediaCodec