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.71k stars 6.02k forks source link

exoplayer2.ParserException: Invalid NAL length when playing .MP4 file from raw folder when we seek the video #8268

Closed rahul-hawge closed 3 years ago

rahul-hawge commented 3 years ago

[REQUIRED] Issue description

Observed Behavior : I am trying to play a MP4 file from raw folder. But when I use seekbar to move back and forth, it throws Invalid length the exception. There is no issue with the video file as I was able to play same video in VideoView(attached github link to sample project) Expected Behavior : The video should play even we use the seek bar to reach particular point in the video.

[REQUIRED] Reproduction steps

I have created a sample app showing how it behaves in SamplePlayer and VideoView. You just need to play around with the seekbar to reproduce the issue.

Steps:

  1. Run the code given in the github link
  2. Click on exoplayer button
  3. The video will start playing once you click on it.
  4. Drag the seek bar to the last portion of the video.
  5. Observe Invalid NAL length toast.

Note : Click on Video view button and observe the video plays fine in VideoView.

[REQUIRED] Link to test content

Below is the github link which has the code and .MP4 file that I am using in the application. https://github.com/rahul-hawge/exoplayer-issue-sample.git

[REQUIRED] A full bug report captured from the device

2020-11-23 12:36:53.221 29196-29196/com.example.sampleexoplayer W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@721ef20 2020-11-23 12:36:53.787 29196-29196/com.example.sampleexoplayer W/sampleexoplaye: Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed) 2020-11-23 12:36:53.833 29196-29196/com.example.sampleexoplayer I/ExoPlayerImpl: Init 15d3a12 [ExoPlayerLib/2.11.4] [generic_x86, Android SDK built for x86, Google, 29] 2020-11-23 12:36:54.003 29196-29196/com.example.sampleexoplayer I/Choreographer: Skipped 47 frames! The application may be doing too much work on its main thread. 2020-11-23 12:36:54.187 29196-29230/com.example.sampleexoplayer D/EGL_emulation: eglMakeCurrent: 0xe95f5600: ver 2 0 (tinfo 0xe95e6410) 2020-11-23 12:36:54.300 29196-29230/com.example.sampleexoplayer D/EGL_emulation: eglMakeCurrent: 0xe95f5600: ver 2 0 (tinfo 0xe95e6410) 2020-11-23 12:36:54.326 29196-29230/com.example.sampleexoplayer D/EGL_emulation: eglMakeCurrent: 0xe95f5600: ver 2 0 (tinfo 0xe95e6410) 2020-11-23 12:36:54.488 29196-29246/com.example.sampleexoplayer I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es 2020-11-23 12:36:54.512 29196-29252/com.example.sampleexoplayer I/OMXClient: IOmx service obtained 2020-11-23 12:36:54.527 29196-29251/com.example.sampleexoplayer D/SurfaceUtils: connecting to surface 0xe15d9808, reason connectToSurface 2020-11-23 12:36:54.530 29196-29251/com.example.sampleexoplayer I/MediaCodec: [OMX.google.h264.decoder] setting surface generation to 29896705 2020-11-23 12:36:54.530 29196-29251/com.example.sampleexoplayer D/SurfaceUtils: disconnecting from surface 0xe15d9808, reason connectToSurface(reconnect) 2020-11-23 12:36:54.530 29196-29251/com.example.sampleexoplayer D/SurfaceUtils: connecting to surface 0xe15d9808, reason connectToSurface(reconnect) 2020-11-23 12:36:54.541 29196-29252/com.example.sampleexoplayer E/ACodec: [OMX.google.h264.decoder] setPortMode on output to DynamicANWBuffer failed w/ err -1010 2020-11-23 12:36:54.549 29196-29252/com.example.sampleexoplayer I/ACodec: codec does not support config priority (err -1010) 2020-11-23 12:36:54.596 29196-29256/com.example.sampleexoplayer I/OMXClient: IOmx service obtained 2020-11-23 12:36:54.608 29196-29256/com.example.sampleexoplayer I/ACodec: codec does not support config priority (err -2147483648) 2020-11-23 12:36:54.645 29196-29251/com.example.sampleexoplayer D/MediaCodec: [OMX.google.h264.decoder] setting dataspace on output surface to #11820000 2020-11-23 12:36:54.732 29196-29251/com.example.sampleexoplayer D/eglCodecCommon: allocate: Ask for block of size 0x55000 2020-11-23 12:36:54.733 29196-29251/com.example.sampleexoplayer D/eglCodecCommon: allocate: ioctl allocate returned offset 0x3ff757000 size 0x56000 2020-11-23 12:36:54.797 29196-29251/com.example.sampleexoplayer D/SoftwareRenderer: setting dataspace on output surface to #11820000 2020-11-23 12:36:54.886 29196-29246/com.example.sampleexoplayer D/AudioTrack: getTimestamp_l(79): device stall time corrected using current time 28676291663700 2020-11-23 12:36:54.908 29196-29246/com.example.sampleexoplayer W/AudioTrack: getTimestamp_l(79): retrograde timestamp time corrected, 28676296544800 < 28676303673700 2020-11-23 12:37:02.453 29196-29246/com.example.sampleexoplayer D/AudioTrack: getTimestamp_l(80): device stall time corrected using current time 28683858979400 2020-11-23 12:37:07.002 29196-29246/com.example.sampleexoplayer E/ExoPlayerImplInternal: Source error com.google.android.exoplayer2.ParserException: Invalid NAL length at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readSample(Mp4Extractor.java:542) at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:192) at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:982) at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:919) 2020-11-23 12:37:07.035 29196-29251/com.example.sampleexoplayer D/SurfaceUtils: disconnecting from surface 0xe15d9808, reason disconnectFromSurface 2020-11-23 12:37:07.062 29196-29196/com.example.sampleexoplayer W/System.err: com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.ParserException: Invalid NAL length 2020-11-23 12:37:07.062 29196-29196/com.example.sampleexoplayer W/System.err: at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:394) 2020-11-23 12:37:07.062 29196-29196/com.example.sampleexoplayer W/System.err: at android.os.Handler.dispatchMessage(Handler.java:103) 2020-11-23 12:37:07.062 29196-29196/com.example.sampleexoplayer W/System.err: at android.os.Looper.loop(Looper.java:214) 2020-11-23 12:37:07.062 29196-29196/com.example.sampleexoplayer W/System.err: at android.os.HandlerThread.run(HandlerThread.java:67) 2020-11-23 12:37:07.062 29196-29196/com.example.sampleexoplayer W/System.err: Caused by: com.google.android.exoplayer2.ParserException: Invalid NAL length 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readSample(Mp4Extractor.java:542) 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:192) 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:982) 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391) 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 2020-11-23 12:37:07.063 29196-29196/com.example.sampleexoplayer W/System.err: at java.lang.Thread.run(Thread.java:919) 2020-11-23 12:37:07.132 29196-29230/com.example.sampleexoplayer D/EGL_emulation: eglMakeCurrent: 0xe95f5600: ver 2 0 (tinfo 0xe95e6410) 2020-11-23 12:37:07.152 29196-29230/com.example.sampleexoplayer D/EGL_emulation: eglMakeCurrent: 0xe95f5600: ver 2 0 (tinfo 0xe95e6410)

[REQUIRED] Version of ExoPlayer being used

implementation 'com.google.android.exoplayer:exoplayer:2.11.4'

[REQUIRED] Device(s) and version(s) of Android being used

Issue is reproducible in both emulator and in android devices, not specific to particular OS.

AquilesCanta commented 3 years ago

Hi Kim, mind taking a look at what seems to be an MP4 issue? If it's not, please feel free to reassign to me.

AquilesCanta commented 3 years ago

@rahul-hawge, please check the link, which currently points to an empty project: https://github.com/rahul-hawge/exoplayer-issue-sample.git.

rahul-hawge commented 3 years ago

@AquilesCanta

Just need to switch to master, Here is the path.

https://github.com/rahul-hawge/exoplayer-issue-sample/tree/master

kim-vde commented 3 years ago

The problem is that the Mp4Extractor is unable to split the last video sample into NAL units (as defined in ISO/IEC FDIS 14496-15). When parsing the last sample, it first finds a NAL unit of length 1 byte (which is already suspicious) and then finds a second NAL unit of negative length, causing the exception to be thrown.

The reason is probably that

rahul-hawge commented 3 years ago

@kim-vde Thanks for your response. There are multiple videos in my actual project where this issue occurs. I am not sure to call it a bad media when it plays fine with the other basic media player's like VideoView . Is there any way that we can fix this?

kim-vde commented 3 years ago

It is a bad media in the sense that it doesn't comply to the specifications.

The best way to fix this error is of course to fix the media. If it is not possible, you can use a custom Mp4Extractor where you could for example replace the line throwing the error by return RESULT_END_OF_INPUT;. Custom extractors can be added by passing a custom DefaultExtractorsFactory to the SimpleExoPlayer builder. Note that this solution would only work in the case where the invalid sample is the last one.