@@ -18,72 +18,76 @@ Mss.dependencies.MssFragmentController = function() {
1818
1919 var processTfrf = function ( request , tfrf , tfdt , adaptation ) {
2020 var manifest = this . manifestModel . getValue ( ) ,
21- segmentsUpdated = false ,
2221 segments = adaptation . SegmentTemplate . SegmentTimeline . S_asArray ,
2322 timescale = adaptation . SegmentTemplate . timescale ,
2423 entries = tfrf . entry ,
24+ entry ,
2525 segment = null ,
2626 segmentTime ,
2727 t = 0 ,
28- i = 0 ,
2928 availabilityStartTime = null ,
3029 type = adaptation . type ,
3130 range ;
3231
33- // Process tfrf only for live streams
32+ // Process tfrf only for live or start-over streams
3433 if ( ! this . manifestExt . getIsDynamic ( manifest ) && ! this . manifestExt . getIsStartOver ( manifest ) ) {
3534 return ;
3635 }
3736
38- // Go through tfrf entries
37+ if ( entries . length === 0 ) {
38+ return ;
39+ }
40+
41+ // Consider only first tfrf entry (to avoid pre-condition failure on fragment info requests)
42+ entry = entries [ 0 ] ;
43+
3944 // !! For tfrf fragment_absolute_time and fragment_duration are returned as goog.math.Long values (see mp4lib)
40- while ( i < entries . length ) {
41- // Check if time is not greater than Number.MAX_SAFE_INTEGER (2^53-1), see MssParser
42- // => fragment_absolute_timeManifest = original timestamp value as a string (for constructing the fragment request url, see DashHandler)
43- // => fragment_absolute_time = number value of timestamp (maybe rounded value, but only for 0.1 microsecond)
44- if ( entries [ i ] . fragment_absolute_time . greaterThan ( goog . math . Long . fromNumber ( Number . MAX_SAFE_INTEGER ) ) ) {
45- entries [ i ] . fragment_absolute_timeManifest = entries [ i ] . fragment_absolute_time . toString ( ) ;
46- }
4745
48- // Convert goog.math.Long to Number values
49- entries [ i ] . fragment_absolute_time = entries [ i ] . fragment_absolute_time . toNumber ( ) ;
50- entries [ i ] . fragment_duration = entries [ i ] . fragment_duration . toNumber ( ) ;
51-
52- // In case of start-over streams, check if we have reached end of original manifest duration (set in timeShiftBufferDepth)
53- // => then do not update anymore timeline
54- if ( this . manifestExt . getIsStartOver ( manifest ) ) {
55- // Get first segment time
56- segmentTime = segments [ 0 ] . tManifest ? parseFloat ( segments [ 0 ] . tManifest ) : segments [ 0 ] . t ;
57- if ( entries [ i ] . fragment_absolute_time > ( segmentTime + ( manifest . timeShiftBufferDepth * timescale ) ) ) {
58- break ;
59- }
60- }
46+ // Check if time is not greater than Number.MAX_SAFE_INTEGER (2^53-1), see MssParser
47+ // => fragment_absolute_timeManifest = original timestamp value as a string (for constructing the fragment request url, see DashHandler)
48+ // => fragment_absolute_time = number value of timestamp (maybe rounded value, but only for 0.1 microsecond)
49+ if ( entry . fragment_absolute_time . greaterThan ( goog . math . Long . fromNumber ( Number . MAX_SAFE_INTEGER ) ) ) {
50+ entry . fragment_absolute_timeManifest = entry . fragment_absolute_time . toString ( ) ;
51+ }
6152
62- // Get last segment time
63- segmentTime = segments [ segments . length - 1 ] . tManifest ? parseFloat ( segments [ segments . length - 1 ] . tManifest ) : segments [ segments . length - 1 ] . t ;
64- // Check if we have to append new segment to timeline
65- if ( entries [ i ] . fragment_absolute_time > segmentTime ) {
66- this . debug . log ( "[MssFragmentController][" + type + "] Add new segment - t = " + ( entries [ i ] . fragment_absolute_time / timescale ) ) ;
67- segment = { } ;
68- segment . t = entries [ i ] . fragment_absolute_time ;
69- segment . d = entries [ i ] . fragment_duration ;
70- // If timestamps starts at 0 relative to 1st segment (dynamic to static) then update segment time
71- if ( segments [ 0 ] . tManifest ) {
72- segment . t -= parseFloat ( segments [ 0 ] . tManifest ) - segments [ 0 ] . t ;
73- }
74- // Set tManifest either in case of timestamps greater then 2^53 or in case of dynamic to static streams
75- if ( entries [ i ] . fragment_absolute_timeManifest ) {
76- segment . tManifest = entries [ i ] . fragment_absolute_timeManifest ;
77- } else if ( segments [ 0 ] . tManifest ) {
78- segment . tManifest = entries [ i ] . fragment_absolute_time ;
79- }
80- segments . push ( segment ) ;
81- segmentsUpdated = true ;
82- }
53+ // Convert goog.math.Long to Number values
54+ entry . fragment_absolute_time = entry . fragment_absolute_time . toNumber ( ) ;
55+ entry . fragment_duration = entry . fragment_duration . toNumber ( ) ;
56+
57+ // In case of start-over streams, check if we have reached end of original manifest duration (set in timeShiftBufferDepth)
58+ // => then do not update anymore timeline
59+ if ( this . manifestExt . getIsStartOver ( manifest ) ) {
60+ // Get first segment time
61+ segmentTime = segments [ 0 ] . tManifest ? parseFloat ( segments [ 0 ] . tManifest ) : segments [ 0 ] . t ;
62+ if ( entry . fragment_absolute_time > ( segmentTime + ( manifest . timeShiftBufferDepth * timescale ) ) ) {
63+ return ;
64+ }
65+ }
66+
67+ // Get last segment time
68+ segmentTime = segments [ segments . length - 1 ] . tManifest ? parseFloat ( segments [ segments . length - 1 ] . tManifest ) : segments [ segments . length - 1 ] . t ;
8369
84- i += 1 ;
70+ // Check if we have to append new segment to timeline
71+ if ( entry . fragment_absolute_time <= segmentTime ) {
72+ return ;
8573 }
8674
75+ this . debug . log ( "[MssFragmentController][" + type + "] Add new segment - t = " + ( entry . fragment_absolute_time / timescale ) ) ;
76+ segment = { } ;
77+ segment . t = entry . fragment_absolute_time ;
78+ segment . d = entry . fragment_duration ;
79+ // If timestamps starts at 0 relative to 1st segment (dynamic to static) then update segment time
80+ if ( segments [ 0 ] . tManifest ) {
81+ segment . t -= parseFloat ( segments [ 0 ] . tManifest ) - segments [ 0 ] . t ;
82+ }
83+ // Set tManifest either in case of timestamps greater then 2^53 or in case of dynamic to static streams
84+ if ( entry . fragment_absolute_timeManifest ) {
85+ segment . tManifest = entry . fragment_absolute_timeManifest ;
86+ } else if ( segments [ 0 ] . tManifest ) {
87+ segment . tManifest = entry . fragment_absolute_time ;
88+ }
89+ segments . push ( segment ) ;
90+
8791 // In case of static start-over streams, update content duration
8892 if ( this . manifestExt . getIsStartOver ( manifest ) ) {
8993 if ( type === 'video' ) {
@@ -95,48 +99,21 @@ Mss.dependencies.MssFragmentController = function() {
9599 }
96100 return ;
97101 }
98-
99- // Update segment timeline in case the timestamps from tfrf differ from timestamps in Manifest.
100- // In that case we consider tfrf timing
101- // var j = 0,
102- // segmentId = -1,
103- // for (j = segments.length - 1; j >= 0; j -= 1) {
104- // if (segments[j].t === tfdt.baseMediaDecodeTime) {
105- // segmentId = j;
106- // break;
107- // }
108- // }
109- // if (segmentId >= 0) {
110- // for (i = 0; i < entries.length; i += 1) {
111- // if (segmentId + i < segments.length) {
112- // t = segments[segmentId + i].t;
113- // if ((t + segments[segmentId + i].d) !== entries[i].fragment_absolute_time) {
114- // segments[segmentId + i].t = entries[i].fragment_absolute_time;
115- // segments[segmentId + i].d = entries[i].fragment_duration;
116- // this.debug.log("[MssFragmentController] Correct tfrf time = " + entries[i].fragment_absolute_time + " and duration = " + entries[i].fragment_duration);
117- // segmentsUpdated = true;
118- // }
119- // }
120- // }
121- // }
122-
123- // Update segment timeline according to DVR window
124- if ( manifest . timeShiftBufferDepth && manifest . timeShiftBufferDepth > 0 ) {
125- if ( segmentsUpdated ) {
126- // Get timestamp of the last segment
127- segment = segments [ segments . length - 1 ] ;
128- t = segment . t ;
129-
130- // Determine the segments' availability start time
131- availabilityStartTime = t - ( manifest . timeShiftBufferDepth * timescale ) ;
132-
133- // Remove segments prior to availability start time
102+ // In case of live streams, update segment timeline according to DVR window
103+ else if ( manifest . timeShiftBufferDepth && manifest . timeShiftBufferDepth > 0 ) {
104+ // Get timestamp of the last segment
105+ segment = segments [ segments . length - 1 ] ;
106+ t = segment . t ;
107+
108+ // Determine the segments' availability start time
109+ availabilityStartTime = t - ( manifest . timeShiftBufferDepth * timescale ) ;
110+
111+ // Remove segments prior to availability start time
112+ segment = segments [ 0 ] ;
113+ while ( segment . t < availabilityStartTime ) {
114+ this . debug . log ( "[MssFragmentController][" + type + "] Remove segment - t = " + ( segment . t / timescale ) ) ;
115+ segments . splice ( 0 , 1 ) ;
134116 segment = segments [ 0 ] ;
135- while ( segment . t < availabilityStartTime ) {
136- this . debug . log ( "[MssFragmentController][" + type + "] Remove segment - t = " + ( segment . t / timescale ) ) ;
137- segments . splice ( 0 , 1 ) ;
138- segment = segments [ 0 ] ;
139- }
140117 }
141118
142119 // Update DVR window range => set range's end to end time of current segment
@@ -159,8 +136,7 @@ Mss.dependencies.MssFragmentController = function() {
159136 traf = null ,
160137 tfdt = null ,
161138 tfrf = null ,
162- pos ,
163- i = 0 ;
139+ pos ;
164140
165141 // Create new fragment
166142 fragment = mp4lib . deserialize ( bytes ) ;
@@ -188,9 +164,7 @@ Mss.dependencies.MssFragmentController = function() {
188164 }
189165 } ;
190166 } else {
191- for ( i = 0 ; i < tfrf . length ; i += 1 ) {
192- processTfrf . call ( this , request , tfrf [ i ] , tfdt , adaptation ) ;
193- }
167+ processTfrf . call ( this , request , tfrf [ 0 ] , tfdt , adaptation ) ;
194168 }
195169 } ,
196170
@@ -354,8 +328,8 @@ Mss.dependencies.MssFragmentController = function() {
354328 traf . boxes . splice ( pos + 1 , 0 , tfdt ) ;
355329 }
356330
357- // Process tfrf box
358331 if ( manifest . type === 'dynamic' ) {
332+ // Process tfrf box
359333 tfrf = traf . getBoxesByType ( "tfrf" ) ;
360334 if ( tfrf === null || tfrf . length === 0 ) {
361335 throw {
@@ -366,10 +340,8 @@ Mss.dependencies.MssFragmentController = function() {
366340 }
367341 } ;
368342 } else {
369- for ( i = 0 ; i < tfrf . length ; i += 1 ) {
370- processTfrf . call ( this , request , tfrf [ i ] , tfdt , adaptation ) ;
371- traf . removeBoxByType ( "tfrf" ) ;
372- }
343+ processTfrf . call ( this , request , tfrf [ 0 ] , tfdt , adaptation ) ;
344+ traf . removeBoxByType ( "tfrf" ) ;
373345 }
374346 }
375347
0 commit comments