-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exoplayer freezes for a couple of secondes on the first buffering state of an HLS video #2096
Comments
It's unclear exactly what you mean here (and the bug report attached doesn't look like a full bug report, as would be obtained from Please could you clarify what you mean by "freeze"? Please also provide logging and a full bug report when reproducing this issue with the demo app, rather than your own, since we know what logging to expect in that case and not in the case of your app. Thanks! |
I have the same problem. v 2.0.4 This is happen in MediaCodec.render / drainOutputBuffer call, but drainOutputBuffer is in while and codec is null after processEndOfStream because of BUFFER_FLAG_END_OF_STREAM. I'm working with single hls provider and i know all stream details, to avoid this i did override of max width, height and buffer values in CodecMaxValues to full hd. I didn't have time to track everything to the root. but looks like async problem. if a stream start from lowest bitrate the processing of the next segment /period/ can happen before playback start .. or something. For example on first call after start AdaptiveVideoTrackSelectionController updateSelectedTrack - currentFormat returns second fragment bitrate. /if there is a bw change/ I hope this info will help. |
@Nelsun - You should ask your HLS provider to include RESOLUTION attributes in the master playlist, or use a provider who does this. Whilst technically optional in the HLS spec, inclusion of RESOLUTION attributes has been recommended for over three years now. If the master playlist contains these attributes then the player will not need to reconfigure the decoder in this way. If the master playlist doesn't contain them then the player has no way of knowing what the maximum resolution is in advance of switching to the highest resolution variant, and may have to perform a (potentially quite expensive) buffer re-allocation when this occurs. @gbadoual - You'll likely find including RESOLUTION attributes in your master playlist also resolves the issue for your stream. @Nelsun - I'm not sure I follow your null pointer exception description. It sounds like something we should definitely fix though. Could you provide more details to help? As I understand it:
It's here that I get lost. processEndOfStream should re-initialize the codec when it calls maybeInitCodec, so codec shouldn't end up null after this call. Could you take a look and see why this isn't happening? The only thing I can think of is if the surface isn't valid, but that sounds pretty strange? |
Please also provide a stack trace for the null pointer exception. Thanks. |
Hi - thanks for the answer and sorry about the delay. In my case - player receiving 3 bandwidths 1, 3, 5 Mbit in order 1, 5, 3 /from m3u8/ I just guess - the first bitrate is actually group.getFormat(0).bitrate - where the list is not sorted Also, you are right about that RESOLUTION is missing in my playlists. And there is NO code exception - all was my fault. Sorry about. |
I can't see how this would ever make a difference, but there's no point in returning true. Either we've really reached EOS (in which case outputStreamEnded will be true and the next drainOutputBuffer will be turned into a no-op) or we've re-initialized the codec (in which case there wont be anything to drain since we wont have fed anything to the codec yet). This change should also prevent the hypothetical NPE described in issue #2096, although we're unsure how that NPE would occur unless MediaCodecRenderer has been extended in an unusual way. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=140338581
@ojw28 The sample HLS URls provided by Apple and included in the Exo samples itself does not contain the RESOLUTION attribute in master playlist. In 1.x Exo, canReconfigureCodec API of MediaCodecVideoTrackRenderer used to only check for current format and new format mime types before it deciding if a reconfiguration is possible or not. Whereas, 2.x sets the max width and max height of the codec based on the maximum width and height provided in streamformats in onStreamChanged API. So it ends up having to re-create codec if the new format is of higher resolution than current. I think one small change that can be done to handle URLs that do not contain RESOLUTION attribute is that in getCodecMaxValues API, the codecMaxValues can be set to the max value support by the platform when the resolution info is missing from the stream codecs. (or do not set the max width and max height values at all in this scenario). Is that an acceptable solution? |
I'm pretty sure there is a check somewhere in V1. The reason playbacks are able to avoid the codec re-instantiation in most cases is because HlsChunkSource hard-codes 1080p in the case that resolution tags were missing (here). I think that approach is quite problematic, since it can cause unnecessary playback failures on devices not supporting resolutions that high. We should probably do as you suggest for V2. A few caveats:
|
I think we can just avoid setting the Max values when RESOLUTION field is missing. Platform decoders will allocate memory for the maximum supported resolution by default.
It's a trade off if the content provider has not set the RESOLUTION. To guarantee optimal memory usage, RESOLUTION must be provided, I agree. |
I don't think that's correct. As I understand it decoders operate in two modes. Decoders that operate in "legacy" mode they allocate for (width,height) or (maxWidth,maxHeight) if specified, and playback will fail if those dimension are exceeded. This is why it's not valid to avoid setting the max values in such cases. Decoders that operate in "non-legacy" mode are able to dynamically re-allocate their output buffers when adaptation occurs, and so don't fail in this case. I suspect these decoders might ignore (maxWidth,maxHeight) even if specified, although I'm not certain about this. Anyway, due to "legacy" mode decoders, not setting the max values and also not re-initializing the decoder when the resolution increases is not an option. We have a change under review that will set (maxWidth,maxHeight) to something sensible, based on standard video resolutions, the aspect ratio of the initial video and the capabilities of the decoder. It'll get merged into |
…are unknown Issue: #2096 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=145542983
The change above sets the maximum resolution to something sensible when the variant resolutions are unknown. Please give it a try on the dev-v2 branch. We're planning to cut a 2.2.0 release containing this fix sometime next week. |
Hi,
We are trying to play smoothly a 4k HLS video,
but it appears that Exoplayer freezes for 3-4 of seconds on the first buffering state.
{NOT_READY}{READY}{PLAYING}{BUFFERING}{FREEZE 3-4 SECONDS}
Then, the video plays properly :
{PLAYING}{BUFFERING}{PLAYING}{BUFFERING}{PLAYING}{BUFFERING}{PLAYING}{BUFFERING}{PLAYING}{BUFFERING}{PLAYING}{BUFFERING}{END}
We try to understand why we have this behavior. We experience it both with Exoplayer 2 and Exoplayer1.5.12
We tried on a Samsung Galaxy S6 and a S7 and experience a similar behavior.
We use Exoplayer as a library to send content to a 360° surface in Unity 5.4.1 but have reproduce the issue in Exoplayer demo app.
You can see here logs reporting State and Exoplayer position.
The freeze comes at position 8106, for approximatively 4 seconds.
We use releasePlayer(), and preparePlayer() at every new load of a video.
Do someone have an explanation or any hint on how to fix this issue.
Thanks in advance,
Adb Logcat :
AdbBugReport.docx
The text was updated successfully, but these errors were encountered: