Exoplayer: Error when using multiple SimpleExoPlayer instances share the same Cache instances (SimpleCache)

Created on 28 Jan 2018  路  11Comments  路  Source: google/ExoPlayer

Issue description

The following Exception is thrown with I tried to use SimpleCache with multiple SimpleExoPlayer:

6439-6696/packagename E/LoadTask: Unexpected exception loading stream
                                          java.lang.IllegalStateException: Top bit not zero: -2021886842
                                              at com.google.android.exoplayer2.util.ParsableByteArray.readUnsignedIntToInt(ParsableByteArray.java:388)
                                              at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readSample(Mp4Extractor.java:474)
                                              at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:179)
                                              at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:749)
                                              at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:315)
                                              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
                                              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
                                              at java.lang.Thread.run(Thread.java:764)
6439-6538/packagename E/ExoPlayerImplInternal: Source error.
                                                       com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected IllegalStateException: Top bit not zero: -2021886842
                                                           at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:337)
                                                           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
                                                           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
                                                           at java.lang.Thread.run(Thread.java:764)
                                                        Caused by: java.lang.IllegalStateException: Top bit not zero: -2021886842
                                                           at com.google.android.exoplayer2.util.ParsableByteArray.readUnsignedIntToInt(ParsableByteArray.java:388)
                                                           at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readSample(Mp4Extractor.java:474)
                                                           at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:179)
                                                           at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:749)
                                                           at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:315)
                                                           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)聽
                                                           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)聽
                                                           at java.lang.Thread.run(Thread.java:764)聽
6439-6703/packagename D/SurfaceUtils: disconnecting from surface 0x79fc077010, reason disconnectFromSurface

The term "multiple" is my assumption, as in this demo, I used a pool with a factory method that uses a fixed Cache (as factory option) to create SimpleExoPlayer instances on demand and cache for reuse. This is not always reproducible but the rate of failure is high.

When the Cache is set to null I get no error.

Link to test content

All videos are get from this link (the video/mp4 variants, not webm)

https://material.io/guidelines/motion/material-motion.html

Version of ExoPlayer being used: 2.6.1

Device(s) and version(s) of Android being used: Nexus 5X, Android 27 (8.1).

I can provide the code for various part if need. But hope the log above says something.

bug

Most helpful comment

Yeah; @erdemguven found a bug that could cause corrupt data to be written into the cache. A fix will be available next week or early the week after.

All 11 comments

Are you creating more than one SimpleCache instance, or are you creating a single global SimpleCache that's accessed by multiple CacheDataSource instances?

To clarify, I'm unclear what "same Cache instances" means. Is there more than one Cache being shared? If so, how does this work exactly?

@ojw28 One global SimpleCache instance, and one CacheDataSourceFactory passed to create SimpleExoPlayer instance. So I suppose it is this:

a single global SimpleCache that's accessed by multiple CacheDataSource instances

@ojw28 Answer your question above, let me create a snippet and send you/update here later today.

That should work. I think you'll need to provide us with a concrete way to reproduce the issue (preferably a small patch to the demo app that is able to reproduce the problem). Thanks.

@ojw28 This issue is quite difficult to reproduce at high rate. Right now what I have in hand is: all the cach files (.v3.exo files, and the index file), the Url that have this issue and the code I used to test (simplified version, but works/fails all the time). Do you think these pieces of info can help you to investigate?

@ojw28 Here is the repo where you can try and see the issues, works all the time (I have included the start guide in README, make sure you follow it): https://github.com/eneim/DrExo . Hope this helps ^^!

The cached file differs from the source media in some places (see the diff below), which is why playback is failing. Unfortunately this doesn't really help to explain how you're getting into that state. I'm unable to do so, despite repeated attempts.

Starting from an empty cache, do you have any idea how I might manage to reproduce actually writing the corrupt data into the cache? And are you sure this didn't occur as a result of some development version of your app that did something incorrect (e.g. multiple cache instances accessing the same directory)?

diff

@ojw28 just see the label bug, I guess you have found something. But even if it is not the case, I'm trying to read and log the call order of cache's methods. Hope to figure out something helpful.

Yeah; @erdemguven found a bug that could cause corrupt data to be written into the cache. A fix will be available next week or early the week after.

The fix ref'd above should resolve this issue, and will be picked up in the next release. Please let us know if you're able to reproduce, either with the current dev-v2 branch, or any future tagged release.

Was this page helpful?
0 / 5 - 0 ratings