FFmpegMediaMetadataRetriever icon indicating copy to clipboard operation
FFmpegMediaMetadataRetriever copied to clipboard

memory leaky in android?

Open dancingpipi opened this issue 7 years ago • 2 comments

I found my usage of FFmpegMediaMetadataRetriever cause a memory leaky, there is my code:

private Bitmap[] extractFramesFromVideo(String path){
        if(TextUtils.isEmpty(path)){
            return null;
        }
        Log.i("LOGCAT", "video frame start");

        FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
        FFmpegMediaMetadataRetriever.IN_PREFERRED_CONFIG = Bitmap.Config.ARGB_8888;

        retriever.setDataSource(path);
        String sDuration = retriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);
        long iDuration = EXTRACT_STEP;
        try{
            iDuration = Integer.parseInt(sDuration) * 1000;
            Log.i("LOGCAT", "iDuration is :" + iDuration);
        }catch (NumberFormatException e){
            e.printStackTrace();
        }

        ArrayList<Bitmap> frames = new ArrayList<Bitmap>();
        for(int i=0;i<=iDuration;i += EXTRACT_STEP){
            Log.i("LOGCAT", "i is : " + i);
            Bitmap bitmap = retriever.getFrameAtTime(i, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);

            frames.add(bitmap);
        }
        retriever.release();

        return frames.toArray(new Bitmap[frames.size()]);
    }

when I call this function repeatedly for same videopath, the memory usage grows quickly according to profile~ @wseemann am i using it wrong ? please help, thanks much~

dancingpipi avatar Jan 10 '19 10:01 dancingpipi

Your problem is here:

for(int i=0;i<=iDuration;i += EXTRACT_STEP){
    Log.i("LOGCAT", "i is : " + i);
    Bitmap bitmap = retriever.getFrameAtTime(i, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
    frames.add(bitmap);
}

You are calling FFmpegMediaMetadataRetriever continuously. Instead, you should wait from the current instance to complete before starting the next.

This should also not be done on the main thread. Use an AsyncTask instead.

HBiSoft avatar Nov 29 '19 05:11 HBiSoft

@HBiSoft how do you know that the current instance has completed the job? This is a void method, really. How can we do that? Code snippet?

RowlandOti avatar Dec 12 '19 11:12 RowlandOti