Skip to content

Commit

Permalink
feat: Convert CEA parsers to plugins (#5195)
Browse files Browse the repository at this point in the history
Fixes #5178 

Changes included:
- converted CEA parsers to externs
- added API to register/unregister CEA parsers
- TextEngine now checks is CEA decoder registered
- excluded CEA plugin from core build
- added lcevc plugin to core build

Bundle size results (all in KB, compared to
bf4b4a5):


  | core | complete - ui | complete - ui - cea
-- | -- | -- | --
before | 246 | 473 | 473
after | 231 | 474 | 459
  • Loading branch information
tykus160 authored Apr 29, 2023
1 parent f1c5a1c commit 7bda65d
Show file tree
Hide file tree
Showing 23 changed files with 313 additions and 199 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Vincent Valot <[email protected]>
V-Nova Limited <*@v-nova.com>
Wayne Morgan <[email protected]>
Wen Ren <[email protected]>
Wojciech Tyczyński <[email protected]>
Raymond Cheng <[email protected]>
Blue Billywig <*@bluebillywig.com>
João Nabais <[email protected]>
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ Vinod Balakrishnan <[email protected]>
Wayne Morgan <[email protected]>
Wen Ren <[email protected]>
Will Harris <[email protected]>
Wojciech Tyczyński <[email protected]>
Yohann Connell <[email protected]>
Raymond Cheng <[email protected]>
Janroel Koppen <[email protected]>
Expand Down
3 changes: 0 additions & 3 deletions build/types/cea
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
+../../lib/cea/cea708_service.js
+../../lib/cea/cea708_window.js
+../../lib/cea/dtvcc_packet_builder.js
+../../lib/cea/dummy_cea_parser.js
+../../lib/cea/i_caption_decoder.js
+../../lib/cea/i_cea_parser.js
+../../lib/cea/mp4_cea_parser.js
+../../lib/cea/sei_processor.js
+../../lib/cea/ts_cea_parser.js
2 changes: 1 addition & 1 deletion build/types/complete
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

+@ads
+@cast
+@cea
+@fairplay
+@networking
+@manifests
+@polyfill
+@text
+@transmuxer
+@ui
+@lcevc
5 changes: 4 additions & 1 deletion build/types/core
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
+../../lib/routing/payload.js
+../../lib/routing/walker.js

+../../lib/cea/dummy_cea_parser.js
+../../lib/cea/dummy_caption_decoder.js

+../../lib/text/cue.js
+../../lib/text/simple_text_displayer.js
+../../lib/text/text_engine.js
Expand Down Expand Up @@ -116,4 +119,4 @@
+../../third_party/closure-uri/uri.js
+../../third_party/closure-uri/utils.js

+@cea
+@lcevc
110 changes: 110 additions & 0 deletions externs/shaka/cea.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/


/**
* @externs
*/

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

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

/**
* @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).
* @property {number} pts
* The presentation timestamp (pts) at which the ITU-T T.35 data shows up.
* in seconds.
* @exportDoc
*/
shaka.extern.ICeaParser.CaptionPacket;


/**
* Interface for decoding inband closed captions from packets.
* @interface
* @exportDoc
*/
shaka.extern.ICaptionDecoder = class {
/**
* Extracts packets and prepares them for decoding. In a given media fragment,
* all the caption packets found in its SEI messages should be extracted by
* successive calls to extract(), followed by a single call to decode().
*
* @param {!Uint8Array} userDataSeiMessage
* This is a User Data registered by Rec.ITU-T T.35 SEI message.
* It is described in sections D.1.6 and D.2.6 of Rec. ITU-T H.264 (06/2019).
* @param {number} pts PTS when this packet was received, in seconds.
* @exportDoc
*/
extract(userDataSeiMessage, pts) {}

/**
* Decodes all currently extracted packets and then clears them.
* This should be called once for a set of extracts (see comment on extract).
* @return {!Array.<!shaka.extern.ICaptionDecoder.ClosedCaption>}
* @exportDoc
*/
decode() {}

/**
* Clears the decoder state completely.
* Should be used when an action renders the decoder state invalid,
* e.g. unbuffered seeks.
* @exportDoc
*/
clear() {}
};

/**
* Parsed Cue.
* @typedef {{
* cue: !shaka.text.Cue,
* stream: string
* }}
*
* @exportDoc
*/
shaka.extern.ICaptionDecoder.ClosedCaption;

/**
* @typedef {function():!shaka.extern.ICeaParser}
* @exportDoc
*/
shaka.extern.CeaParserPlugin;

/**
* @typedef {function():!shaka.extern.ICaptionDecoder}
* @exportDoc
*/
shaka.extern.CaptionDecoderPlugin;
13 changes: 6 additions & 7 deletions lib/cea/cea608_data_channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ goog.provide('shaka.cea.Cea608DataChannel');
goog.require('shaka.cea.Cea608Memory');
goog.require('shaka.cea.CeaUtils');
goog.require('shaka.log');
goog.requireType('shaka.cea.ICaptionDecoder');


/**
Expand Down Expand Up @@ -225,7 +224,7 @@ shaka.cea.Cea608DataChannel = class {
/**
* The Cea608DataChannel control methods implement all CC control operations.
* @param {!shaka.cea.Cea608DataChannel.Cea608Packet} ccPacket
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
controlMiscellaneous_(ccPacket) {
Expand Down Expand Up @@ -291,7 +290,7 @@ shaka.cea.Cea608DataChannel = class {
* Any currently buffered line needs to be emitted, along
* with a window scroll action.
* @param {number} pts in seconds.
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
controlCr_(pts) {
Expand Down Expand Up @@ -324,7 +323,7 @@ shaka.cea.Cea608DataChannel = class {
* This means must force emit entire display buffer.
* @param {number} scrollSize New scroll window size.
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
controlRu_(scrollSize, pts) {
Expand Down Expand Up @@ -368,7 +367,7 @@ shaka.cea.Cea608DataChannel = class {
* Mode check:
* EDM affects all captioning modes (but not Text mode);
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
controlEdm_(pts) {
Expand Down Expand Up @@ -415,7 +414,7 @@ shaka.cea.Cea608DataChannel = class {
* This forces Pop-On mode, and swaps the displayed and nondisplayed memories.
* @private
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
*/
controlEoc_(pts) {
let parsedClosedCaption = null;
Expand Down Expand Up @@ -513,7 +512,7 @@ shaka.cea.Cea608DataChannel = class {
* Three types of control codes:
* Preamble Address Codes, Mid-Row Codes, and Miscellaneous Control Codes.
* @param {!shaka.cea.Cea608DataChannel.Cea608Packet} ccPacket
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
*/
handleControlCode(ccPacket) {
const b1 = ccPacket.ccData1;
Expand Down
3 changes: 1 addition & 2 deletions lib/cea/cea608_memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ goog.provide('shaka.cea.Cea608Memory');

goog.require('shaka.cea.CeaUtils');
goog.require('shaka.text.Cue');
goog.requireType('shaka.cea.ICaptionDecoder');


/**
Expand Down Expand Up @@ -77,7 +76,7 @@ shaka.cea.Cea608Memory = class {
* Emits a closed caption based on the state of the buffer.
* @param {number} startTime Start time of the cue.
* @param {number} endTime End time of the cue.
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
*/
forceEmit(startTime, endTime) {
const stream = `CC${(this.fieldNum_<< 1) | this.channelNum_ +1}`;
Expand Down
17 changes: 8 additions & 9 deletions lib/cea/cea708_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ goog.provide('shaka.cea.Cea708Service');

goog.require('shaka.cea.Cea708Window');
goog.require('shaka.cea.DtvccPacket');
goog.require('shaka.cea.ICaptionDecoder');


/**
Expand Down Expand Up @@ -44,7 +43,7 @@ shaka.cea.Cea708Service = class {
/**
* Processes a CEA-708 control code.
* @param {!shaka.cea.DtvccPacket} dtvccPacket
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @throws {!shaka.util.Error}
*/
handleCea708ControlCode(dtvccPacket) {
Expand Down Expand Up @@ -156,7 +155,7 @@ shaka.cea.Cea708Service = class {
* Handles C0 group data.
* @param {number} controlCode
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
handleC0_(controlCode, pts) {
Expand Down Expand Up @@ -207,7 +206,7 @@ shaka.cea.Cea708Service = class {
* @param {!shaka.cea.DtvccPacket} dtvccPacket
* @param {number} captionCommand
* @param {number} pts in seconds
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @throws {!shaka.util.Error} a possible out-of-range buffer read.
* @private
*/
Expand Down Expand Up @@ -318,7 +317,7 @@ shaka.cea.Cea708Service = class {
/**
* @param {number} windowsBitmap
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
clearWindows_(windowsBitmap, pts) {
Expand Down Expand Up @@ -356,7 +355,7 @@ shaka.cea.Cea708Service = class {
/**
* @param {number} windowsBitmap
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
hideWindows_(windowsBitmap, pts) {
Expand All @@ -377,7 +376,7 @@ shaka.cea.Cea708Service = class {
/**
* @param {number} windowsBitmap
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
toggleWindows_(windowsBitmap, pts) {
Expand All @@ -402,7 +401,7 @@ shaka.cea.Cea708Service = class {
/**
* @param {number} windowsBitmap
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
deleteWindows_(windowsBitmap, pts) {
Expand All @@ -424,7 +423,7 @@ shaka.cea.Cea708Service = class {
* Emits anything currently present in any of the windows, and then
* deletes all windows, cancels all delays, reinitializes the service.
* @param {number} pts
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
reset_(pts) {
Expand Down
3 changes: 1 addition & 2 deletions lib/cea/cea708_window.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ goog.provide('shaka.cea.Cea708Window');

goog.require('shaka.cea.CeaUtils');
goog.require('shaka.cea.CeaUtils.StyledChar');
goog.require('shaka.cea.ICaptionDecoder');
goog.require('shaka.text.Cue');
goog.require('shaka.util.Functional');

Expand Down Expand Up @@ -288,7 +287,7 @@ shaka.cea.Cea708Window = class {
/**
* @param {number} endTime
* @param {number} serviceNumber Number of the service emitting this caption.
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
*/
forceEmit(endTime, serviceNumber) {
const stream = `svc${serviceNumber}`;
Expand Down
16 changes: 10 additions & 6 deletions lib/cea/cea_decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ goog.provide('shaka.cea.CeaDecoder');
goog.require('shaka.cea.Cea608DataChannel');
goog.require('shaka.cea.Cea708Service');
goog.require('shaka.cea.DtvccPacketBuilder');
goog.require('shaka.cea.ICaptionDecoder');
goog.require('shaka.log');
goog.require('shaka.media.ClosedCaptionParser');
goog.require('shaka.util.DataViewReader');
goog.require('shaka.util.Error');
goog.requireType('shaka.cea.DtvccPacket');


/**
* CEA-X08 captions decoder. Currently only CEA-608 supported.
* @implements {shaka.cea.ICaptionDecoder}
* CEA-X08 captions decoder.
* @implements {shaka.extern.ICaptionDecoder}
* @export
*/
shaka.cea.CeaDecoder = class {
/** */
Expand Down Expand Up @@ -208,7 +209,7 @@ shaka.cea.CeaDecoder = class {
* @override
*/
decode() {
/** @type {!Array.<!shaka.cea.ICaptionDecoder.ClosedCaption>} */
/** @type {!Array.<!shaka.extern.ICaptionDecoder.ClosedCaption>} */
const parsedClosedCaptions = [];

// In some versions of Chrome, and other browsers, the default sorting
Expand Down Expand Up @@ -250,7 +251,7 @@ shaka.cea.CeaDecoder = class {
/**
* Decodes a CEA-608 closed caption packet based on ANSI/CEA-608.
* @param {shaka.cea.Cea608DataChannel.Cea608Packet} ccPacket
* @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
* @private
*/
decodeCea608_(ccPacket) {
Expand Down Expand Up @@ -315,7 +316,7 @@ shaka.cea.CeaDecoder = class {
/**
* Decodes a CEA-708 DTVCC packet based on ANSI/CTA-708-E.
* @param {shaka.cea.DtvccPacket} dtvccPacket
* @return {!Array<!shaka.cea.ICaptionDecoder.ClosedCaption>}
* @return {!Array<!shaka.extern.ICaptionDecoder.ClosedCaption>}
* @private
*/
decodeCea708_(dtvccPacket) {
Expand Down Expand Up @@ -415,3 +416,6 @@ shaka.cea.CeaDecoder.NTSC_CC_FIELD_2 = 1;
* @private @const {number}
*/
shaka.cea.CeaDecoder.USA_COUNTRY_CODE = 0xb5;

shaka.media.ClosedCaptionParser.registerDecoder(
() => new shaka.cea.CeaDecoder());
Loading

0 comments on commit 7bda65d

Please sign in to comment.