1

We're working on an Android App that requires resizing (frame size) and compressing videos. We tested the code sample below and it's currently slow: https://github.com/hoolrory/AndroidVideoSamples/blob/master/CommonVideoLibrary/src/com/roryhool/commonvideolibrary/VideoResampler.java

The output video frame size is reduced (e.g., 480x320), and the bit-rate is also reduced to achieve compression. The final video looks very good and the compression ratios are good, too. It's just that the process is slow. I tested on a Galaxy S4 running Android 4.4 and Galaxy Note 5 running Android 6.0. The later is faster, but not by much. On Galaxy S4, a 30-second video takes about a minute to compress (on average).

The code above decods the input video on an input surface, reduces frame size, and outputs to an output surface. MediaMuxer is used to mux-in the audio. The example is using an MPEG container and H264 encoder. Some relevant questions:

  1. Are there some parameters we can use to speed up the compression?
  2. How is the video compression speed affected by the target bit rate and frame size, if any?
  3. We didn't use FFMpeg. Is that faster?

Any pointers or hints, even if not related to the code sample above, would be highly appreciated.

Thank you very much!

Omar

user3117562
  • 33
  • 2
  • 7
  • Thanks to @mstorsjo, I set the TIMEOUT_USEC in the code sample to 1000 micro-seconds instead of the default 10000. On Galaxy S4, speed was improved by 55% on averaged over a dozen videos of different lengths. For Galaxy Note5, the speed improvement was 65%. – user3117562 Oct 17 '16 at 17:59

1 Answers1

1

Your problem is with how you synchronously wait for events on one of the components (encoder or decoder). Either rebuild the code to run with asynchronous callbacks, or lower the timeouts.

See https://stackoverflow.com/a/37513916/3115956 for a longer explanation with more references, and https://github.com/mstorsjo/android-decodeencodetest for an example on how to use the asynchronous mode effectively.

Community
  • 1
  • 1
mstorsjo
  • 12,983
  • 2
  • 39
  • 62
  • Thank you very much @mstorsjo. I will test your suggested changes and update back. – user3117562 Oct 17 '16 at 11:06
  • One question please, the code samples you pointed out, does it assume Android 5.0? We're currently trying to support API level 18+. Thank you again. https://github.com/mstorsjo/android-decodeencodetest – user3117562 Oct 17 '16 at 11:08
  • That sample code requires Android 5.0, yes. If you need to support the old synchronous API, you need to lower the timeouts and/or improve the logic for choosing how/when to wait for what with what timeout. Ideally, if you reduce the timeouts to close to zero, it will probably run faster, but you'll waste more time busylooping, polling the inputs/outputs all the time. One possible solution is to use separate threads, one feeding input to the decoder, one waiting for output from the decoder, feeding it to the encoder, and one waiting for output from the encoder. – mstorsjo Oct 17 '16 at 19:46