| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 | /** * mux.js * * Copyright (c) Brightcove * Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE */'use strict';var ExpGolomb;/** * Parser for exponential Golomb codes, a variable-bitwidth number encoding * scheme used by h264. */ExpGolomb = function(workingData) {  var    // the number of bytes left to examine in workingData    workingBytesAvailable = workingData.byteLength,    // the current word being examined    workingWord = 0, // :uint    // the number of bits left to examine in the current word    workingBitsAvailable = 0; // :uint;  // ():uint  this.length = function() {    return (8 * workingBytesAvailable);  };  // ():uint  this.bitsAvailable = function() {    return (8 * workingBytesAvailable) + workingBitsAvailable;  };  // ():void  this.loadWord = function() {    var      position = workingData.byteLength - workingBytesAvailable,      workingBytes = new Uint8Array(4),      availableBytes = Math.min(4, workingBytesAvailable);    if (availableBytes === 0) {      throw new Error('no bytes available');    }    workingBytes.set(workingData.subarray(position,                                          position + availableBytes));    workingWord = new DataView(workingBytes.buffer).getUint32(0);    // track the amount of workingData that has been processed    workingBitsAvailable = availableBytes * 8;    workingBytesAvailable -= availableBytes;  };  // (count:int):void  this.skipBits = function(count) {    var skipBytes; // :int    if (workingBitsAvailable > count) {      workingWord          <<= count;      workingBitsAvailable -= count;    } else {      count -= workingBitsAvailable;      skipBytes = Math.floor(count / 8);      count -= (skipBytes * 8);      workingBytesAvailable -= skipBytes;      this.loadWord();      workingWord <<= count;      workingBitsAvailable -= count;    }  };  // (size:int):uint  this.readBits = function(size) {    var      bits = Math.min(workingBitsAvailable, size), // :uint      valu = workingWord >>> (32 - bits); // :uint    // if size > 31, handle error    workingBitsAvailable -= bits;    if (workingBitsAvailable > 0) {      workingWord <<= bits;    } else if (workingBytesAvailable > 0) {      this.loadWord();    }    bits = size - bits;    if (bits > 0) {      return valu << bits | this.readBits(bits);    }    return valu;  };  // ():uint  this.skipLeadingZeros = function() {    var leadingZeroCount; // :uint    for (leadingZeroCount = 0; leadingZeroCount < workingBitsAvailable; ++leadingZeroCount) {      if ((workingWord & (0x80000000 >>> leadingZeroCount)) !== 0) {        // the first bit of working word is 1        workingWord <<= leadingZeroCount;        workingBitsAvailable -= leadingZeroCount;        return leadingZeroCount;      }    }    // we exhausted workingWord and still have not found a 1    this.loadWord();    return leadingZeroCount + this.skipLeadingZeros();  };  // ():void  this.skipUnsignedExpGolomb = function() {    this.skipBits(1 + this.skipLeadingZeros());  };  // ():void  this.skipExpGolomb = function() {    this.skipBits(1 + this.skipLeadingZeros());  };  // ():uint  this.readUnsignedExpGolomb = function() {    var clz = this.skipLeadingZeros(); // :uint    return this.readBits(clz + 1) - 1;  };  // ():int  this.readExpGolomb = function() {    var valu = this.readUnsignedExpGolomb(); // :int    if (0x01 & valu) {      // the number is odd if the low order bit is set      return (1 + valu) >>> 1; // add 1 to make it even, and divide by 2    }    return -1 * (valu >>> 1); // divide by two then make it negative  };  // Some convenience functions  // :Boolean  this.readBoolean = function() {    return this.readBits(1) === 1;  };  // ():int  this.readUnsignedByte = function() {    return this.readBits(8);  };  this.loadWord();};module.exports = ExpGolomb;
 |