Skip to content

Commit

Permalink
Created MP4 box parsers to parse data for common box types (shaka-pro…
Browse files Browse the repository at this point in the history
…ject#2648)

added tkhd box parsing

unit testing for mp4 box parsers

moved mp4 box structs to lib/util

inlined returns for mp4 boxes

created mp4 parser to parse cea708 packets from mp4 streams (shaka-project#2648)

tightened array out of bound checks

added error code for invalid mp4 for cea packets

refactored name of mp4 cea parser interface

fixed a bug with increment ordering that affected time

linting

addressed mp4 cea parsing comments

stylistic changes to mp4 cea parser

improved mp4 parser comments and addressed pr review

return caption packets as array instead of in a callback

removed caption packets from class state to avoid clearing it in the middle of a parse
  • Loading branch information
muhammadharis committed Jul 9, 2020
1 parent 5923388 commit 31a2fef
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 18 deletions.
2 changes: 1 addition & 1 deletion build/types/cea
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Inband closed caption support.

+../../lib/cea/mp4_cea_parser.js
+../../lib/cea/i_cea_parser.js
+../../lib/cea/cea_parser.js
+../../lib/cea/sei_processor.js
56 changes: 56 additions & 0 deletions lib/cea/cea_parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

goog.provide('shaka.cea.ICeaParser');

/**
* Interface for parsing inband closed caption data from MP4 streams.
* @interface
*/
shaka.cea.ICeaParser = class {
/**
* Initializes the parser with init segment data.
* @param {!BufferSource} initSegment init segment to parse.
*/
init(initSegment) {}

/**
* Parses the stream and extracts closed captions packets.
* @param {!BufferSource} mediaSegment media segment to parse.
* @return {!Array<!shaka.cea.ICeaParser.CaptionPacket>}
*/
parse(mediaSegment) {}
};

/**
* NALU type for Supplemental Enhancement Information (SEI).
* @const {number}
*/
shaka.cea.ICeaParser.NALU_TYPE_SEI = 0x06;

/**
* Default timescale value for a track.
*/
shaka.cea.ICeaParser.DEFAULT_TIMESCALE_VALUE = 90000;

/**
* @typedef {{
* packet: !Uint8Array,
* pts: !number
* }}
*
* @description Parsed Caption Packet.
* @property {!Uint8Array} packet
* Caption packet. More specifically, it contains a "User data
* registered by Recommendation ITU-T T.35 SEI message", from section D.1.6
* and section D.2.6 of Rec. ITU-T H.264 (06/2019). The second parameter is
* the presentation time stamp (pts).
* @property {!number} pts
* The presentation timestamp (pts) at which the ITU-T T.35 data shows up.
* @exportDoc
*/
shaka.cea.ICeaParser.CaptionPacket;

15 changes: 7 additions & 8 deletions lib/cea/mp4_cea_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,7 @@ shaka.cea.Mp4CeaParser = class {
if (baseMediaDecodeTime === null) {
// This field should have been populated by
// the Base Media Decode time in the TFDT box
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.TEXT,
shaka.util.Error.Code.INVALID_MP4_CEA);
return;
}
this.parseMdat_(box.reader, baseMediaDecodeTime, timescale,
defaultSampleDuration, defaultSampleSize, sampleData,
Expand Down Expand Up @@ -222,12 +219,14 @@ shaka.cea.Mp4CeaParser = class {
let timeOffset = 0;

if (sampleData.length > sampleIndex) {
timeOffset = sampleData[sampleIndex].sampleCompositionTimeOffset || 0;
timeOffset =
(sampleData[sampleIndex].sampleCompositionTimeOffset || 0)
/timescale;
}

const pts = (time + timeOffset)/timescale;
for (const packet of this.seiProcessor_
.process(reader.readBytes(naluSize - 1))) {
for (const packet of
this.seiProcessor_.process(reader.readBytes(naluSize - 1))) {
captionPackets.push({
packet,
pts,
Expand All @@ -240,7 +239,7 @@ shaka.cea.Mp4CeaParser = class {
if (sampleSize == 0) {
if (sampleData.length > sampleIndex) {
time += sampleData[sampleIndex].sampleDuration ||
defaultSampleDuration;
defaultSampleDuration;
} else {
time += defaultSampleDuration;
}
Expand Down
21 changes: 12 additions & 9 deletions test/cea/mp4_cea_parser_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,23 @@ describe('Mp4CeaParser', () => {
const cea708Parser = new shaka.cea.Mp4CeaParser();

const expectedCea708Packet = new Uint8Array([
0xb5, 0x00, 0x31, 0x47, 0x41, 0x39, 0x34, 0x03,
0xce, 0xff, 0xfd, 0x94, 0x20, 0xfd, 0x94, 0xae,
0xfd, 0x91, 0x62, 0xfd, 0x73, 0xf7, 0xfd, 0xe5,
0xba, 0xfd, 0x91, 0xb9, 0xfd, 0xb0, 0xb0, 0xfd,
0xba, 0xb0, 0xfd, 0xb0, 0xba, 0xfd, 0xb0, 0x31,
0xfd, 0xba, 0xb0, 0xfd, 0xb0, 0x80, 0xfd, 0x94,
0x2c, 0xfd, 0x94, 0x2f, 0xff,
0xb5, 0x00, 0x31, 0x47, 0x41,
0x39, 0x34, 0x03, 0xce, 0xff,
0xfd, 0x94, 0x20, 0xfd, 0x94,
0xae, 0xfd, 0x91, 0x62, 0xfd,
0x73, 0xf7, 0xfd, 0xe5, 0xba,
0xfd, 0x91, 0xb9, 0xfd, 0xb0,
0xb0, 0xfd, 0xba, 0xb0, 0xfd,
0xb0, 0xba, 0xfd, 0xb0, 0x31,
0xfd, 0xba, 0xb0, 0xfd, 0xb0,
0x80, 0xfd, 0x94, 0x2c, 0xfd,
0x94, 0x2f, 0xff,
]);

cea708Parser.init(ceaInitSegment);
const cea708Packets = cea708Parser.parse(ceaSegment);
expect(cea708Packets).toBeDefined();
expect(cea708Packets.length).toBe(4);
expect(cea708Packets[cea708Packets.length - 1].packet)
expect(cea708Packets[cea708Packets.length-1].packet)
.toEqual(expectedCea708Packet);
});

Expand Down

0 comments on commit 31a2fef

Please sign in to comment.