dburckh / ExoPlayer

Deprecated. See https://github.com/dburckh/Media3Avi
Apache License 2.0
3 stars 2 forks source link

Playback error #10

Open moneytoo opened 2 years ago

moneytoo commented 2 years ago

I'm getting following error with both source video as well as attached sample.

2022-01-29 14:03:08.322 26842-1316/com.google.android.exoplayer2.demo E/LoadTask: Unexpected exception loading stream
      java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.google.android.exoplayer2.extractor.avi.AviTrack.handlesChunkId(int)' on a null object reference
        at com.google.android.exoplayer2.extractor.avi.AviExtractor.getAviTrack(AviExtractor.java:474)
        at com.google.android.exoplayer2.extractor.avi.AviExtractor.readSamples(AviExtractor.java:518)
        at com.google.android.exoplayer2.extractor.avi.AviExtractor.read(AviExtractor.java:538)
        at com.google.android.exoplayer2.source.BundledExtractorsAdapter.read(BundledExtractorsAdapter.java:127)
        at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1042)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:409)
        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:920)

Sample: pu-15.zip

dburckh commented 2 years ago

Crashed caused by unknown FourCC FMP4. Add FMP4, fixed crash, added test to cover crash.

Changes pushed

moneytoo commented 2 years ago

Both sample and source video now play just fine.

rgrk11 commented 2 years ago

Hi @dburckh, thank you for your excellent work.

I'd like to report that, after applying your latest commit 5f76e0f, I am still failing to play the above pu-15.avi and pyth.avi in #9 (both of which has mp3 audio from MediaInfo) on my pixel 4a5G.

For pu-15.avi:

2022-02-01 14:56:47.670 12164-12414/com.google.android.exoplayer2.demo I/AviExtractor: Video chunks=450 us=15012009
2022-02-01 14:56:47.670 12164-12414/com.google.android.exoplayer2.demo I/AviExtractor: Audio #1 chunks: 625 us=15000000 size=306816
2022-02-01 14:56:47.670 12164-12414/com.google.android.exoplayer2.demo W/AviExtractor: Audio is not all key frames chunks=625 keyFrames=538
2022-02-01 14:56:48.003 12164-12164/com.google.android.exoplayer2.demo E/EventLogger: playerFailed [eventTime=0.43, mediaPos=0.00, window=0, period=0, errorCode=ERROR_CODE_DECODING_FAILED
      com.google.android.exoplayer2.ExoPlaybackException: MediaCodecAudioRenderer error, index=2, format=Format(1, null, null, audio/mpeg, null, -1, null, [-1, -1, -1.0], [2, 48000]), format_supported=YES
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:573)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecDecoderException: Decoder failed: c2.android.mp3.decoder
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.createDecoderException(MediaCodecRenderer.java:929)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:810)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:996)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:497)
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
     Caused by: java.lang.IllegalStateException
        at android.media.MediaCodec.native_queueInputBuffer(Native Method)
        at android.media.MediaCodec.queueInputBuffer(MediaCodec.java:2559)
        at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.queueInputBuffer(SynchronousMediaCodecAdapter.java:143)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:1345)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:791)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:996) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:497) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
    ]

For pyth.avi:

2022-02-01 14:59:31.364 12164-12494/com.google.android.exoplayer2.demo W/AviExtractor: Unknown Track Type: 7Fxx
2022-02-01 14:59:31.412 12164-12494/com.google.android.exoplayer2.demo I/AviExtractor: Video chunks=103644 us=4145760000
2022-02-01 14:59:31.412 12164-12494/com.google.android.exoplayer2.demo I/AviExtractor: Audio #1 chunks: 4146 us=4145640000 size=66330240
2022-02-01 14:59:31.420 12164-12494/com.google.android.exoplayer2.demo W/AviExtractor: Unknown tag=ix00 pos=64680 size=32024 moviEnd=1048799404
2022-02-01 14:59:31.428 12164-12494/com.google.android.exoplayer2.demo W/AviExtractor: Unknown tag=ix01 pos=96712 size=32024 moviEnd=1048799404
2022-02-01 14:59:31.725 12164-12164/com.google.android.exoplayer2.demo E/EventLogger: playerFailed [eventTime=0.40, mediaPos=0.00, window=0, period=0, errorCode=ERROR_CODE_DECODING_FAILED
      com.google.android.exoplayer2.ExoPlaybackException: MediaCodecAudioRenderer error, index=2, format=Format(1, null, null, audio/mpeg, null, -1, null, [-1, -1, -1.0], [2, 48000]), format_supported=YES
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:573)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecDecoderException: Decoder failed: c2.android.mp3.decoder
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.createDecoderException(MediaCodecRenderer.java:929)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:810)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:996)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:497)
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
     Caused by: java.lang.IllegalStateException
        at android.media.MediaCodec.native_queueInputBuffer(Native Method)
        at android.media.MediaCodec.queueInputBuffer(MediaCodec.java:2559)
        at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.queueInputBuffer(SynchronousMediaCodecAdapter.java:143)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:1345)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:791)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:996) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:497) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
    ]

I've also encountered similar error messages on Android studio emulator (API 29) and my Essential ph-1, except that the audio decoder used is OMX.google.mp3.decoder.

Note however that my Samsung tab s6 lite is able to play the above two avi files successfully. Not sure if Samsung devices can handle these files better, as I noticed that you are using S20.

dburckh commented 2 years ago

I have issues on my 3a too. The MP4-es decoder is extremely limited on my 3a. I don't have the exact number but it reports it doesn't even support SD. Exo will generally ignore this and try anyway. Maybe it's the same issue on the 4a? See this line below from my 3a.

[X] Track:0, id=0, mimeType=video/mp4v-es, res=720x480, fps=29.976, supported=NO_EXCEEDS_CAPABILITIES

What I don't understand is why the audio doesn't at least play. I looked at the raw file and the packet muxing looks fine. I demuxed the audio to MP3 and it plays fine. I'm going to re-open this and look

rgrk11 commented 2 years ago

Maybe it's the same issue on the 4a?

Yes, my 4a5G has exactly the same issue, but as you said, exoplayer will always try to play even in this scenario. For example in exoplayer demo app, if you resume the playback after setting audio to none via select tracks button, the video will play just fine. Therefore, it seems that something is wrong in the audio part.

dburckh commented 2 years ago

So, I did a little research on this one. Neither play on my Pixel 3a. It looks like the 3a uses a software MP3 renderer: https://android.googlesource.com/platform/frameworks/av/+/master/media/codec2/components/mp3/C2SoftMp3Dec.cpp

It's crashing with this error: "Error in parse mp3 header during outSize estimation." That's around line 292. What that really means, I have no clue. I assume it has something to do with key frame synchronization. In general, this guy seems to be more picky than the ones used by my Moto X/Note S20, which play fine.

Both of these files are weird from a muxing standpoint. pu-15.avi has a massive mp3 chunk followed by a bunch of empty frames. pyth.avi is muxed wrong and it's miracle it plays on any device. All the audio frames are 16K and marked as key frames, but only the first frame is truly a key frame.

All that said, the only way to fix this is to remux the file or write some sort of MP3 specific code that parses the stream and fixes it on the fly. I do have an issue out there that is somewhat related and I'll link in this thread, but for the moment, this is a case of GIGO.

dburckh commented 2 years ago

The "everything" branch now has a fix for the poorly muxed mp3 files. I'm still seeing sync issues with pu-15.avi on my Pixel 3a, but I believe that is a device issue as the output timestamps appear correct.

rgrk11 commented 2 years ago

Your latest fix works for the above two avi files. Thanks.

I'm still seeing sync issues with pu-15.avi on my Pixel 3a

FYI, my pixel 4a5G suffers from the same problem too.

However, for pyth.avi I can quite easily reproduce the following playback failure if I pressed time bar of the demo app rapidly to seek forward few times.

2022-02-05 15:53:02.987 6697-6905/com.google.android.exoplayer2.demo W/AviExtractor: Unknown Track Type: 7Fxx
2022-02-05 15:53:03.117 6697-6905/com.google.android.exoplayer2.demo I/AviExtractor: Video chunks=103644 us=4145760000
2022-02-05 15:53:03.117 6697-6905/com.google.android.exoplayer2.demo I/AviExtractor: Audio #1 chunks: 4146 us=4145640000 size=66330240
2022-02-05 15:53:03.199 6697-6905/com.google.android.exoplayer2.demo W/AviExtractor: Unknown tag=ix00 pos=96704 size=32024 moviEnd=1048799404
2022-02-05 15:53:03.199 6697-6905/com.google.android.exoplayer2.demo W/AviExtractor: Unknown tag=ix01 pos=128736 size=32024 moviEnd=1048799404
2022-02-05 15:53:16.757 6697-6905/com.google.android.exoplayer2.demo W/AviExtractor: Unknown tag=ix00 pos=344972172 size=32024 moviEnd=1048799404
2022-02-05 15:53:21.486 6697-6697/com.google.android.exoplayer2.demo E/EventLogger: playerFailed [eventTime=18.69, mediaPos=2172.35, window=0, period=0, errorCode=ERROR_CODE_IO_UNSPECIFIED
      com.google.android.exoplayer2.ExoPlaybackException: Source error
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:639)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:214)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected ArrayIndexOutOfBoundsException: length=65536; regionStart=476; regionLength=-116
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:430)
        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)
     Caused by: java.lang.ArrayIndexOutOfBoundsException: length=65536; regionStart=476; regionLength=-116
        at libcore.util.ArrayUtils.throwsIfOutOfBounds(ArrayUtils.java:40)
        at libcore.io.IoBridge.read(IoBridge.java:508)
        at java.io.FileInputStream.read(FileInputStream.java:313)
        at com.google.android.exoplayer2.upstream.ContentDataSource.read(ContentDataSource.java:181)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.read(DefaultDataSource.java:263)
        at com.google.android.exoplayer2.upstream.cache.CacheDataSource.read(CacheDataSource.java:612)
        at com.google.android.exoplayer2.upstream.StatsDataSource.read(StatsDataSource.java:92)
        at com.google.android.exoplayer2.extractor.DefaultExtractorInput.readFromUpstream(DefaultExtractorInput.java:291)
        at com.google.android.exoplayer2.extractor.DefaultExtractorInput.read(DefaultExtractorInput.java:68)
        at com.google.android.exoplayer2.source.SampleDataQueue.sampleData(SampleDataQueue.java:178)
        at com.google.android.exoplayer2.source.SampleQueue.sampleData(SampleQueue.java:590)
        at com.google.android.exoplayer2.extractor.TrackOutput.sampleData(TrackOutput.java:153)
        at com.google.android.exoplayer2.extractor.avi.Mp3ChunkHandler.process(Mp3ChunkHandler.java:109)
        at com.google.android.exoplayer2.extractor.avi.Mp3ChunkHandler.resume(Mp3ChunkHandler.java:63)
        at com.google.android.exoplayer2.extractor.avi.AviExtractor.readChunks(AviExtractor.java:500)
        at com.google.android.exoplayer2.extractor.avi.AviExtractor.read(AviExtractor.java:555)
        at com.google.android.exoplayer2.source.BundledExtractorsAdapter.read(BundledExtractorsAdapter.java:127)
        at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1042)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:409)
        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) 
    ]
dburckh commented 2 years ago

I remember writing the code that found the next header on seek. I said to myself, there will never be a frame smaller than 128 bytes. Whelp, that's why you should never AssUMe. The max read size is now 16. I assume there will never be a frame smaller than that. :)

Also flushed the codec buffer on seek. That didn't appear to be the problem, but it seemed like a good idea.

Code pushed.

rgrk11 commented 2 years ago

Works fine now. Thanks.

Below is my another question.

To test with more avi files, I've been playing around an open source video editor called "Avidemux". The video stream of one converted file (pu-15_edit.zip), which is marked as DivX 4 by MediaInfo, cannot be properly detected by exoplayer. Eventually, this issue seems to be fixed by adding STREAM_MAP.put('D' | ('I' << 8) | ('V' << 16) | ('X' << 24), mimeType); to VideoFormat. So I wonder if it is reasonable to add it to your patch.

dburckh commented 2 years ago

Yeah, there seems to be a never ending list of FourCCs for Divx. Added it and pushed the changes. Let me know if you find any more.

I've been using Avidemux as well, it seems to be the best and easiest to use.