Which AVC profile/level will be set in Android MediaCodec if we don't set this value manually?

1.7k views Asked by At

In Android ACodec.cpp setupAVCEncoderParameters, it reads profile and level from msg(msg->findInt32("profile", &profile)/msg->findInt32("level", &level)), the msg appears to be coming from format in MediaCodec.configure(). So, I think we can set profile/level manually before MediaCodec.configure() like below:

format.setInteger(MediaCodec.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.AVCProfileHigh);
format.setInteger(MediaCodec.KEY_LEVEL, MediaCodecInfo.CodecProfileLevel.AVCLevel5);

Of course, I agree it's not a good idea, because we don't konw if our device support the profile/level we set. And also I find most example code didn't set these values at all.

For example:

MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);  // API >= 18
format.setInteger(MediaFormat.KEY_BIT_RATE, calcBitRate());
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10)

mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

Maybe they will be set automatically? Will MediaCodec query which profile/level current device support and choose one automatically? If device support more than one profile/level, which one will be selected? The lower level one(baseline, e.g.) or the higher level one(high, e.g.)?

1

There are 1 answers

0
mstorsjo On

In most cases (as far as I know), it will be baseline, since higher profiles (with B-frames enabled) requires you as a caller to be prepared to handle it correctly (a trivial/naive application might have assumptions that don't hold up with B-frames), and an encoder with B-frames has got higher latency.