Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exoplayer throws Decoder initialisation exception for large mp4 files in android

Iam using Exoplayer to play videos as a playlist continuously in android . When I play low quality mp4 videos it works fine but when i try to play higher quality mp4 videos after playing one or two videos in the playlist the screen doesnot display anything and the log gives the following exception

com.google.android.exoplayer.MediaCodecTrackRenderer$DecoderInitializationException: Decoder init failed: OMX.amlogic.avc.decoder.awesome, MediaFormat(video/avc, 198826, 1920, 1080, -1.0, -1, -1, -1, -1, -1)

Even if i loop the same high quality video the first time it plays and then second time this exception is thrown . when the video size is more than 80mb this exception is thrown .is it some buffer size issue ? can someone please guide me . thankyou very much

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.adplayertexture);   
    AdplayerTexture=(TextureView)findViewById(R.id.AdPlayerTexture);
    AdplayerTexture.setBackgroundColor(Color.BLACK);
        AdplayerTexture.setSurfaceTextureListener(this);
  }
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
    int height) {

 AdPlayerSurface = new Surface( surface); 
 playMedia(AdPlayerSurface);
}


private void playMedia(Surface surface){
mediaplayer=new ExoPlayer();
mediaplayer.play(this,Videopathlist[CurrentVideoIndex],surface;
 mediaplayer.addListener(this);   
   }

@Override
public void onStateChanged(boolean playWhenReady, int playbackState) {

if (playbackState == ExoPlayer.STATE_ENDED) {
//releasing the resources   
    mediaplayer.DestroyPlayer();
AdPlayerSurface.release();

AdPlayerSurface=new Surface(AdplayerTexture.getSurfaceTexture());
    CurrentVideoIndex++;
playMedia(AdPlayerSurface);
}

this is the function play() in root2mediaplayer class

public void playMedia(Activity playerActivity,String mediapath,final long Position,Surface mediasurface){
    String Systemroot = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
try{
    File myFile=new File(Systemroot + java.io.File.separator + "Videos"
            + java.io.File.separator
            + mediapath);
    Uri uri = Uri.fromFile(myFile);
    final int numRenderers = 2;

    SampleSource sampleSource = 
            new FrameworkSampleSource(playerActivity, uri, /* headers */ null, numRenderers);

    // Build the track renderers
    TrackRenderer    videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);

    TrackRenderer    audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

    // Build the ExoPlayer and start playback
    MoviePlayer = ExoPlayer.Factory.newInstance(numRenderers);
    MoviePlayer.prepare(videoRenderer, audioRenderer);

    MoviePlayer.addListener(this);
    // Pass the surface to the video renderer.
    MoviePlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, mediasurface);

            MoviePlayer.seekTo(Position);
            MoviePlayer.setPlayWhenReady(true);
}catch(Exception e){

e.printStackTrace();
FileLog("exception in mediaplayer");
}
like image 574
user2949215 Avatar asked Feb 02 '15 12:02

user2949215


Video Answer


1 Answers

Without looking at your full code and without knowing which device/platform you see this issue (though from your question it looks like a h/w platform from AMLOGIC), I can only guess that may be you are not releasing the MediaCodec resources in your player when the playback ends and/or you switch playing new video.

MediaCodec is released in releaseCodec() API in https://github.com/google/ExoPlayer/blob/master/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java.

You may want to check if that is indeed called when you stop playback of first video and start playback of next video in your playlist.

Typically, all high end mobile platforms have h/w based decoders that use limited and dedicated video memory(accessible only by h/w decoders) on the system to decode frames. In some platforms, you will not be able to create a decoder if some other app (or same app) in the system has created another instance of the same h/w based decoder, and not released it when it goes to background (in Activity Life cycle language, onStop etc) .

Additionally, if the dedicated video memory is not released when the decoders are destroyed, you will exhaust the limited video memory available on the platform in couple of video playback sessions due to the leak.

Look out for full platform adb logs when you create and destroy the MediaCodec instances (or in your case, stop and start playback of next video in playlist). That may give you some clues.

Hope my high level advice is of some use to you to hunt down the problem. Good luck!!!.

like image 98
Srikanth Peddibhotla Avatar answered Oct 31 '22 00:10

Srikanth Peddibhotla