Search code examples
androidandroid-mediacodec

MediaCodec output bitrate decrees to 10% when update bitrate


I want to compare the difference between "bitrate-mode" of Android MediaCodec, my test workflow is:

  1. Use MediaExtractor to extract H.264 video frames from a mp4 file (a 100 seconds clip from video), it's in 1280*720 size;
  2. Use MediaCodec decoder to decode those video frames;
  3. Render the decoded frame into MediaCodec encoder's input Surface, the output size is 360*640;
  4. Collect encoder output frame size, calculate the output bitrate of every second;

During the test process, I'll change encoder's output bitrate, and see how does it change in different "bitrate-mode", CQ, VBR, and CBR.

My problem is, in VBR and CBR mode, once I change the encoder output bitrate, e.g. from 500 kbps to 600 kbps or 400 kbps, the collected output bitrate decreases into only 50kbps, and never get up again!

I've created a python script to plot the result, the result of CBR is below:

360*640

The red line is calculated output bitrate of each second, the blue dots are bitrate update actions, 500 -> 1100 -> 400 -> 1000. We can see that at the first time I update bitrate, it decreases into only about 50 kbps.

Any idea of what happened?

More info:

When I change encoder's output size into 1280*720, the plot is like below:

1280*720

And here is the source code of my test project: https://github.com/Piasy/MediaCodecRcTest

Please help me, thanks!


Solution

  • Your issue seems to be that you have the variable mCurrentBr in the unit kbps, while the API expects it in the unit bps. You handle this correctly at init:

    encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mConfig.initBr() * 1000);
    mCurrentBr = mConfig.initBr();
    

    But fail to do the same when updating the bitrate:

    mParams.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, mCurrentBr);
    

    If you add a * 1000 at the second spot, I would expect it to behave much better.