google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.73k stars 6.03k forks source link

When MediaCodecRenderer$DecoderInitializationException occurs? #5847

Closed mansurrrr closed 5 years ago

mansurrrr commented 5 years ago

[REQUIRED] Question

I have multiple Exoplayers in Recyclerview and i'm calling player.stop(/* reset */ true) inside ondetachedFromWindow() of each rowview. After each rowview reattached from onAttachFromWindow(), prepare exoplayer with existing mediasource.

It works normally when playingback at the first time, but player error occurs when the player is reattached after calling player.stop(true) from onDetachFromWindow()via recyclerview scrolling. (Please refer to the stacktrace below)

  1. When this error occurs?
  2. Should I call player.release() on onDetachedFromWindow()instead of stop(true) inside of each rowview?

(Full stackTrace below)

I/ACodec:  [] Now uninitialized
I/ACodec: [] onAllocateComponent
MediaPlayerService::getOMX
I/OMXClient: MuxOMX ctor
I/OMXMaster: makeComponentInstance(OMX.Exynos.avc.dec) in mediacodec process
D/libexynosv4l2: try node: /dev/video6
I/libexynosv4l2: node found for device s5p-mfc-dec: /dev/video6
I/libexynosv4l2: open video device /dev/video6
I/ACodec: [OMX.Exynos.avc.dec] Now Loaded
E/BufferQueueProducer: [SurfaceTexture-0-17261-4] connect: BufferQueue has been abandoned
E/MediaCodec: native_window_api_connect returned an error: No such device (-19)
E/MediaCodec: configure failed with err 0xffffffed, resetting...
I/ACodec:  [OMX.Exynos.avc.dec] Now uninitialized
I/ACodec:  [] Now kWhatShutdownCompleted event : 8398
I/MediaCodec: Codec shutdown complete
I/ACodec:  [] Now uninitialized
I/ACodec: [] onAllocateComponent
I/MediaPlayerService: MediaPlayerService::getOMX
I/OMXClient: MuxOMX ctor
I/OMXMaster: makeComponentInstance(OMX.Exynos.avc.dec) in mediacodec process
D/libexynosv4l2: try node: /dev/video6
I/libexynosv4l2: node found for device s5p-mfc-dec: /dev/video6
I/libexynosv4l2: open video device /dev/video6
I/ACodec: [OMX.Exynos.avc.dec] Now Loaded
I/ACodec:  [OMX.Exynos.avc.dec] Now uninitialized
I/ACodec:  [] Now kWhatShutdownCompleted event : 8398
I/MediaCodec: Codec shutdown complete
W/MediaCodecRenderer: Failed to initialize decoder: OMX.Exynos.avc.dec
                             android.media.MediaCodec$CodecException: Error 0xffffffed
                                 at android.media.MediaCodec.native_configure(Native Method)
                                 at android.media.MediaCodec.configure(MediaCodec.java:1882)
                                 at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.configureCodec(MediaCodecVideoRenderer.java:483)
                                 at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:805)
                                 at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodecWithFallback(MediaCodecRenderer.java:745)
                                 at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:474)
                                 at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.reinitializeCodec(MediaCodecRenderer.java:1261)
                                 at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1111)
                                 at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:552)
                                 at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:647)
                                 at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:529)
                                 at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:300)
                                 at android.os.Handler.dispatchMessage(Handler.java:98)
                                 at android.os.Looper.loop(Looper.java:154)
                                 at android.os.HandlerThread.run(HandlerThread.java:61)
E/ExoPlayerImplInternal: Playback error.
                         com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.Exynos.avc.dec, Format(1, null, null, video/avc, null, -1, null, [640, 640, -1.0], [-1, -1])
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:479)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.reinitializeCodec(MediaCodecRenderer.java:1261)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1111)
                             at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:552)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:647)
                             at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:529)
                             at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:300)
                             at android.os.Handler.dispatchMessage(Handler.java:98)
                             at android.os.Looper.loop(Looper.java:154)
                             at android.os.HandlerThread.run(HandlerThread.java:61)
                          Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.Exynos.avc.dec, Format(1, null, null, video/avc, null, -1, null, [640, 640, -1.0], [-1, -1])
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodecWithFallback(MediaCodecRenderer.java:753)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:474)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.reinitializeCodec(MediaCodecRenderer.java:1261) 
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1111) 
                             at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:552) 
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:647) 
                             at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:529) 
                             at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:300) 
                             at android.os.Handler.dispatchMessage(Handler.java:98) 
                             at android.os.Looper.loop(Looper.java:154) 
                             at android.os.HandlerThread.run(HandlerThread.java:61) 
                          Caused by: android.media.MediaCodec$CodecException: Error 0xffffffed
                             at android.media.MediaCodec.native_configure(Native Method)
                             at android.media.MediaCodec.configure(MediaCodec.java:1882)
                             at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.configureCodec(MediaCodecVideoRenderer.java:483)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:805)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodecWithFallback(MediaCodecRenderer.java:745)
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:474) 
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.reinitializeCodec(MediaCodecRenderer.java:1261) 
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1111) 
                             at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:552) 
                             at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:647) 
                             at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:529) 
                             at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:300) 
                             at android.os.Handler.dispatchMessage(Handler.java:98) 
                             at android.os.Looper.loop(Looper.java:154) 
                             at android.os.HandlerThread.run(HandlerThread.java:61) 
marcbaechinger commented 5 years ago

I think this happens because more than one player is trying to acquire the same codec instance (see #5799 also).

Can you reproduce this issue if you are only using a single ExoPlayer instance?

mansurrrr commented 5 years ago

When I checked, the cause was elsewhere. While processing the visibility of textureview, an error occurred when trying to prepare multiple players while textureview is gone. Thank you for your help.

Another question is, if there is an exoplayer inside a particular fragment, I wonder if the player resource is released without explicitly calling player.release at the time the fragment is destroyed.

marcbaechinger commented 5 years ago

You should definitely call release yourself and not rely on something is releasing codec resources automatically.

That said I would recommend to not instantiate and release the player within a fragment but instead have one single player which you then pass to the fragment when it is attached to the window (or when it needs the player). This is the most efficient and also quickest way. You don't have control of how many fragments the system, creates and when it is attached/detached to the window.

Specifically if all your videos are of the same format, the player can (since v2.10) reuse codec resources efficiently because the renderers can be reused after a first playback. This can help for your pager view use case as well as for recycler view. Please see the Medium blog post we just published around this topic.

Please also note than in this case you should not call stop() or release(), at all but just prepare the player with the next media source.

marcbaechinger commented 5 years ago

Closing due to inactivity.