import { getBit , paddingByte } from "../../../common/src" ; import { RtpHeader } from "../rtp/rtp" ; import { DePacketizerBase } from "./base" ; export class Vp9RtpPayload implements DePacketizerBase { /**Picture ID (PID) present */ iBit ! : number ; /**Inter-picture predicted frame */ pBit ! : number ; /**Layer indices present */ lBit ! : number ; /**Flexible mode */ fBit ! : number ; /**Start of a frame */ bBit ! : number ; /**End of a frame */ eBit ! : number ; /**Scalability structure */ vBit ! : number ; zBit ! : number ; m ? : number ; pictureId ? : number ; tid ? : number ; u ? : number ; sid ? : number ; /**inter_layer_predicted */ d ? : number ; tl0PicIdx ? : number ; pDiff : number [ ] = [ ] ; n_s ? : number ; y ? : number ; g ? : number ; width : number [ ] = [ ] ; height : number [ ] = [ ] ; n_g : number = 0 ; pgT : number [ ] = [ ] ; pgU : number [ ] = [ ] ; pgP_Diff : number [ ] [ ] = [ ] ; payload ! : Buffer ; static deSerialize ( buf ) { const { p , offset } = this . parseRtpPayload ( buf ) ; p . payload = buf . slice ( offset ) ; return p ; } static parseRtpPayload ( buf ) { const p = new Vp9RtpPayload ( ) ; let offset = 0 ; p . iBit = getBit ( buf [ offset ] , 0 ) ; p . pBit = getBit ( buf [ offset ] , 1 ) ; p . lBit = getBit ( buf [ offset ] , 2 ) ; p . fBit = getBit ( buf [ offset ] , 3 ) ; p . bBit = getBit ( buf [ offset ] , 4 ) ; p . eBit = getBit ( buf [ offset ] , 5 ) ; p . vBit = getBit ( buf [ offset ] , 6 ) ; p . zBit = getBit ( buf [ offset ] , 7 ) ; offset ++ ; if ( p . iBit ) { p . m = getBit ( buf [ offset ] , 0 ) ; if ( p . m ) { const _7 = paddingByte ( getBit ( buf [ offset ] , 1 , 7 ) ) ; const _8 = paddingByte ( buf [ offset + 1 ] ) ; p . pictureId = parseInt ( _7 + _8 , 2 ) ; offset += 2 ; } else { p . pictureId = getBit ( buf [ offset ] , 1 , 7 ) ; offset ++ ; } } if ( p . lBit ) { p . tid = getBit ( buf [ offset ] , 0 , 3 ) ; p . u = getBit ( buf [ offset ] , 3 ) ; p . sid = getBit ( buf [ offset ] , 4 , 3 ) ; p . d = getBit ( buf [ offset ] , 7 ) ; offset ++ ; if ( p . fBit === 0 ) { p . tl0PicIdx = buf [ offset ] ; offset ++ ; } } if ( p . fBit && p . pBit ) { for ( ; ; ) { p . pDiff = [ ... p . pDiff , getBit ( buf [ offset ] , 0 , 7 ) ] ; const n = getBit ( buf [ offset ] , 7 ) ; offset ++ ; if ( n === 0 ) break ; } } if ( p . vBit ) { p . n_s = getBit ( buf [ offset ] , 0 , 3 ) ; p . y = getBit ( buf [ offset ] , 3 ) ; p . g = getBit ( buf [ offset ] , 4 ) ; offset ++ ; if ( p . y ) { [ ... Array ( p . n_s + 1 ) ] . forEach ( ( ) => { p . width . push ( buf . readUInt16BE ( offset ) ) ; offset += 2 ; p . height . push ( buf . readUInt16BE ( offset ) ) ; offset += 2 ; } ) ; } if ( p . g ) { p . n_g = buf [ offset ] ; offset ++ ; } if ( p . n_g > 0 ) { [ ... Array ( p . n_g ) . keys ( ) ] . forEach ( ( i ) => { p . pgT . push ( getBit ( buf [ offset ] , 0 , 3 ) ) ; p . pgU . push ( getBit ( buf [ offset ] , 3 ) ) ; const r = getBit ( buf [ offset ] , 4 , 2 ) ; offset ++ ; p . pgP_Diff [ i ] = [ ] ; if ( r > 0 ) { [ ... Array ( r ) ] . forEach ( ( ) => { p . pgP_Diff [ i ] . push ( buf [ offset ] ) ; offset ++ ; } ) ; } } ) ; } } return { offset , p } ; } static isDetectedFinalPacketInSequence ( header ) { return header . marker ; } get isKeyframe ( ) { return ! ! ( ! this . pBit && this . bBit && ( ! this . sid || ! this . lBit ) ) ; } get isPartitionHead ( ) { return this . bBit && ( ! this . lBit || ! this . d ) ; } }