Search code examples
javaandroidandroid-mediacodec

Why always got NullPointerException while getting KEY_FRAME_RATE from MediaCodec?


I want to retrieve the frameRate from the MediaCodec, but i always got the NullPointerException. The code as following:

    public void handleWriteSampleData(MediaCodec encoder, int trackIndex, int bufferIndex, ByteBuffer encodedData, MediaCodec.BufferInfo bufferInfo) {
        super.writeSampleData(encoder, trackIndex, bufferIndex, encodedData, bufferInfo);
        int rc = -1;

        if (((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0)) {
            if (VERBOSE) Log.i(TAG, "handling BUFFER_FLAG_CODEC_CONFIG for track " + trackIndex);
            if (trackIndex == VIDEO_TRACK_INDEX) {
                // Capture H.264 SPS + PPS Data
                Log.d(TAG, "Capture SPS + PPS");

                captureH264MetaData(encodedData, bufferInfo);
                mFFmpeg.setVideoCodecExtraData(videoConfig, videoConfig.length);
                fps = encoder.getOutputFormat().getInteger(MediaFormat.KEY_FRAME_RATE);
                Log.i(TAG, "fps:" + fps);
            }
            ....

The exception as following:

E/AndroidRuntime( 1419): java.lang.NullPointerException
E/AndroidRuntime( 1419):    at android.media.MediaFormat.getInteger(MediaFormat.java:282)

I have gone through the source code:

/**
 * Returns the value of an integer key.
 */
public final int getInteger(String name) {
    return ((Integer)mMap.get(name)).intValue();
}

How to get the right fps value from MediaCodec ?


Solution

  • The information is not available from MediaCodec, because timing information is not necessarily present in H.264 (see e.g. this link). KEY_FRAME_RATE is an argument for the encoder.

    A nominal frame rate value may be present in the wrapper (e.g. .mp4) that MediaExtractor handles, but I don't know if there's a consistent way to access that.

    You can dig through SPS, or calculate an fps value by looking at the presentation time stamps on a series of frames. If the video uses a variable frame rate, like "screenrecord" output does, then you may get an incorrect number from this... but I would argue that, for VFR video, there is no correct number for The Frame Rate, just maximum and average values.