UNPKG

shaka-player

Version:
150 lines (132 loc) • 4.88 kB
/*! @license * Shaka Player * Copyright 2016 Google LLC * SPDX-License-Identifier: Apache-2.0 */ goog.provide('shaka.codec.AAC'); goog.require('goog.asserts'); goog.require('shaka.util.Uint8ArrayUtils'); /** * AAC utils, for when the codec configuration comes as an AudioSpecificConfig. * * @see ISO/IEC 14496-3 (AudioSpecificConfig) * @see ISO/IEC 14496-1 (descriptors) */ shaka.codec.AAC = class { /** * Gets the RFC 6381 codec string of an AAC stream. * * @param {!Uint8Array} audioSpecificConfig * @param {?number=} sampleRate The sample rate of the AAC core. * @param {?number=} outputSampleRate The sample rate of the output, which * is twice the core's when HE-AAC is signaled implicitly. * @return {string} */ static getCodecs(audioSpecificConfig, sampleRate, outputSampleRate) { const AAC = shaka.codec.AAC; // The first 5 bits of the AudioSpecificConfig are the audio object type; // 31 announces an escape to 6 more bits. let objectType = audioSpecificConfig[0] >> 3; if (objectType == AAC.OBJECT_TYPE_ESCAPE_ && audioSpecificConfig.length > 1) { objectType = 32 + (((audioSpecificConfig[0] & 0x07) << 3) | (audioSpecificConfig[1] >> 5)); } const isImplicitSbr = objectType == AAC.OBJECT_TYPE_LC_ && !!sampleRate && !!outputSampleRate && outputSampleRate >= 2 * sampleRate; if (isImplicitSbr) { objectType = AAC.OBJECT_TYPE_SBR_; } return 'mp4a.40.' + objectType; } /** * Builds the payload of the esds box around the decoder configuration. * * @param {!Uint8Array} decoderConfig The AudioSpecificConfig of AAC. Codecs * that need no configuration (MPEG audio) give it empty. * @param {number=} objectTypeIndication The codec that the stream has. * @return {!Uint8Array} */ static buildEsds(decoderConfig, objectTypeIndication) { const AAC = shaka.codec.AAC; const decoderSpecificInfo = decoderConfig.length ? AAC.descriptor_(AAC.TAG_DECODER_SPECIFIC_INFO_, decoderConfig) : new Uint8Array(0); const decoderConfigDescriptor = AAC.descriptor_( AAC.TAG_DECODER_CONFIG_, new Uint8Array([ objectTypeIndication == null ? AAC.OBJECT_TYPE_MPEG4_AUDIO_ : objectTypeIndication, AAC.STREAM_TYPE_AUDIO_, // bufferSizeDB (3 bytes), maxBitrate and avgBitrate (4 bytes each) // are informative and 0 means "unknown". 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]), decoderSpecificInfo); const slConfig = AAC.descriptor_( AAC.TAG_SL_CONFIG_, new Uint8Array([AAC.SL_PREDEFINED_MP4_])); const esDescriptor = AAC.descriptor_( AAC.TAG_ES_, // ES_ID (2 bytes, 0: the sample entry refers to the track) and the // stream dependence, URL and OCR flags (1 byte, none set). new Uint8Array([0, 0, 0]), decoderConfigDescriptor, slConfig); // esds is a full box: version and flags, all zero. return shaka.util.Uint8ArrayUtils.concat(new Uint8Array(4), esDescriptor); } /** * Builds an MPEG-4 descriptor: a tag, a length and the payload. * * @param {number} tag * @param {...!Uint8Array} payload * @return {!Uint8Array} * @private */ static descriptor_(tag, ...payload) { const body = shaka.util.Uint8ArrayUtils.concat(...payload); // Descriptor lengths are variable-length, but ours never reach 128 bytes // (an AudioSpecificConfig is a handful of bytes), so one byte is enough. goog.asserts.assert(body.length < 0x80, 'Descriptor is too long'); return shaka.util.Uint8ArrayUtils.concat( new Uint8Array([tag, body.length]), body); } }; /** * Audio object types of MPEG-4 Audio: AAC LC and HE-AAC (with SBR); 31 is the * escape value. * @private @const {number} */ shaka.codec.AAC.OBJECT_TYPE_LC_ = 2; /** @private @const {number} */ shaka.codec.AAC.OBJECT_TYPE_SBR_ = 5; /** @private @const {number} */ shaka.codec.AAC.OBJECT_TYPE_ESCAPE_ = 31; /** * Tags of the MPEG-4 descriptors that make up an esds box. * @private @const {number} */ shaka.codec.AAC.TAG_ES_ = 0x03; /** @private @const {number} */ shaka.codec.AAC.TAG_DECODER_CONFIG_ = 0x04; /** @private @const {number} */ shaka.codec.AAC.TAG_DECODER_SPECIFIC_INFO_ = 0x05; /** @private @const {number} */ shaka.codec.AAC.TAG_SL_CONFIG_ = 0x06; /** * objectTypeIndication of MPEG-4 Audio (ISO/IEC 14496-3). * @private @const {number} */ shaka.codec.AAC.OBJECT_TYPE_MPEG4_AUDIO_ = 0x40; /** * streamType 5 (audio) shifted into the top six bits, plus the reserved bit * that is always set. * @private @const {number} */ shaka.codec.AAC.STREAM_TYPE_AUDIO_ = (0x05 << 2) | 0x01; /** * The SL config predefined value reserved for use in MP4 files. * @private @const {number} */ shaka.codec.AAC.SL_PREDEFINED_MP4_ = 0x02;