Open moneytoo opened 2 years ago
Crashed caused by unknown FourCC FMP4. Add FMP4, fixed crash, added test to cover crash.
Changes pushed
Both sample and source video now play just fine.
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.
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
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.
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.
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.
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)
]
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.
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.
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.
I'm getting following error with both source video as well as attached sample.
Sample: pu-15.zip