@@ -19,19 +19,19 @@ Mss.dependencies.MssFragmentController = function() {
1919 var processTfrf = function ( request , tfrf , tfdt , adaptation ) {
2020 var manifest = this . manifestModel . getValue ( ) ,
2121 segmentsUpdated = false ,
22- // Get adaptation's segment timeline (always a SegmentTimeline in Smooth Streaming use case)
23- segments = adaptation . SegmentTemplate . SegmentTimeline . S ,
22+ segments = adaptation . SegmentTemplate . SegmentTimeline . S_asArray ,
23+ timescale = adaptation . SegmentTemplate . timescale ,
2424 entries = tfrf . entry ,
2525 segment = null ,
26+ segmentTime ,
2627 t = 0 ,
2728 i = 0 ,
28- // j = 0,
29- // segmentId = -1,
3029 availabilityStartTime = null ,
30+ type = adaptation . type ,
3131 range ;
3232
3333 // Process tfrf only for live streams
34- if ( manifest . type !== 'dynamic' ) {
34+ if ( ! this . manifestExt . getIsDynamic ( manifest ) && ! this . manifestExt . getIsStartOver ( manifest ) ) {
3535 return ;
3636 }
3737
@@ -49,13 +49,33 @@ Mss.dependencies.MssFragmentController = function() {
4949 entries [ i ] . fragment_absolute_time = entries [ i ] . fragment_absolute_time . toNumber ( ) ;
5050 entries [ i ] . fragment_duration = entries [ i ] . fragment_duration . toNumber ( ) ;
5151
52- if ( entries [ i ] . fragment_absolute_time > segments [ segments . length - 1 ] . t ) {
53- this . debug . log ( "[MssFragmentController] Add new segment - t = " + ( entries [ i ] . fragment_absolute_time / 10000000.0 ) ) ;
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+ }
61+
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 ) ) ;
5467 segment = { } ;
5568 segment . t = entries [ i ] . fragment_absolute_time ;
5669 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
5775 if ( entries [ i ] . fragment_absolute_timeManifest ) {
5876 segment . tManifest = entries [ i ] . fragment_absolute_timeManifest ;
77+ } else if ( segments [ 0 ] . tManifest ) {
78+ segment . tManifest = entries [ i ] . fragment_absolute_time ;
5979 }
6080 segments . push ( segment ) ;
6181 segmentsUpdated = true ;
@@ -64,8 +84,22 @@ Mss.dependencies.MssFragmentController = function() {
6484 i += 1 ;
6585 }
6686
87+ // In case of static start-over streams, update content duration
88+ if ( this . manifestExt . getIsStartOver ( manifest ) ) {
89+ if ( type === 'video' ) {
90+ segment = segments [ segments . length - 1 ] ;
91+ var end = ( segment . t + segment . d ) / timescale ;
92+ if ( end > this . videoModel . getDuration ( ) ) {
93+ this . system . notify ( "sourceDurationChanged" , end ) ;
94+ }
95+ }
96+ return ;
97+ }
98+
6799 // Update segment timeline in case the timestamps from tfrf differ from timestamps in Manifest.
68100 // In that case we consider tfrf timing
101+ // var j = 0,
102+ // segmentId = -1,
69103 // for (j = segments.length - 1; j >= 0; j -= 1) {
70104 // if (segments[j].t === tfdt.baseMediaDecodeTime) {
71105 // segmentId = j;
@@ -88,18 +122,18 @@ Mss.dependencies.MssFragmentController = function() {
88122
89123 // Update segment timeline according to DVR window
90124 if ( manifest . timeShiftBufferDepth && manifest . timeShiftBufferDepth > 0 ) {
91- if ( segmentsUpdated && manifest . startOver !== true ) {
125+ if ( segmentsUpdated ) {
92126 // Get timestamp of the last segment
93127 segment = segments [ segments . length - 1 ] ;
94128 t = segment . t ;
95129
96130 // Determine the segments' availability start time
97- availabilityStartTime = t - ( manifest . timeShiftBufferDepth * 10000000 ) ;
131+ availabilityStartTime = t - ( manifest . timeShiftBufferDepth * timescale ) ;
98132
99133 // Remove segments prior to availability start time
100134 segment = segments [ 0 ] ;
101135 while ( segment . t < availabilityStartTime ) {
102- this . debug . log ( "[MssFragmentController] Remove segment - t = " + ( segment . t / 10000000.0 ) ) ;
136+ this . debug . log ( "[MssFragmentController][" + type + "] Remove segment - t = " + ( segment . t / timescale ) ) ;
103137 segments . splice ( 0 , 1 ) ;
104138 segment = segments [ 0 ] ;
105139 }
@@ -116,7 +150,7 @@ Mss.dependencies.MssFragmentController = function() {
116150 }
117151 }
118152
119- return segmentsUpdated ;
153+ return ;
120154 } ,
121155
122156 updateSegmentsList = function ( bytes , request , adaptation ) {
@@ -413,6 +447,8 @@ Mss.dependencies.MssFragmentController = function() {
413447 rslt . manifestModel = undefined ;
414448 rslt . manifestExt = undefined ;
415449 rslt . metricsModel = undefined ;
450+ rslt . videoModel = undefined ;
451+ rslt . mediaSourceExt = undefined ;
416452
417453 rslt . process = function ( bytes , request , representation ) {
418454 var deferred = Q . defer ( ) ,
0 commit comments