Search code examples
androidexceptionandroid-mediacodecnative-code

When to call MediaCodec:getOutputFormat()?


For an audio codec, calling MediaCodec::getOutputFormat() throws an IllegalStateException on one device (not on another).

The Android docs says that such an exception is raised if the codec is not in the Configured or Executing states:

http://developer.android.com/reference/android/media/MediaCodec.html

On both devices, the call to getOutputFormat was after the codec was configured. There were also intervening calls to starting the codec, and retrieving its input and output buffers.

Does the call to getOutputFormat need to be immediately after the configure() call? The docs suggest that the call to configure() puts the codec in the Configured state, and the call to start() puts it in the Executing state. So it should be OK to put the call after the start().

But in fact, a change was made in the boilerplate code in the docs, indicating that you get the IllegalStateException if you call getOutputFormat() just after start():

https://code.google.com/p/android-source-browsing/source/diff?spec=svn.platform--frameworks--base.e55d5e864b133df8ccf9f92ca4a5d3accb1dab5c&repo=platform--frameworks--base&name=jb-mr1-dev&r=b529e4c9ca8a6790162275ac2e481f768a6d585f&format=side&path=/media/java/android/media/MediaCodec.java&old_path=/media/java/android/media/MediaCodec.java&old=2ac3f2e285159300c62c797bb2123604773ccac7

So there's something else going on besides the codec state that triggers whether this exception is thrown.


Solution

  • You can only call MediaCodec::getOutputFormat after you get MediaCodec.INFO_OUTPUT_FORMAT_CHANGED returned from MediaCodec:: dequeueOutputBuffer. It's not enough that it is in the executing state, the internal codec also needs to have produced the output MediaFormat object.

    The example was fixed further soon after the MediaCodec API was made public, in https://android-review.googlesource.com/39100, but you're right that the documentation for the method itself also still needs to be fixed.

    EDIT: Actually, the clause in the documentation for MediaCodec::getOutputFormat that says you can call it directly after configure was added in https://android.googlesource.com/platform/frameworks/base/+/d4023114e8cf7ec7db4d07958a303699b658f2c0%5E%21/ (which became part of the 5.0 release). Thefore you can probably do that successfully since 5.0, but not on earlier versions.