Skip to content

Commit 0602cff

Browse files
H-LHadrien Lepoutre
andauthored
Fix multiple memory leaks on Cta608Parser and ResizeObserver (Dash-Industry-Forum#5042)
* fix: Memory leak from Cta608Parser on player.reset() / player.destroy() * fix: Memory leaks due to VideoModel not reseting + its ResizeObserver and element retention * fix: Move memory leaks fixes to destroy, not reset --------- Co-authored-by: Hadrien Lepoutre <hadrien.lepoutre.ext@francetv.fr>
1 parent 73c1f2b commit 0602cff

3 files changed

Lines changed: 50 additions & 4 deletions

File tree

src/dash/DashAdapter.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,10 @@ function DashAdapter() {
861861
voPeriods = [];
862862
}
863863

864+
function destroy() {
865+
cea608parser = null;
866+
}
867+
864868
/**
865869
* Checks if the given Preselection is from the given media type
866870
* @param {object} preselection
@@ -1315,6 +1319,7 @@ function DashAdapter() {
13151319
applyPatchToManifest,
13161320
areMediaInfosEqual,
13171321
convertAdaptationToMediaInfo,
1322+
destroy,
13181323
getAllMediaInfoForType,
13191324
getAvailabilityStartTime,
13201325
getBandwidthForRepresentation,

src/streaming/MediaPlayer.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,16 @@ function MediaPlayer() {
494494
*/
495495
function destroy() {
496496
reset();
497+
498+
if (videoModel) {
499+
videoModel.destroy();
500+
videoModel = null;
501+
}
502+
503+
if (adapter) {
504+
adapter.destroy();
505+
}
506+
497507
FactoryMaker.deleteSingletonInstances(context);
498508
}
499509

src/streaming/models/VideoModel.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,19 @@ function VideoModel() {
9494
_disposeResizeObserver();
9595
}
9696

97+
function destroy() {
98+
reset();
99+
element = null;
100+
TTMLRenderingDiv = null;
101+
vttRenderingDiv = null;
102+
}
103+
97104
function _disposeResizeObserver() {
98105
try {
99106
if (resizeObserver && element) {
100107
resizeObserver.unobserve(element);
108+
}
109+
if (resizeObserver) {
101110
resizeObserver.disconnect();
102111
resizeObserver = null;
103112
}
@@ -208,13 +217,25 @@ function VideoModel() {
208217
}
209218

210219
function setElement(value) {
220+
// In case there was already an element stored in model
221+
const isNewElement = element !== value;
222+
if (element && !isNewElement) {
223+
return;
224+
}
225+
226+
_unregisterResizeObserver(element);
227+
element = value;
228+
211229
//add check of value type
212-
if (value === null || value === undefined || (value && (/^(VIDEO|AUDIO)$/i).test(value.nodeName))) {
213-
element = value;
230+
if (value === null || value === undefined) {
231+
return;
232+
}
233+
234+
if (value && /^(VIDEO|AUDIO)$/i.test(value.nodeName)) {
214235
_registerResizeObserver(element);
215-
} else {
216-
throw VIDEO_MODEL_WRONG_ELEMENT_TYPE;
236+
return;
217237
}
238+
throw VIDEO_MODEL_WRONG_ELEMENT_TYPE;
218239
}
219240

220241
function _registerResizeObserver(element) {
@@ -228,6 +249,15 @@ function VideoModel() {
228249
}
229250
}
230251

252+
function _unregisterResizeObserver(element) {
253+
try {
254+
if (!resizeObserver || !element) {
255+
return;
256+
}
257+
resizeObserver.unobserve(element);
258+
} catch (e) {}
259+
}
260+
231261
function setSource(source) {
232262
if (element) {
233263
if (source) {
@@ -557,6 +587,7 @@ function VideoModel() {
557587
addEventListener,
558588
addTextTrack,
559589
appendChild,
590+
destroy,
560591
getBufferRange,
561592
getClientHeight,
562593
getClientWidth,

0 commit comments

Comments
 (0)