import { BaseParser } from "./parser" ; import { IDescriptor , IDecoderSpecificInfo , IProfileLevelIndicationIndexDescriptor , IDecoderConfigDescriptor , ISLConfigDescriptor , IESDescriptor , IInitialObjectDescriptor , IExtensionDescriptor } from "./interface.descr" ; import { DESCR_TAG_DECODER_SPECIFIC_INFO , DESCR_TAG_PROFILE_LEVEL_INDICATION_INDEX_DESCRIPTOR , DESCR_TAG_DECODER_CONFIG_DESCRIPTOR , DESCR_TAG_SL_CONFIG_DESCRIPTOR , DESCR_TAG_ES_DESCRIPTOR } from "./statics" ; const dict = { } ; function Tag ( tag ) { return function ( constructor ) { constructor . TAG = tag ; if ( typeof tag === "number" ) { dict [ tag ] = constructor ; } else { tag . forEach ( t => ( dict [ t ] = constructor ) ) ; } return constructor ; } ; } export var getDescriptorInfo = ( bytes , offset = 0 ) : IDescriptor => { var tag = bytes [ offset ++ ] ; var b = bytes [ offset ++ ] ; var bodyLength = b & 0x7f ; var headerLength = 2 ; while ( b & 0x80 ) { headerLength ++ ; b = bytes [ offset ++ ] ; bodyLength <<= 7 ; bodyLength |= b & 0x7f ; } return { tag : tag , byteLength : headerLength + bodyLength , headerLength : headerLength , bodyLength : bodyLength } ; } ; export class DescriptorParserMixin extends BaseParser { readDescriptor ( ) { var info = getDescriptorInfo ( this . bytes , this . byteOffset ) ; return createDescriptorParser ( this . readBytes ( info . byteLength ) , info . tag ) . parse ( ) ; } } export class DescriptorParser extends DescriptorParserMixin { parse ( ) { var info = getDescriptorInfo ( this . bytes ) ; this . skipBytes ( info . headerLength ) ; info . bytes = this . bytes ; return info ; } } @ Tag ( DESCR_TAG_DECODER_SPECIFIC_INFO ) export class DecoderSpecificInfoParser extends DescriptorParser { parse ( ) { var ret = < IDecoderSpecificInfo > super . parse ( ) ; ret . data = this . bytes . subarray ( this . byteOffset ) ; return ret ; } } @ Tag ( DESCR_TAG_PROFILE_LEVEL_INDICATION_INDEX_DESCRIPTOR ) export class ProfileLevelINdicationIndexDescriptor extends DescriptorParser { parse ( ) { var ret = < IProfileLevelIndicationIndexDescriptor > super . parse ( ) ; ret . profileLevelIndicationIndex = this . readUint8 ( ) ; return ret ; } } @ Tag ( DESCR_TAG_DECODER_CONFIG_DESCRIPTOR ) export class DecoderConfigDescriptorParser extends DescriptorParser { static OBJECT_TYPE_INDICATION = { MP3 : 0x6b , AAC : 0x40 } ; parse ( ) { var ret = < IDecoderConfigDescriptor > super . parse ( ) ; ret . objectTypeIndication = this . readUint8 ( ) ; ret . streamType = this . readBits ( 6 ) ; ret . upStream = this . readBits ( 1 ) ; this . skipBits ( 1 ) ; ret . bufferSizeDB = this . readUint24 ( ) ; ret . maxBitrate = this . readUint32 ( ) ; ret . avgBitrate = this . readUint32 ( ) ; var info ; var descrParser ; var descr ; ret . profileLevelIndicationIndexDescrs = [ ] ; while ( ! this . eof ( ) ) { info = getDescriptorInfo ( this . bytes . subarray ( this . byteOffset ) ) ; descrParser = createDescriptorParser ( this . readBytes ( info . byteLength ) , info . tag ) ; descr = descrParser . parse ( ) ; if ( descrParser instanceof DecoderSpecificInfoParser ) { ret . decSpecificInfo = < IDecoderSpecificInfo > descr ; } else if ( descrParser instanceof ProfileLevelINdicationIndexDescriptor ) { ret . profileLevelIndicationIndexDescrs . push ( < IProfileLevelIndicationIndexDescriptor > descr ) ; } else { throw new TypeError ( ) ; } } return ret ; } } @ Tag ( DESCR_TAG_SL_CONFIG_DESCRIPTOR ) export class SLConfigDescriptorParser extends DescriptorParser { parse ( ) { var ret = < ISLConfigDescriptor > super . parse ( ) ; ret . preDefined = this . readUint8 ( ) ; if ( ret . preDefined === 0 ) { ret . useAccessUnitStartFlag = this . readBits ( 1 ) ; ret . useAccessUnitEndFlag = this . readBits ( 1 ) ; ret . useRandomAccessPointFlag = this . readBits ( 1 ) ; ret . hasRandomAccessUnitsOnlyFlag = this . readBits ( 1 ) ; ret . usePaddingFlag = this . readBits ( 1 ) ; ret . useTimeStampsFlag = this . readBits ( 1 ) ; ret . useIdleFlag = this . readBits ( 1 ) ; ret . durationFlag = this . readBits ( 1 ) ; ret . timeStampResolution = this . readUint32 ( ) ; ret . ocrResolution = this . readUint32 ( ) ; ret . timeStampLength = this . readUint8 ( ) ; ret . ocrLength = this . readUint8 ( ) ; ret . auLength = this . readUint8 ( ) ; ret . instantBitrateLength = this . readUint8 ( ) ; ret . degradationPriorityLength = this . readBits ( 4 ) ; ret . auSeqNumLength = this . readBits ( 5 ) ; ret . packetSeqNumLength = this . readBits ( 5 ) ; this . skipBits ( 2 ) ; } if ( ret . durationFlag ) { ret . timeScale = this . readUint32 ( ) ; ret . accessUnitDuration = this . readUint16 ( ) ; ret . compositionUnitDuration = this . readUint16 ( ) ; } if ( ret . useTimeStampsFlag === 0 ) { ret . startDecodingTimeStamp = this . readBits ( ret . timeStampLength ) ; ret . startCompositionTimeStamp = this . readBits ( ret . timeStampLength ) ; } return ret ; } } export class IPIDescriptorPointerParser extends DescriptorParser { } export class IPIdentificationDataSetParser extends DescriptorParser { } export class IPMPDescriptorPointerParser extends DescriptorParser { } export class LanguageDescriptorParser extends DescriptorParser { } export class QosDescriptorParser extends DescriptorParser { } export class ExtensionDescriptorParser extends DescriptorParser { } @ Tag ( DESCR_TAG_ES_DESCRIPTOR ) export class ESDescriptorParser extends DescriptorParser { parse ( ) { var ret = < IESDescriptor > super . parse ( ) ; var descr ; ret . esID = this . readUint16 ( ) ; ret . streamDependenceFlag = this . readBits ( 1 ) ; ret . urlFlag = this . readBits ( 1 ) ; ret . ocrStreamFlag = this . readBits ( 1 ) ; ret . streamPriority = this . readBits ( 5 ) ; if ( ret . streamDependenceFlag ) { ret . dependsOnEsID = this . readUint16 ( ) ; } if ( ret . urlFlag ) { ret . urlLength = this . readUint8 ( ) ; ret . urlString = this . readString ( ret . urlLength ) ; } if ( ret . ocrStreamFlag ) { ret . ocrEsID = this . readUint16 ( ) ; } while ( ! this . eof ( ) ) { descr = this . readDescriptor ( ) ; switch ( descr . tag ) { case DESCR_TAG_DECODER_CONFIG_DESCRIPTOR : ret . decConfigDescr = < IDecoderConfigDescriptor > descr ; break ; case DESCR_TAG_SL_CONFIG_DESCRIPTOR : ret . slConfigDescr = < ISLConfigDescriptor > descr ; break ; } } return ret ; } } @ Tag ( [ 0x02 , 0x10 ] ) export class InitialObjectDescriptorParser extends DescriptorParser { parse ( ) { var ret = < IInitialObjectDescriptor > super . parse ( ) ; ret . objectDescrID = this . readBits ( 10 ) ; ret . urlFlag = this . readBits ( 1 ) ; ret . includeInlineProfileLevelFlag = this . readBits ( 1 ) ; this . skipBits ( 4 ) ; if ( ret . urlFlag ) { ret . urlLength = this . readUint8 ( ) ; ret . urlString = this . readString ( ret . urlLength ) ; } else { ret . odProfileLevelIndication = this . readUint8 ( ) ; ret . sceneProfileLevelIndication = this . readUint8 ( ) ; ret . audioProfileLevelIndication = this . readUint8 ( ) ; ret . visualProfileLevelIndication = this . readUint8 ( ) ; ret . graphicsProfileLevelIndication = this . readUint8 ( ) ; } ret . extDescrs = [ ] ; if ( ret . urlFlag ) while ( ! this . eof ( ) ) { ret . extDescrs . push ( < IExtensionDescriptor > this . readDescriptor ( ) ) ; } return ret ; } } export var createDescriptorParser = ( bytes , tag ) : DescriptorParser => { return new ( dict [ tag ] || DescriptorParser ) ( bytes ) ; } ;