5

I'm processing a live stream via MediaCodec and have a scenario where the MediaFormat changes mid-stream (ie: resolution of the video being decoded changes). Given I'm attaching the decoder to a Surface to render it as soon as I detect the change in resolution on the incoming stream I recreate the decoder before feeding it the new resolution buffer (providing it with the proper new MediaFormat).

I've been getting some weird errors which don't give me too much info as to what could be wrong, ie when calling MediaCodec.configure with the new format and same Surface:

android.media.MediaCodec$CodecException: Error 0xffffffea
  at android.media.MediaCodec.native_configure(Native Method)
  at android.media.MediaCodec.configure(MediaCodec.java:577)

Which when fetching the CodecException.getDiagnosticInfo it shows nothing that I can really use to understand the reason for the failure: android.media.MediaCodec.error_neg_22

I've also noted the following on the logs and found some related information and am wondering if there's something I need to do regarding the Surface itself (like detaching it from the old instance of the decoder being giving it to the new one):

07-09 15:00:17.217 E/BufferQueueProducer(  139): [SurfaceView] connect(P): already connected (cur=3 req=3)
07-09 15:00:17.217 E/MediaCodec( 5388): native_window_api_connect returned an error: Invalid argument (-22)
07-09 15:00:17.218 E/MediaCodec( 5388): configure failed with err 0xffffffea, resetting...
Roberto Andrade
  • 1,793
  • 1
  • 21
  • 27
  • 1
    Some decoders support "adaptive playback", which allows for resolution changes mid-stream. This is a relatively new feature (4.4?). http://developer.android.com/reference/android/media/MediaCodec.html has some notes. – fadden Jul 09 '15 at 15:46
  • yeah unfortunately the decoder I'm using (for `video/avc`) doesn't support it (at least not on the devices I'm testing). But it's good to know such API exists. – Roberto Andrade Jul 09 '15 at 17:57

2 Answers2

3

Looks like calling stop() and release() as well as reinitializing any references I had to the getInputBuffers() and getOutputBuffers() did the trick. At least I don't get the messages/exceptions anymore. Now I just need to figure out the Surface reference part as it seems the resized stream (when resolution changes) is still being fit in the original surface dimensions instead of adjusting the Surface for the new resolution.

Roberto Andrade
  • 1,793
  • 1
  • 21
  • 27
0

If your encoder supports adaptive playback, then apparently you can alter some codec paramaters on the fly:

https://stackoverflow.com/a/34427724/1048170

Community
  • 1
  • 1
Dominic Cerisano
  • 3,522
  • 1
  • 31
  • 44