Skip to content

Commit

Permalink
feat: Parses a PRFT Box, with a loss of precision beyond 53 bits (sha…
Browse files Browse the repository at this point in the history
  • Loading branch information
avelad committed Jun 26, 2023
1 parent ebaddf0 commit a797651
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 42 deletions.
38 changes: 12 additions & 26 deletions lib/media/streaming_engine.js
Expand Up @@ -2038,30 +2038,16 @@ shaka.media.StreamingEngine = class {
!reference.initSegmentReference.timescale) {
return;
}
box.reader.readUint32(); // Ignore referenceTrackId
const ntpTimestampSec = box.reader.readUint32();
const ntpTimestampFrac = box.reader.readUint32();
const ntpTimestamp = ntpTimestampSec * 1000 +
ntpTimestampFrac / 2**32 * 1000;

let mediaTime;
if (box.version === 0) {
mediaTime = box.reader.readUint32();
} else {
try {
mediaTime = box.reader.readUint64();
} catch (e) {
shaka.log.warning('parsePrft_: parsing mediatime resulted in a '+
'MEDIA.JS_INTEGER_OVERFLOW exception');
this.parsedPrftEventRaised_ = true;
return;
}
}
goog.asserts.assert(
box.version == 0 || box.version == 1,
'PRFT version can only be 0 or 1');
const parsed = shaka.util.Mp4BoxParsers.parsePRFTInaccurate(
box.reader, box.version);

const timescale = reference.initSegmentReference.timescale;
const wallClockTime = this.convertNtp(ntpTimestamp);
const wallClockTime = this.convertNtp(parsed.ntpTimestamp);
const programStartDate = new Date(wallClockTime -
(mediaTime / timescale) * 1000);
(parsed.mediaTime / timescale) * 1000);
const prftInfo = {
wallClockTime,
programStartDate,
Expand All @@ -2077,11 +2063,11 @@ shaka.media.StreamingEngine = class {


/**
* Convert Ntp ntpTimeStamp to UTC Time
*
* @param {number} ntpTimeStamp
* @return {number} utcTime
*/
* Convert Ntp ntpTimeStamp to UTC Time
*
* @param {number} ntpTimeStamp
* @return {number} utcTime
*/
convertNtp(ntpTimeStamp) {
const start = new Date(Date.UTC(1900, 0, 1, 0, 0, 0));
return new Date(start.getTime() + ntpTimeStamp).getTime();
Expand Down
40 changes: 40 additions & 0 deletions lib/util/mp4_box_parsers.js
Expand Up @@ -89,6 +89,36 @@ shaka.util.Mp4BoxParsers = class {
}
}

/**
* Parses a PRFT Box, with a loss of precision beyond 53 bits.
* Use only when exact integers are not required, e.g. when
* dividing by the timescale.
*
* @param {!shaka.util.DataViewReader} reader
* @param {number} version
* @return {!shaka.util.ParsedPRFTBox}
*/
static parsePRFTInaccurate(reader, version) {
reader.readUint32(); // Ignore referenceTrackId
const ntpTimestampSec = reader.readUint32();
const ntpTimestampFrac = reader.readUint32();
const ntpTimestamp = ntpTimestampSec * 1000 +
ntpTimestampFrac / 2**32 * 1000;

let mediaTime;
if (version === 0) {
mediaTime = reader.readUint32();
} else {
const high = reader.readUint32();
const low = reader.readUint32();
mediaTime = (high * Math.pow(2, 32)) + low;
}
return {
mediaTime,
ntpTimestamp,
};
}

/**
* Parses a MDHD Box.
* @param {!shaka.util.DataViewReader} reader
Expand Down Expand Up @@ -332,6 +362,16 @@ shaka.util.ParsedTFHDBox;
*/
shaka.util.ParsedTFDTBox;

/**
* @typedef {{
* mediaTime: number,
* ntpTimestamp: number
* }}
*
* @exportDoc
*/
shaka.util.ParsedPRFTBox;

/**
* @typedef {{
* timescale: number,
Expand Down
16 changes: 0 additions & 16 deletions test/media/streaming_engine_unit.js
Expand Up @@ -3226,22 +3226,6 @@ describe('StreamingEngine', () => {
expectedStartDate.toUTCString());
});

it('does not raise event if mediatime exceeds Number.MAX_VALUE',
async () => {
const prftSegment = Uint8ArrayUtils.fromHex(
'00000020707266740100000000000001E683B62E8E63CC58'+
'FFFFFFFFFFFFFFFF');
segmentData[ContentType.VIDEO].segments[0] = prftSegment;
segmentData[ContentType.VIDEO].initSegments[0] = mdhdSegment;

streamingEngine.switchVariant(variant);
streamingEngine.switchTextStream(textStream);
await streamingEngine.start();
playing = true;
await runTest();
expect(onEvent).not.toHaveBeenCalled();
});

it('raises an event once only', async () => {
segmentData[ContentType.VIDEO].segments[0] =
shaka.util.Uint8ArrayUtils.concat(prftSegment, prftSegment);
Expand Down

0 comments on commit a797651

Please sign in to comment.