-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(BREAKING): use bigint for 64 bit ints if needed and available. #383
Changes from all commits
c8c9bf7
26af3b6
9331fd8
5cd00b7
da1a66c
9e7f68b
0d7faf6
15281d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,8 +15,11 @@ var parseType = require('../mp4/parse-type.js'); | |
var parseTfhd = require('../tools/parse-tfhd.js'); | ||
var parseTrun = require('../tools/parse-trun.js'); | ||
var parseTfdt = require('../tools/parse-tfdt.js'); | ||
var getUint64 = require('../utils/numbers.js').getUint64; | ||
var timescale, startTime, compositionStartTime, getVideoTrackIds, getTracks, | ||
getTimescaleFromMediaHeader; | ||
var window = require('global/window'); | ||
|
||
|
||
/** | ||
* Parses an MP4 initialization segment and extracts the timescale | ||
|
@@ -87,52 +90,55 @@ timescale = function(init) { | |
* fragment, in seconds | ||
*/ | ||
startTime = function(timescale, fragment) { | ||
var trafs, baseTimes, result; | ||
var trafs, result; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code was all kinds of weird. We create an empty array twice to map over another array of trafs?? Then we map over all tfhd/tfdt and parse them, but only take the first? It's all kinds of nuts. I switched it so that we loop over all |
||
|
||
// we need info from two childrend of each track fragment box | ||
trafs = findBox(fragment, ['moof', 'traf']); | ||
|
||
// determine the start times for each track | ||
baseTimes = [].concat.apply([], trafs.map(function(traf) { | ||
return findBox(traf, ['tfhd']).map(function(tfhd) { | ||
var id, scale, baseTime; | ||
|
||
// get the track id from the tfhd | ||
id = toUnsigned(tfhd[4] << 24 | | ||
tfhd[5] << 16 | | ||
tfhd[6] << 8 | | ||
tfhd[7]); | ||
// assume a 90kHz clock if no timescale was specified | ||
scale = timescale[id] || 90e3; | ||
|
||
// get the base media decode time from the tfdt | ||
baseTime = findBox(traf, ['tfdt']).map(function(tfdt) { | ||
var version, result; | ||
|
||
version = tfdt[0]; | ||
result = toUnsigned(tfdt[4] << 24 | | ||
tfdt[5] << 16 | | ||
tfdt[6] << 8 | | ||
tfdt[7]); | ||
if (version === 1) { | ||
result *= Math.pow(2, 32); | ||
result += toUnsigned(tfdt[8] << 24 | | ||
tfdt[9] << 16 | | ||
tfdt[10] << 8 | | ||
tfdt[11]); | ||
} | ||
return result; | ||
})[0]; | ||
baseTime = typeof baseTime === 'number' && !isNaN(baseTime) ? baseTime : Infinity; | ||
var lowestTime = trafs.reduce(function(acc, traf) { | ||
var tfhd = findBox(traf, ['tfhd'])[0]; | ||
|
||
// get the track id from the tfhd | ||
var id = toUnsigned(tfhd[4] << 24 | | ||
tfhd[5] << 16 | | ||
tfhd[6] << 8 | | ||
tfhd[7]); | ||
// assume a 90kHz clock if no timescale was specified | ||
var scale = timescale[id] || 90e3; | ||
|
||
// get the base media decode time from the tfdt | ||
var tfdt = findBox(traf, ['tfdt'])[0]; | ||
var dv = new DataView(tfdt.buffer, tfdt.byteOffset, tfdt.byteLength); | ||
var baseTime; | ||
|
||
// version 1 is 64 bit | ||
if (tfdt[0] === 1) { | ||
baseTime = getUint64(tfdt.subarray(4, 12)); | ||
} else { | ||
baseTime = dv.getUint32(4); | ||
} | ||
|
||
// convert base time to seconds | ||
return baseTime / scale; | ||
}); | ||
})); | ||
// convert base time to seconds if it is a valid number. | ||
let seconds; | ||
if (typeof baseTime === 'bigint') { | ||
seconds = baseTime / window.BigInt(scale); | ||
} else if (typeof baseTime === 'number' && !isNaN(baseTime)) { | ||
seconds = baseTime / scale; | ||
} | ||
|
||
if (seconds < Number.MAX_SAFE_INTEGER) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if converting it to the appropriate scale, brings it below the threshold to be a bigInt bring it back to a number. |
||
seconds = Number(seconds); | ||
} | ||
|
||
// return the minimum | ||
result = Math.min.apply(null, baseTimes); | ||
return isFinite(result) ? result : 0; | ||
if (seconds < acc) { | ||
acc = seconds; | ||
} | ||
|
||
return acc; | ||
}, Infinity); | ||
|
||
return typeof lowestTime === 'bigint' || isFinite(lowestTime) ? lowestTime : 0; | ||
}; | ||
|
||
/** | ||
|
@@ -194,7 +200,18 @@ compositionStartTime = function(timescales, fragment) { | |
var timescale = timescales[trackId] || 90e3; | ||
|
||
// return the composition start time, in seconds | ||
return (baseMediaDecodeTime + compositionTimeOffset) / timescale; | ||
if (typeof baseMediaDecodeTime === 'bigint') { | ||
compositionTimeOffset = window.BigInt(compositionTimeOffset); | ||
timescale = window.BigInt(timescale); | ||
} | ||
|
||
var result = (baseMediaDecodeTime + compositionTimeOffset) / timescale; | ||
|
||
if (typeof result === 'bigint' && result < Number.MAX_SAFE_INTEGER) { | ||
result = Number(result); | ||
} | ||
|
||
return result; | ||
}; | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
var MAX_UINT32 = Math.pow(2, 32); | ||
|
||
var getUint64 = (uint8) => { | ||
var dv = new DataView(uint8.buffer, uint8.byteOffset, uint8.byteLength); | ||
var value; | ||
|
||
if (dv.getBigUint64) { | ||
value = dv.getBigUint64(0); | ||
|
||
if (value < Number.MAX_SAFE_INTEGER) { | ||
return Number(value); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
return (dv.getUint32(0) * MAX_UINT32) + dv.getUint32(4); | ||
}; | ||
|
||
module.exports = { | ||
getUint64: getUint64, | ||
MAX_UINT32: MAX_UINT32 | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We subtracted 1 from it at the top, only to minus 1 later...