gotch4
gotch4

Reputation: 13259

Android MediaMetadataRetriever.getFrameAtTime skips frames

I wrote a simple Android application that is using MediaMetadataRetriver class to get frames. It works fine, except that I realized that it skips frames.

The video clip I am trying to decode is one shot with the phone camera. Follow relevant code snippets:

MediaMetadataRetriever mediaDataRet = new MediaMetadataRetriever();
            mediaDataRet.setDataSource(path);

            String lengthMsStr = mediaDataRet
                    .extractMetadata(mediaDataRet.METADATA_KEY_DURATION);
            final long lenMs = Long.parseLong(lengthMsStr);

            String widthStr = mediaDataRet
                    .extractMetadata(mediaDataRet.METADATA_KEY_VIDEO_WIDTH);
            int width = Integer.parseInt(widthStr);
            String heightStr = mediaDataRet
                    .extractMetadata(mediaDataRet.METADATA_KEY_VIDEO_HEIGHT);
            int height = Integer.parseInt(heightStr);

note the variable lenMs, it holds the clid duration in milliseconds. Then for every frame I do:

                int pace = 30; // 30 fps ms spacing 


                for (long i = 0; i < lenMs; i += pace) {

                    if (is_abort())
                        return;

                    Bitmap bitmap = mediaDataRet.getFrameAtTime(i * 1000); // I tried the other version of this method with OPTION_CLOSEST, with no luck.

                    if (bc == null)
                        bc = bitmap.getConfig();

                    bitmap.getPixels(pixBuffer, 0, width, 0, 0, width, height);
[...]
}

After checking visually I noticed that some frames are skipped (like short sequences). Why? And ho do I avoid this?

Upvotes: 1

Views: 2630

Answers (1)

hoford
hoford

Reputation: 5323

Use:

mediaDataRet.getFrameAtTime(i * 1000, MediaMetadataRetriever.OPTION_CLOSEST);

The getFrameAtTime(n) uses OPTION_CLOSEST_SYNC which would give you key frames only.

Upvotes: 3

Related Questions