| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 | /** * mux.js * * Copyright (c) Brightcove * Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE * * Accepts program elementary stream (PES) data events and corrects * decode and presentation time stamps to account for a rollover * of the 33 bit value. */'use strict';var Stream = require('../utils/stream');var MAX_TS = 8589934592;var RO_THRESH = 4294967296;var TYPE_SHARED = 'shared';var handleRollover = function(value, reference) {  var direction = 1;  if (value > reference) {    // If the current timestamp value is greater than our reference timestamp and we detect a    // timestamp rollover, this means the roll over is happening in the opposite direction.    // Example scenario: Enter a long stream/video just after a rollover occurred. The reference    // point will be set to a small number, e.g. 1. The user then seeks backwards over the    // rollover point. In loading this segment, the timestamp values will be very large,    // e.g. 2^33 - 1. Since this comes before the data we loaded previously, we want to adjust    // the time stamp to be `value - 2^33`.    direction = -1;  }  // Note: A seek forwards or back that is greater than the RO_THRESH (2^32, ~13 hours) will  // cause an incorrect adjustment.  while (Math.abs(reference - value) > RO_THRESH) {    value += (direction * MAX_TS);  }  return value;};var TimestampRolloverStream = function(type) {  var lastDTS, referenceDTS;  TimestampRolloverStream.prototype.init.call(this);  // The "shared" type is used in cases where a stream will contain muxed  // video and audio. We could use `undefined` here, but having a string  // makes debugging a little clearer.  this.type_ = type || TYPE_SHARED;  this.push = function(data) {    // Any "shared" rollover streams will accept _all_ data. Otherwise,    // streams will only accept data that matches their type.    if (this.type_ !== TYPE_SHARED && data.type !== this.type_) {      return;    }    if (referenceDTS === undefined) {      referenceDTS = data.dts;    }    data.dts = handleRollover(data.dts, referenceDTS);    data.pts = handleRollover(data.pts, referenceDTS);    lastDTS = data.dts;    this.trigger('data', data);  };  this.flush = function() {    referenceDTS = lastDTS;    this.trigger('done');  };  this.endTimeline = function() {    this.flush();    this.trigger('endedtimeline');  };  this.discontinuity = function() {    referenceDTS = void 0;    lastDTS = void 0;  };  this.reset = function() {    this.discontinuity();    this.trigger('reset');  };};TimestampRolloverStream.prototype = new Stream();module.exports = {  TimestampRolloverStream: TimestampRolloverStream,  handleRollover: handleRollover};
 |