Inconsistent video quality when encoding camera preview frames using MediaCodec on Xperia Z1

I encode frames NV21coming from a camera preview. For some reason, a circuit that works fine on other devices doesn't work correctly Sony Xperia Z1with Android 4.3. It sends back encoded frames with the wrong (low) quality.

MediaCodecformat COLOR_FormatYUV420SemiPlanar, which is equal NV12(conversion NV21to NV12by replacing U and V components). The output buffers sent to me back MediaCodecare very low in size, which does not match the resolution ( 1280x720) and bitrate ( 1000000) that I use. The first few frames go with good quality, but then it drops significantly:

int encoderStatus = mMediaCodec.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
// a few encoderStatus checks skipped
ByteBuffer encodedData = outputBuffers[encoderStatus];
Log.i(Constants.TAG, "Buffer size " + mBufferInfo.size);

What gives me the following Xperia Z1 magazine:

Buffer size 26
Buffer size 52172
Buffer size 23650
Buffer size 14394
Buffer size 3591
Buffer size 1849
Buffer size 3908

...

Buffer size 1043
Buffer size 248
Buffer size 836
Buffer size 518
Buffer size 1112

An example of a log from Sony Xperia ZRwhere it works correctly:

Buffer size 21
Buffer size 51048
Buffer size 21063
Buffer size 24228
Buffer size 28040
...
Buffer size 44959
Buffer size 44972
Buffer size 44957
Buffer size 45004
Buffer size 44999
Buffer size 44957

Any advice would be appreciated.

+4
source share
1 answer

Are you sure that you are passing the timestamps in the right block (microseconds) - and that he set a reasonable frame rate?

  • Some encoders can ignore timestamps and set only a fixed bitrate budget per frame based on the frame rate.

  • Others may try to calculate how many bits they are allowed to use for each frame based on a timestamp.

If timestamps are specified, for example. in milliseconds, instead, this can cause the encoder to reduce the size of the encoded frames to zero.

+4
source

All Articles