/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.provide('shaka.mkv.BlockAddType');
goog.provide('shaka.mkv.BlockFlag');
goog.provide('shaka.mkv.CodecId');
goog.provide('shaka.mkv.ContentCompression');
goog.provide('shaka.mkv.ElementId');
goog.provide('shaka.mkv.Lacing');
goog.provide('shaka.mkv.MatroskaConstants');
goog.provide('shaka.mkv.TrackType');
/**
* EBML element IDs used by Matroska and WebM.
*
* The IDs are the wire values of the Matroska specification (RFC 9559), IDs
* included their length marker, so they can be compared directly with what the
* EBML parser returns.
*
* @see https://www.rfc-editor.org/rfc/rfc9559.html#name-matroska-schema
* @enum {number}
*/
shaka.mkv.ElementId = {
// EBML header.
EBML: 0x1A45DFA3,
EBML_VERSION: 0x4286,
EBML_READ_VERSION: 0x42F7,
EBML_MAX_ID_LENGTH: 0x42F2,
EBML_MAX_SIZE_LENGTH: 0x42F3,
DOC_TYPE: 0x4282,
DOC_TYPE_VERSION: 0x4287,
DOC_TYPE_READ_VERSION: 0x4285,
// Segment and its top-level children.
SEGMENT: 0x18538067,
SEEK_HEAD: 0x114D9B74,
INFO: 0x1549A966,
TRACKS: 0x1654AE6B,
CLUSTER: 0x1F43B675,
CUES: 0x1C53BB6B,
CHAPTERS: 0x1043A770,
TAGS: 0x1254C367,
ATTACHMENTS: 0x1941A469,
// SeekHead.
SEEK: 0x4DBB,
SEEK_ID: 0x53AB,
SEEK_POSITION: 0x53AC,
// Info.
TIMECODE_SCALE: 0x2AD7B1,
DURATION: 0x4489,
MUXING_APP: 0x4D80,
WRITING_APP: 0x5741,
// Tracks.
TRACK_ENTRY: 0xAE,
TRACK_NUMBER: 0xD7,
TRACK_UID: 0x73C5,
TRACK_TYPE: 0x83,
FLAG_ENABLED: 0xB9,
FLAG_DEFAULT: 0x88,
FLAG_FORCED: 0x55AA,
FLAG_HEARING_IMPAIRED: 0x55AB,
FLAG_VISUAL_IMPAIRED: 0x55AC,
FLAG_ORIGINAL: 0x55AE,
FLAG_COMMENTARY: 0x55AF,
DEFAULT_DURATION: 0x23E383,
TRACK_NAME: 0x536E,
LANGUAGE: 0x22B59C,
LANGUAGE_BCP47: 0x22B59D,
CODEC_ID: 0x86,
CODEC_PRIVATE: 0x63A2,
CODEC_DELAY: 0x56AA,
BLOCK_ADDITION_MAPPING: 0x41E4,
BLOCK_ADD_ID_TYPE: 0x41E7,
BLOCK_ADD_ID_EXTRA_DATA: 0x41ED,
CONTENT_ENCODINGS: 0x6D80,
CONTENT_ENCODING: 0x6240,
CONTENT_ENCODING_SCOPE: 0x5032,
CONTENT_ENCODING_TYPE: 0x5033,
CONTENT_COMPRESSION: 0x5034,
CONTENT_COMP_ALGO: 0x4254,
CONTENT_COMP_SETTINGS: 0x4255,
// Track video settings.
VIDEO: 0xE0,
PIXEL_WIDTH: 0xB0,
PIXEL_HEIGHT: 0xBA,
DISPLAY_WIDTH: 0x54B0,
DISPLAY_HEIGHT: 0x54BA,
DISPLAY_UNIT: 0x54B2,
COLOUR: 0x55B0,
TRANSFER_CHARACTERISTICS: 0x55BA,
COLOUR_PRIMARIES: 0x55BB,
// Track audio settings.
AUDIO: 0xE1,
SAMPLING_FREQUENCY: 0xB5,
OUTPUT_SAMPLING_FREQUENCY: 0x78B5,
CHANNELS: 0x9F,
BIT_DEPTH: 0x6264,
// Cluster.
CLUSTER_TIMECODE: 0xE7,
SIMPLE_BLOCK: 0xA3,
BLOCK_GROUP: 0xA0,
BLOCK: 0xA1,
BLOCK_DURATION: 0x9B,
REFERENCE_BLOCK: 0xFB,
// Cues.
CUE_POINT: 0xBB,
CUE_TIME: 0xB3,
CUE_TRACK_POSITIONS: 0xB7,
CUE_TRACK: 0xF7,
CUE_CLUSTER_POSITION: 0xF1,
// Chapters.
EDITION_ENTRY: 0x45B9,
CHAPTER_ATOM: 0xB6,
CHAPTER_TIME_START: 0x91,
CHAPTER_TIME_END: 0x92,
CHAPTER_DISPLAY: 0x80,
CHAP_STRING: 0x85,
CHAP_LANGUAGE: 0x437C,
CHAP_LANGUAGE_BCP47: 0x437D,
};
/**
* Values of the TrackType element.
*
* @see https://www.rfc-editor.org/rfc/rfc9559.html#name-tracktype-element
* @enum {number}
*/
shaka.mkv.TrackType = {
VIDEO: 1,
AUDIO: 2,
SUBTITLE: 0x11,
};
/**
* The lacing scheme of a block, stored in bits 1-2 of the block flags. Lacing
* packs several small frames (typically audio) into one block.
*
* @see https://www.rfc-editor.org/rfc/rfc9559.html#name-lacing
* @enum {number}
*/
shaka.mkv.Lacing = {
NONE: 0x00,
XIPH: 0x02,
FIXED_SIZE: 0x04,
EBML: 0x06,
};
/**
* Bits of the flags byte that follows the timecode in a (Simple)Block.
*
* @enum {number}
*/
shaka.mkv.BlockFlag = {
/** Set on a SimpleBlock that is a keyframe. */
KEYFRAME: 0x80,
/** Mask of the two lacing bits. */
LACING_MASK: 0x06,
};
/**
* Values of ContentCompAlgo. Only header stripping can be undone without a
* decompressor; it is what mkvmerge uses to save a few bytes per frame.
*
* @enum {number}
*/
shaka.mkv.ContentCompression = {
HEADER_STRIPPING: 3,
};
/**
* Values of BlockAddIDType that the parser knows: the four characters of a
* box name, as a number. Matroska carries the Dolby Vision configuration
* record in a BlockAdditionMapping of this type.
*
* @enum {number}
*/
shaka.mkv.BlockAddType = {
DVCC: 0x64766343,
DVVC: 0x64767643,
};
/**
* The CodecID strings of the codecs the parser knows how to repackage into
* fragmented MP4. Any other CodecID is ignored.
*
* @see https://www.matroska.org/technical/codec_specs.html
* @enum {string}
*/
shaka.mkv.CodecId = {
AVC: 'V_MPEG4/ISO/AVC',
HEVC: 'V_MPEGH/ISO/HEVC',
VP8: 'V_VP8',
VP9: 'V_VP9',
AV1: 'V_AV1',
AAC: 'A_AAC',
AC3: 'A_AC3',
EAC3: 'A_EAC3',
OPUS: 'A_OPUS',
VORBIS: 'A_VORBIS',
FLAC: 'A_FLAC',
MP3: 'A_MPEG/L3',
SRT: 'S_TEXT/UTF8',
// Deprecated alias of S_TEXT/UTF8 that old muxers still write.
ASCII: 'S_TEXT/ASCII',
ASS: 'S_TEXT/ASS',
SSA: 'S_TEXT/SSA',
};
shaka.mkv.MatroskaConstants = class {};
/**
* Matroska stores every time as an integer count of "ticks", and TimecodeScale
* says how many nanoseconds a tick is. This is the number of nanoseconds in a
* second, i.e. the factor that turns ticks * TimecodeScale into seconds.
*
* @const {number}
*/
shaka.mkv.MatroskaConstants.NANOSECONDS_PER_SECOND = 1e9;
/**
* Default TimecodeScale when the Info element does not write one: 1,000,000 ns,
* i.e. every tick is 1 ms.
*
* @const {number}
*/
shaka.mkv.MatroskaConstants.DEFAULT_TIMECODE_SCALE = 1000000;
/**
* Language of a track that has no Language element. The Matroska
* specification (not "und") defines the default as English.
*
* @const {string}
*/
shaka.mkv.MatroskaConstants.DEFAULT_LANGUAGE = 'eng';
/**
* How much later than in the file the transmuxer presents the media, in
* seconds. The parser makes up for it with the timestampOffset of the
* references, so the presentation times do not change.
*
* A frame in MP4 cannot be decoded after it is presented, and decode times
* cannot be negative. A video frame that the encoder reorders (B-frames) is
* decoded earlier than it is presented, by up to 16 frames (about 0.7 s at
* 24 fps). The transmuxer uses the times of the file as decode times, and
* moves the presentation times by more than that delay, so no frame is
* presented before it is decoded, and the decode times of the segments follow
* each other with no gap or overlap.
*
* @const {number}
*/
shaka.mkv.MatroskaConstants.MEDIA_TIME_SHIFT = 1;
/**
* What is added to the number of a track to make the identifier of a second
* stream of the same track. A Dolby Vision track whose base layer plays on its
* own has two streams, one with each codec, the way HLS and DASH describe
* them, and the identifiers of streams are unique. It is larger than any track
* number a muxer writes (they count from 1).
*
* @const {number}
*/
shaka.mkv.MatroskaConstants.ALTERNATE_STREAM_ID_OFFSET = 1048576;
/**
* The EBML DocType values a Matroska parser accepts. WebM is the subset of
* Matroska that browsers can already play, but the same structure applies.
*
* @const {!Array<string>}
*/
shaka.mkv.MatroskaConstants.DOC_TYPES = ['matroska', 'webm'];
/**
* Level-1 elements: the children of Segment. An unknown-size Cluster ends
* when the next one of these begins.
*
* @const {!Set<number>}
*/
shaka.mkv.MatroskaConstants.LEVEL_1_IDS = new Set([
shaka.mkv.ElementId.SEEK_HEAD,
shaka.mkv.ElementId.INFO,
shaka.mkv.ElementId.TRACKS,
shaka.mkv.ElementId.CLUSTER,
shaka.mkv.ElementId.CUES,
shaka.mkv.ElementId.CHAPTERS,
shaka.mkv.ElementId.TAGS,
shaka.mkv.ElementId.ATTACHMENTS,
]);