Caused by: java.lang.IllegalArgumentException: The surface has been released by MediaCodecVideoRenderer

Dear Support team,

I am currently utilizing the latest SDK version 3.37.1 of the Bitmovin player to play content in a series for AndroidTV OTT app. However, when attempting to navigate through the content using the next or previous button on the remote, I am frequently encountering the error message “Caused by: java.lang.IllegalArgumentException: The surface has been released by MediaCodecVideoRenderer”. To clarify, I am using the Bitmovin Custom Player demo for this purpose.

Thank you for your assistance in resolving this issue.

 Playback error
                                         com.bitmovin.android.exoplayer2.ExoPlaybackException: MediaCodecVideoRenderer error, index=0, format=Format(3, null, null, video/avc, avc1.42C01F, 972056, null, [640, 360, -1.0], [-1, -1]), format_supported=YES
                                             at com.bitmovin.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:588)
                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                             at android.os.Looper.loopOnce(Looper.java:201)
                                             at android.os.Looper.loop(Looper.java:288)
                                             at android.os.HandlerThread.run(HandlerThread.java:67)
                                         Caused by: com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: c2.goldfish.h264.decoder, Format(3, null, null, video/avc, avc1.42C01F, 972056, null, [640, 360, -1.0], [-1, -1])
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecWithFallback(MediaCodecRenderer.java:1012)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecOrBypass(MediaCodecRenderer.java:536)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1444)
                                             at com.bitmovin.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:917)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:945)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:760)
                                             at com.bitmovin.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1017)
                                             at com.bitmovin.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:512)
                                             at android.os.Handler.dispatchMessage(Handler.java:102) 
                                             at android.os.Looper.loopOnce(Looper.java:201) 
                                             at android.os.Looper.loop(Looper.java:288) 
                                             at android.os.HandlerThread.run(HandlerThread.java:67) 
                                         Caused by: java.lang.IllegalArgumentException: The surface has been released
                                             at android.media.MediaCodec.native_configure(Native Method)
                                             at android.media.MediaCodec.configure(MediaCodec.java:2214)
                                             at android.media.MediaCodec.configure(MediaCodec.java:2130)
                                             at com.bitmovin.android.exoplayer2.mediacodec.AsynchronousMediaCodecAdapter.initialize(AsynchronousMediaCodecAdapter.java:156)
                                             at com.bitmovin.android.exoplayer2.mediacodec.AsynchronousMediaCodecAdapter.access$100(AsynchronousMediaCodecAdapter.java:50)
                                             at com.bitmovin.android.exoplayer2.mediacodec.AsynchronousMediaCodecAdapter$Factory.createAdapter(AsynchronousMediaCodecAdapter.java:103)
                                             at com.bitmovin.android.exoplayer2.mediacodec.DefaultMediaCodecAdapterFactory.createAdapter(DefaultMediaCodecAdapterFactory.java:111)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:1090)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecWithFallback(MediaCodecRenderer.java:1001)
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecOrBypass(MediaCodecRenderer.java:536) 
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1444) 
                                             at com.bitmovin.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:917) 
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:945) 
                                             at com.bitmovin.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:760) 
                                             at com.bitmovin.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1017) 
                                             at com.bitmovin.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:512) 
                                             at android.os.Handler.dispatchMessage(Handler.java:102) 
                                             at android.os.Looper.loopOnce(Looper.java:201) 
                                             at android.os.Looper.loop(Looper.java:288) 
                                             at android.os.HandlerThread.run(HandlerThread.java:67) 

Note: Logs attached

Hi @malviya.software , thanks for reporting this. Can you please share additional information about the issue scenario.

  • Does this also happen on older player versions or did it start with 3.37.1?
  • Which device(s) is the issue encountered on?
  • Can you please share the link to Bitmovin Custom Player demo used to replicate this issue?
  • Bitmovin sample apps do not provide code for next/previous playback using remote control. Did you customize the sample for this functionality? If yes, can you please the customized app? Looking at the error trace, it is coming from decoder framework on the device wherein codec initialization is failing when switching content. Can you please share the sequence of API calls made to player to navigate to next/previous content?
  • Does this also happen on older player versions or did it start with 3.37.1?

Yes

  • Which device(s) is the issue encountered on?

SonyTV and Emulator too

  • Can you please share the link to Bitmovin Custom Player demo used to replicate this issue?

I’ll do that

  • Bitmovin sample apps do not provide code for next/previous playback using remote control. Did you customize the sample for this functionality? If yes, can you please the customized app?

Yes

Looking at the error trace, it is coming from decoder framework on the device wherein codec initialization is failing when switching content. Can you please share the sequence of API calls made to player to navigate to next/previous content?

There is only one API call. On successful response only, we are passing playback URL to load and then play. While switching content, we stop, unload and destroy player and then we fetch the URL and then load and play the next content.

Thanks @malviya.software . Will wait for the custom app to replicate the behaviour.

BTW, are you passing a custom surface using player.setSurface() API or letting player use the default surface?

No. I didnt use the setSurface().

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".tv.ui.playback.PlaybackActivity"
    android:orientation="vertical">
</>

playerUi = PlayerUI(this, this,  getPlayerConfig())
binding.rootView.addView(playerUi)

//PlayerUI is a RelativeLayout as same as Bitmovin custom ui kotlin code