linkedin / LiTr

Lightweight hardware accelerated video/audio transcoder for Android.
BSD 2-Clause "Simplified" License
612 stars 85 forks source link

Crash IllegalStateException MediaCodec.native_dequeueInputBuffer(MediaCodec.java) during compression #256

Open emrisb opened 1 year ago

emrisb commented 1 year ago

Hey,

Thanks for this awesome library. I have just implemented the library and release it. When I looked to Crashlytics, I have bunch of crash like below. I could not reproduce the crash so I don't have any user story for that. Do you have any opinion for solution?

Fatal Exception: java.lang.IllegalStateException:
       at android.media.MediaCodec.native_dequeueInputBuffer(MediaCodec.java)
       at android.media.MediaCodec.dequeueInputBuffer(MediaCodec.java:3039)
       at com.linkedin.android.litr.codec.MediaCodecEncoder.dequeueInputFrame(MediaCodecEncoder.java:81)
       at com.linkedin.android.litr.render.AudioRenderer$RenderThread.run(AudioRenderer.java:125)
       at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run$bridge(GlideExecutor.java:299)
izzytwosheds commented 1 year ago

Thank you for reporting this. I will try to reproduce this and will get back to you. My suspicion would be that we are trying to encode an audio frame but the encoder MediaCodec is stopped. I will try to understand how this can happen.

florianPOLARSTEPS commented 1 year ago

I am seeing the same issue happening quite frequently in my logs. I have not yet been able to reproduce it though.

emrisb commented 1 year ago

@izzytwosheds I guess this issue happening when you get failed and if you retry right away with new compression. In that case onError is called before release completed for some components(MediaCodec, MediaExtractor, MediaMuxer). Not fully sure but maybe below change in TransformationJob or something similar to this might solve this issue.

from

@VisibleForTesting
    protected void error(@Nullable Throwable cause) {
        marshallingTransformationListener.onError(jobId, cause, statsCollector.getStats());
        release(false);
    }

to

@VisibleForTesting
    protected void error(@Nullable Throwable cause) {
        release(false);
        marshallingTransformationListener.onError(jobId, cause, statsCollector.getStats());
    }
florianPOLARSTEPS commented 1 year ago

@izzytwosheds I guess this issue happening when you get failed and if you retry right away with new compression. In that case onError is called before release completed for some components(MediaCodec, MediaExtractor, MediaMuxer). Not fully sure but maybe below change in TransformationJob or something similar to this might solve this issue.

from

@VisibleForTesting
    protected void error(@Nullable Throwable cause) {
        marshallingTransformationListener.onError(jobId, cause, statsCollector.getStats());
        release(false);
    }

to

@VisibleForTesting
    protected void error(@Nullable Throwable cause) {
        release(false);
        marshallingTransformationListener.onError(jobId, cause, statsCollector.getStats());
    }

I can confirm this. We are seeing the same pattern in our logs :thumbsup:

izzytwosheds commented 1 year ago

Thanks for reporting this and finding the way to reproduce, guys! We will look into this.