androidmultithreadingvideo-processingandroid-mediacodecandroid-proguard

Why does "Surface frame wait timed out" encoding with proguard turned on?


I have copied code from ExtractDecodeEditEncodeMuxTest.java into my app in order to transcode video, the most significant change being renaming the class to VideoTranscoder and removing the extends AndroidTestCase since I'm going to run it detached from any activity. Everything works fine until I compile a release build with proguard, then it fails at runtime with:

E/d: com.testapp.a.g.a.b.b(OutputSurface.java:270)
E/d: com.testapp.a.g.a.d.a(VideoTranscoder.java:944)
E/d: com.testapp.a.g.a.d.a(VideoTranscoder.java:6353)
E/d: com.testapp.a.g.a.f.run(VideoTranscoder.java:162)
E/d: java.lang.Thread.run(Thread.java:818)
E/d: TestWrapper
E/MediaCodecController: com.testapp.a.g.a.b.b(OutputSurface.java:270)
E/MediaCodecController: com.testapp.a.g.a.d.a(VideoTranscoder.java:944)
E/MediaCodecController: com.testapp.a.g.a.d.a(VideoTranscoder.java:6353)
E/MediaCodecController: com.testapp.a.g.a.f.run(VideoTranscoder.java:162)
E/MediaCodecController: java.lang.Thread.run(Thread.java:818)
W/System.err: java.lang.RuntimeException: Surface frame wait timed out
W/System.err:     at com.testapp.a.g.a.b.b(OutputSurface.java:270)
W/System.err:     at com.testapp.a.g.a.d.a(VideoTranscoder.java:944)
W/System.err:     at com.testapp.a.g.a.d.a(VideoTranscoder.java:6353)
W/System.err:     at com.testapp.a.g.a.f.run(VideoTranscoder.java:162)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
E/CompressionController: Compressor reported error, not hashing!

According to answers like this or that I need to create separate threads et all, but I'm actually using the original code already creating those threads. When I change the gradle release setting to minifyEnabled false in order to disable proguard, everything works again.

So what is proguard doing to threads that mess up the encoder/decoder? Or maybe it is removing some class used indirectly by the MediaCodec? Is there something that I need to add to the proguard settings to make it work?


Solution

  • After adding -dontoptimize to the proguard file everything works again. Obviously this is not an ideal solution, but it seems it is the only thing that can be done, since the suspect here is proguard optimising away some of the loops in the encoding/decoding threads. In my particular case I could avoid using -dontoptimize and use instead the following line which doesn't disable all optimizations:

    -optimizations !code/removal/advanced,!method/inlining/short,!method/inlining/unique,!method/removal/*,!method/marking/*