@@ -43,7 +43,9 @@ var SubtitlesOctopus = function (options) {
43
43
self . oneshotState = {
44
44
eventStart : null ,
45
45
eventOver : false ,
46
- iteration : 0
46
+ iteration : 0 ,
47
+ renderRequested : false ,
48
+ requestNextTimestamp : - 1
47
49
}
48
50
49
51
self . hasAlphaBug = false ;
@@ -175,6 +177,7 @@ var SubtitlesOctopus = function (options) {
175
177
self . video = video ;
176
178
if ( self . video ) {
177
179
if ( self . renderAhead > 0 ) {
180
+ console . debug ( 'starting oneshot render because new video detected' ) ;
178
181
window . requestAnimationFrame ( oneshotRender ) ;
179
182
tryRequestOneshot ( ) ;
180
183
}
@@ -266,8 +269,9 @@ var SubtitlesOctopus = function (options) {
266
269
return removed ;
267
270
}
268
271
269
- function tryRequestOneshot ( currentTime ) {
272
+ function tryRequestOneshot ( currentTime , postIfBusy ) {
270
273
if ( ! self . renderAhead || self . renderAhead <= 0 ) return ;
274
+ if ( self . oneshotState . renderRequested && ! postIfBusy ) return ;
271
275
272
276
if ( typeof currentTime === 'undefined' ) {
273
277
if ( ! self . video ) return ;
@@ -277,31 +281,45 @@ var SubtitlesOctopus = function (options) {
277
281
var size = 0 ;
278
282
for ( var i = 0 , len = self . renderedItems . length ; i < len ; i ++ ) {
279
283
var item = self . renderedItems [ i ] ;
280
- if ( ( item . eventStart < 0 || currentTime >= item . eventStart ) &&
281
- ( item . emptyFinish < 0 || currentTime < item . emptyFinish ) ) {
284
+ if ( item . emptyFinish < 0 ) {
285
+ console . info ( 'oneshot already reached end-of-events' ) ;
286
+ return ;
287
+ }
288
+ if ( currentTime >= item . eventStart && currentTime < item . emptyFinish ) {
282
289
// an event for requested time already exists
290
+ console . debug ( 'not requesting a render for ' + currentTime +
291
+ ' as event already covering it exists (start=' +
292
+ item . eventStart + ', empty=' + item . emptyFinish + ')' ) ;
283
293
return ;
284
294
}
285
295
size += item . size ;
286
296
}
287
297
288
298
if ( size <= self . renderAhead ) {
289
- self . worker . postMessage ( {
290
- target : 'oneshot-render' ,
291
- lastRendered : currentTime - 0.001 ,
292
- renderNow : false ,
293
- iteration : self . oneshotState . iteration
294
- } ) ;
299
+ lastRendered = currentTime - 0.001 ;
300
+ console . info ( 'requesting new frame because current prerender size is less than limit (start=' + lastRendered + ')' ) ;
301
+ if ( ! self . oneshotState . renderRequested ) {
302
+ self . oneshotState . renderRequested = true ;
303
+ self . worker . postMessage ( {
304
+ target : 'oneshot-render' ,
305
+ lastRendered : lastRendered ,
306
+ renderNow : false ,
307
+ iteration : self . oneshotState . iteration
308
+ } ) ;
309
+ } else {
310
+ console . info ( 'worker busy, requesting to seek' ) ;
311
+ self . oneshotState . requestNextTimestamp = lastRendered ;
312
+ }
313
+ } else {
314
+ console . debug ( 'not requesting new frame yet as prerender size is over limit' ) ;
295
315
}
296
316
}
297
317
298
318
function _renderSubtitleEvent ( event , currentTime ) {
299
319
var eventOver = event . eventFinish < currentTime ;
300
320
if ( self . oneshotState . eventStart == event . eventStart && self . oneshotState . eventOver == eventOver ) return ;
301
- self . oneshotState = {
302
- eventStart : event . eventStart ,
303
- eventOver : eventOver
304
- } ;
321
+ self . oneshotState . eventStart = event . eventStart ;
322
+ self . oneshotState . eventOver = eventOver ;
305
323
306
324
var beforeDrawTime = performance . now ( ) ;
307
325
self . ctx . clearRect ( 0 , 0 , self . canvas . width , self . canvas . height ) ;
@@ -325,25 +343,34 @@ var SubtitlesOctopus = function (options) {
325
343
if ( ! self . video ) return ;
326
344
327
345
var currentTime = self . video . currentTime + self . timeOffset ;
328
- var finishTime = - 1 ;
346
+ var finishTime = - 1 , eventShown = false ;
329
347
for ( var i = 0 , len = self . renderedItems . length ; i < len ; i ++ ) {
330
348
var item = self . renderedItems [ i ] ;
331
- if ( item . eventStart <= currentTime && ( item . emptyFinish < 0 || item . emptyFinish >= currentTime ) ) {
349
+ if ( ! eventShown && item . eventStart <= currentTime && ( item . emptyFinish < 0 || item . emptyFinish >= currentTime ) ) {
332
350
_renderSubtitleEvent ( item , currentTime ) ;
351
+ eventShown = true ;
352
+ }
353
+ if ( item . emptyFinish > finishTime ) {
333
354
finishTime = item . emptyFinish ;
334
- break ;
335
355
}
336
356
}
337
357
338
358
if ( _cleanPastRendered ( currentTime ) && finishTime >= 0 ) {
339
- tryRequestOneshot ( finishTime ) ;
359
+ console . debug ( 'some prerendered frame retired, requesting new' ) ;
360
+ if ( eventShown ) {
361
+ tryRequestOneshot ( finishTime ) ;
362
+ } else {
363
+ tryRequestOneshot ( currentTime , true ) ;
364
+ }
340
365
}
341
366
}
342
367
343
368
function resetRenderAheadCache ( ) {
369
+ console . debug ( 'resetting prerender cache' ) ;
344
370
self . renderedItems = [ ] ;
345
371
self . oneshotState . eventStart = null ;
346
372
self . oneshotState . iteration ++ ;
373
+ self . oneshotState . renderRequested = false ;
347
374
tryRequestOneshot ( ) ;
348
375
}
349
376
@@ -473,9 +500,14 @@ var SubtitlesOctopus = function (options) {
473
500
}
474
501
case 'oneshot-result' : {
475
502
if ( data . iteration != self . oneshotState . iteration ) {
476
- // stale render, ignore
503
+ console . debug ( 'received stale prerender, ignoring' ) ;
477
504
return ;
478
505
}
506
+
507
+ console . info ( 'oneshot received (start=' +
508
+ data . eventStart + ', empty=' + data . emptyFinish +
509
+ '), render: ' + Math . round ( data . spentTime ) + ' ms' ) ;
510
+ self . oneshotState . renderRequested = false ;
479
511
var items = [ ] ;
480
512
var size = 0 ;
481
513
for ( var i = 0 , len = data . canvases . length ; i < len ; i ++ ) {
@@ -489,6 +521,10 @@ var SubtitlesOctopus = function (options) {
489
521
} ) ;
490
522
size += item . buffer . byteLength ;
491
523
}
524
+ if ( data . emptyFinish > 0 && data . emptyFinish - data . eventStart < 1.0 / self . targetFps ) {
525
+ data . emptyFinish = data . eventStart + 1.0 / self . targetFps ;
526
+ data . eventFinish = data . emptyFinish ;
527
+ }
492
528
self . renderedItems . push ( {
493
529
eventStart : data . eventStart ,
494
530
eventFinish : data . eventFinish ,
@@ -498,9 +534,18 @@ var SubtitlesOctopus = function (options) {
498
534
items : items ,
499
535
size : size
500
536
} ) ;
501
- if ( data . emptyFinish >= 0 ) {
502
- // there's some more event to render, try doing so
537
+
538
+ if ( self . oneshotState . requestNextTimestamp >= 0 ) {
539
+ console . debug ( "requesting out of order event at " + self . oneshotState . requestNextTimestamp ) ;
540
+ tryRequestOneshot ( self . oneshotState . requestNextTimestamp ) ;
541
+ self . oneshotState . requestNextTimestamp = - 1 ;
542
+ } else if ( data . eventStart < 0 ) {
543
+ console . info ( 'oneshot received "end of frames" event' ) ;
544
+ } else if ( data . emptyFinish >= 0 ) {
545
+ console . debug ( "there's some more event to render, try requesting next event" ) ;
503
546
tryRequestOneshot ( data . emptyFinish ) ;
547
+ } else {
548
+ console . info ( 'there are no more events to prerender' ) ;
504
549
}
505
550
break ;
506
551
}
0 commit comments