-
Notifications
You must be signed in to change notification settings - Fork 2.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
Memory leaks during playback of HEVC / H.265 / HEV1 / HVC1 HLS stream packaged into MPEG-TS (.ts files) #6683
Comments
Apparently, editing if (this.initVPS !== null || track.pps.length === 0) {
track.pps.push(unit.data);
} with if (this.initVPS !== null || track.pps.length === 0) {
const arrayCopy = new Uint8Array(unit.data.length);
arrayCopy.set(unit.data);
track.pps.push(arrayCopy);
}
|
@devoldemar Can you take a look at this issue? For AVC we just use the last PPS hls.js/src/demux/video/avc-video-parser.ts Lines 145 to 151 in 45696be
This issue may be related to the SPS handling in that it is responsible for resetting the SPS and PPS data but will not do so if it matches earlier data: hls.js/src/demux/video/hevc-video-parser.ts Lines 133 to 146 in 45696be
Regardless, that does not stop more pps data from getting added: hls.js/src/demux/video/hevc-video-parser.ts Lines 158 to 159 in 45696be
hls.js/src/demux/video/hevc-video-parser.ts Lines 183 to 184 in 45696be
If all TS segments contain the same SPS and PSS won't this code keep pushing the same data to to those arrays leading to the described leak? |
@izogfif @robwalch Sorry for the delay. Unlike AVC, in HEVC parser we definitely have to handle a case with several SPS and PPS in the decoder configuration record. If VPS+SPS+PPS are retransmitted, but not used to re-generate initial segment, SPS and PPS arrays should be left intact. In case of SPS I added the following condition (new VPS must be used as initVPS): |
What version of Hls.js are you using?
master / 1.6.0
What browser (including version) are you using?
Google Chrome 128.0.6613.120 (Official Build) (32-bit) from PortableApps
What OS (including version) are you using?
Microsoft Windows 11 Version 22H2 (OS Build 22621.3155)
Test stream
No response
Configuration
Additional player setup steps
Here are notes that I couldn't put anywhere else.
Try this:
Investigations show that
TSDemuxer
instance used for video track (de)muxing contains large amount of references to (slices of) fragment / segment / chunks of UInt8Array, presumably with video data in its_videoTrack.pps
field / member.For example, if
window.hls
represents reference to HLS instance, thenwindow.hls.streamController.transmuxer.transmuxer.demuxer._videoTrack.pps
is the thing that keeps references to a huge number of UInt8Array instances and doesn't let browser destroy / GC them.The length of
pps
steadily grows during the entire duration of playback. For Sintel (see below) the size of this array reaches 878 elements. For longer videos (e.g. around 1 hour with the same bitrate) it can reach as large as 7802 elements before browser tab crashes with "Out of memory" error.It should be noted that the size of the used portions of
UInt8Array
whose references are stored inpps
is pretty small:window.hls.streamController.transmuxer.transmuxer.demuxer._videoTrack.pps.map(x => x.byteLength).reduce((a, b) => a + b, 0)
says that combined size of all used portions of all arrays is just 5268 bytes (like, just 6 bytes per item).But the total size of all underlying buffers which these UInt8Arrays take data from is huge:
window.hls.streamController.transmuxer.transmuxer.demuxer._videoTrack.pps.map(x => x.buffer.byteLength).reduce((a, b) => a + b, 0)
is whopping 799,707,013 bytes (almost 800 megabytes) - around 900 kilobytes per item.Notes
Checklist
Steps to reproduce
main
branch.cd
into cloned repository's folder.npm install
npm run serve
Obtaining sample files for sample HLS stream
Option one: from repository
Checkout the repository containing sample stream files (at the moment of writing it's still being uploaded).
Option two: create stream manually
ffmpeg
Key frames are placed every 24 frames (i.e. each second). Fragment length is 2 seconds. Only video stream is selected (no audio) because video is the one that's causing memory issues. Bitrate is chosen high to match the bitrate of original video and also because it produces more noticeable results during test for memory leaks (i.e. errors happen sooner, browser crashes faster).
Expected behaviour
What actually happened?
One of the following issues occurs:
Console output
Chrome media internals output
The text was updated successfully, but these errors were encountered: