linkedin / LiTr

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

Transcode AVC with odds resolution #157

Open fchristysen opened 2 years ago

fchristysen commented 2 years ago

Hi, thanks for this great library!

I'm facing an issue when overlay image onto empty video (much like Empty Video on your demo app), but for my case, I'm basically only transforming image into static .mp4 video. The issue happens when I'm using AVD emulator and when the targeted MediaFormat resolution is odd number e.g. : 1281, 1283, so on. The transformation would encounter IllegalStateException with logs attached below. The issue didn't happen in real device I have Vivo s1, but I have received report where the error occurred on xiaomi device. I'm not sure if this also happens in some other device, hence want to find the root cause of this. For temporary solution, now I make the target resolution to even numbers when the source image have odd resolution.

P.S. : the issue also happens in your demo app, when I try to run it in emulator.


    java.lang.IllegalStateException
        at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
        at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2789)
        at com.linkedin.android.litr.codec.MediaCodecEncoder.dequeueOutputFrame(MediaCodecEncoder.java:108)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.writeEncodedOutputFrame(VideoTrackTranscoder.java:223)
        at com.linkedin.android.litr.transcoder.VideoTrackTranscoder.processNextFrame(VideoTrackTranscoder.java:117)
        at com.linkedin.android.litr.TransformationJob.processNextFrame(TransformationJob.java:211)
        at com.linkedin.android.litr.TransformationJob.transform(TransformationJob.java:108)
        at com.linkedin.android.litr.TransformationJob.run(TransformationJob.java:77)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)```
izzytwosheds commented 2 years ago

Glad to hear you are enjoying LiTr! Which emulator version are you using? MediaCodec emulation is not very good on earlier emulator versions and get better in recent ones. Although I am not sure how even recent emulators handle odd resolutions. But the fact that this issue happens on real devices is not comforting. I will try to reproduce it on my end and will get back to you. From the stack trace it does look like that encoder codec is not liking the odd resolution.

fchristysen commented 2 years ago

I'm using Android 10.0 x86. Also could confirm this happened in OS 11 and 12. Though in 12 the behavior is a bit different, the process calls TransformationListener.onError after sometime, while on the other 2 it just logs the above exception without calling the listener onError.

izzytwosheds commented 2 years ago

I was able to reproduce this issue on Samsung Galaxy Note 10. Looks like this is encoder behavior. Determining video resolution is "business logic", I think it would be better for an application that uses LiTr to handle this. LiTr does not change parameters provided by an application, it simply follows them.