| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173 | 'use strict';/*  ======== A Handy Little QUnit Reference ========  http://api.qunitjs.com/  Test methods:  module(name, {[setup][ ,teardown]})  QUnit.test(name, callback)  expect(numberOfAssertions)  stop(increment)  start(decrement)  Test assertions:  assert.ok(value, [message])  assert.equal(actual, expected, [message])  notEqual(actual, expected, [message])  assert.deepEqual(actual, expected, [message])  notDeepEqual(actual, expected, [message])  assert.strictEqual(actual, expected, [message])  notStrictEqual(actual, expected, [message])  throws(block, [expected], [message])*/var  mp4 = require('../lib/mp4'),  mp4Helpers = require('./utils/mp4-helpers'),  QUnit = require('qunit'),  window = require('global/window'),  typeBytes = mp4Helpers.typeBytes,  box = mp4Helpers.box,  unityMatrix = mp4Helpers.unityMatrix,  BigInt = window.BigInt || Number,  mvhd0 = box('mvhd',             0x00, // version 0             0x00, 0x00, 0x00, // flags             0x00, 0x00, 0x00, 0x01, // creation_time             0x00, 0x00, 0x00, 0x02, // modification_time             0x00, 0x00, 0x00, 0x3c, // timescale             0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration             0x00, 0x01, 0x00, 0x00, // 1.0 rate             0x01, 0x00, // 1.0 volume             0x00, 0x00, // reserved             0x00, 0x00, 0x00, 0x00, // reserved             0x00, 0x00, 0x00, 0x00, // reserved             unityMatrix,             0x00, 0x00, 0x00, 0x00,             0x00, 0x00, 0x00, 0x00,             0x00, 0x00, 0x00, 0x00,             0x00, 0x00, 0x00, 0x00,             0x00, 0x00, 0x00, 0x00,             0x00, 0x00, 0x00, 0x00, // pre_defined             0x00, 0x00, 0x00, 0x02),  tkhd0 = box('tkhd',              0x00, // version 0              0x00, 0x00, 0x00, // flags              0x00, 0x00, 0x00, 0x02, // creation_time              0x00, 0x00, 0x00, 0x03, // modification_time              0x00, 0x00, 0x00, 0x01, // track_ID              0x00, 0x00, 0x00, 0x00, // reserved              0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration              0x00, 0x00, 0x00, 0x00,              0x00, 0x00, 0x00, 0x00, // reserved              0x00, 0x00, // layer              0x00, 0x00, // alternate_group              0x00, 0x00, // non-audio track volume              0x00, 0x00, // reserved              unityMatrix,              0x01, 0x2c, 0x80, 0x00, // 300.5 in 16.16 fixed point              0x00, 0x96, 0x80, 0x00), // 150.5 in 16.16 fixed point  mdhd0 = box('mdhd',              0x00, // version 0              0x00, 0x00, 0x00, // flags              0x00, 0x00, 0x00, 0x02, // creation_time              0x00, 0x00, 0x00, 0x03, // modification_time              0x00, 0x00, 0x00, 0x3c, // timescale              0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration              0x15, 0xc7, // 'eng' language              0x00, 0x00);QUnit.module('MP4 Inspector');QUnit.test('produces an empty array for empty input', function(assert) {  assert.strictEqual(mp4.tools.inspect(new Uint8Array([])).length, 0, 'returned an empty array');});QUnit.test('can parse a Box', function(assert) {  var box = new Uint8Array([    0x00, 0x00, 0x00, 0x00, // size 0    0x00, 0x00, 0x00, 0x00 // boxtype 0  ]);  assert.deepEqual(mp4.tools.inspect(box), [{    type: '\u0000\u0000\u0000\u0000',    size: 0,    data: box.subarray(box.byteLength)  }], 'parsed a Box');});QUnit.test('can parse an ftyp', function(assert) {  assert.deepEqual(mp4.tools.inspect(new Uint8Array(box('ftyp',    0x61, 0x76, 0x63, 0x31, // major brand    0x00, 0x00, 0x00, 0x02, // minor version    98, 111, 111, 112, // compatible brands    98, 101, 101, 112 // compatible brands  ))), [{    type: 'ftyp',    size: 4 * 6,    majorBrand: 'avc1',    minorVersion: 2,    compatibleBrands: ['boop', 'beep']  }], 'parsed an ftyp');});QUnit.test('can parse a pdin', function(assert) {  assert.deepEqual(mp4.tools.inspect(new Uint8Array(box('pdin',    0x01, // version 1    0x01, 0x02, 0x03, // flags    0x00, 0x00, 0x04, 0x00, // 1024 = 0x400 bytes/second rate    0x00, 0x00, 0x00, 0x01 // initial delay  ))), [{    size: 20,    type: 'pdin',    version: 1,    flags: new Uint8Array([1, 2, 3]),    rate: 1024,    initialDelay: 1  }], 'parsed a pdin');});QUnit.test('can parse an mdat', function(assert) {  var mdat = new Uint8Array(box('mdat',      0, 0, 0, 4, // length      0x01, 0x02, 0x03, 0x04 // data    ));  assert.deepEqual(mp4.tools.inspect(mdat), [{    size: 16,    type: 'mdat',    nals: [      'slice_layer_without_partitioning_rbsp'    ],    byteLength: 8  }], 'parsed an mdat');});QUnit.test('can parse a free or skip', function(assert) {  var    free = new Uint8Array(box('free',                              0x01, 0x02, 0x03, 0x04)), // data    skip = new Uint8Array(box('skip',                              0x01, 0x02, 0x03, 0x04)); // data  assert.deepEqual(mp4.tools.inspect(free), [{      size: 12,      type: 'free',      data: free.subarray(free.byteLength - 4)    }], 'parsed a free');  assert.deepEqual(mp4.tools.inspect(skip), [{      size: 12,      type: 'skip',      data: skip.subarray(skip.byteLength - 4)    }], 'parsed a skip');});QUnit.test('can parse a version 0 mvhd', function(assert) {  assert.deepEqual(mp4.tools.inspect(new Uint8Array(mvhd0)), [{    type: 'mvhd',    version: 0,    flags: new Uint8Array([0, 0, 0]),    creationTime: new Date(1000 - 2082844800000),    modificationTime: new Date(2000 - 2082844800000),    timescale: 60,    duration: 600,    rate: 1,    volume: 1,    matrix: new Uint32Array(unityMatrix),    size: 108,    nextTrackId: 2  }]);});QUnit.test('can parse a version 0 tkhd', function(assert) {  assert.deepEqual(mp4.tools.inspect(new Uint8Array(tkhd0)), [{    type: 'tkhd',    version: 0,    flags: new Uint8Array([0, 0, 0]),    creationTime: new Date(2000 - 2082844800000),    modificationTime: new Date(3000 - 2082844800000),    size: 92,    trackId: 1,    duration: 600,    layer: 0,    alternateGroup: 0,    volume: 0,    matrix: new Uint32Array(unityMatrix),    width: 300.5,    height: 150.5  }]);});QUnit.test('can parse a version 0 mdhd', function(assert) {  assert.deepEqual(mp4.tools.inspect(new Uint8Array(mdhd0)), [{    type: 'mdhd',    version: 0,    flags: new Uint8Array([0, 0, 0]),    creationTime: new Date(2000 - 2082844800000),    modificationTime: new Date(3000 - 2082844800000),    size: 32,    timescale: 60,    duration: 600,    language: 'eng'  }]);});QUnit.test('can parse a moov', function(assert) {  var data = mp4Helpers.sampleMoov;  QUnit.dump.maxDepth = 100;  var result = QUnit.dump.parse(mp4.tools.inspect(new Uint8Array(data)));  var expected = QUnit.dump.parse([{    type: 'moov',    size: 1129,    boxes: [{      type: 'mvhd',      version: 1,      flags: new Uint8Array([0, 0, 0]),      creationTime: new Date(1000 - 2082844800000),      modificationTime: new Date(2000 - 2082844800000),      timescale: 1000,      duration: 600,      rate: 1,      size: 120,      volume: 1,      matrix: new Uint32Array(unityMatrix),      nextTrackId: 2    }, {      type: 'trak',      size: 519,      boxes: [{        type: 'tkhd',        flags: new Uint8Array([0, 0, 0]),        version: 1,        creationTime: new Date(2000 - 2082844800000),        modificationTime: new Date(3000 - 2082844800000),        size: 104,        trackId: 1,        duration: 600,        layer: 0,        alternateGroup: 0,        volume: 0,        matrix: new Uint32Array(unityMatrix),        width: 300,        height: 150      }, {        type: 'edts',        size: 36,        boxes: [{          type: 'elst',          size: 28,          version: 0,          flags: new Uint8Array([0, 0, 0]),          edits: [{            segmentDuration: 0,            mediaTime: 1024,            mediaRate: 1.5          }]        }]      }, {        type: 'mdia',        size: 371,        boxes: [{          type: 'mdhd',          version: 1,          flags: new Uint8Array([0, 0, 0]),          creationTime: new Date(2000 - 2082844800000),          modificationTime: new Date(3000 - 2082844800000),          timescale: 90e3,          duration: 600,          language: 'eng',          size: 44        }, {          type: 'hdlr',          version: 1,          flags: new Uint8Array([0, 0, 0]),          handlerType: 'vide',          name: 'one',          size: 37        }, {          type: 'minf',          size: 282,          boxes: [{            type: 'dinf',            size: 36,            boxes: [{              type: 'dref',              size: 28,              version: 1,              flags: new Uint8Array([0, 0, 0]),              dataReferences: [{                type: 'url ',                size: 12,                version: 0,                flags: new Uint8Array([0, 0, 1])              }]            }]          }, {            type: 'stbl',            size: 238,            boxes: [{              type: 'stsd',              size: 114,              version: 1,              flags: new Uint8Array([0, 0, 0]),              sampleDescriptions: [{                config: [                  {                    avcLevelIndication: 13,                    avcProfileIndication: 77,                    configurationVersion: 0,                    lengthSizeMinusOne: 0,                    pps: [],                    profileCompatibility: 64,                    size: 0,                    sps: [],                    type: 'avcC'                  }                ],                dataReferenceIndex: 0,                depth: 0,                frameCount: 0,                height: 0,                horizresolution: 0,                size: 98,                type: 'avc1',                vertresolution: 0,                width: 0              }              ]            }, {              type: 'stts',              size: 24,              version: 1,              flags: new Uint8Array([0, 0, 0]),              timeToSamples: [{                sampleCount: 1,                sampleDelta: 1              }]            }, {              type: 'stsc',              version: 1,              flags: new Uint8Array([0, 0, 0]),              sampleToChunks: [{                firstChunk: 2,                samplesPerChunk: 3,                sampleDescriptionIndex: 1              }],              size: 28            }, {              type: 'stco',              size: 20,              version: 1,              flags: new Uint8Array([0, 0, 0]),              chunkOffsets: [1]            }, {              type: 'stss',              size: 20,              version: 0,              flags: new Uint8Array([0, 0, 0]),              syncSamples: [1]            }, {              type: 'ctts',              size: 24,              version: 0,              flags: new Uint8Array([0, 0, 0]),              compositionOffsets: [                { sampleCount: 1, sampleOffset: 1 }              ]            }]          }]        }]      }]    }, {      type: 'trak',      size: 482,      boxes: [{        type: 'tkhd',        flags: new Uint8Array([0, 0, 0]),        version: 1,        creationTime: new Date(2000 - 2082844800000),        modificationTime: new Date(3000 - 2082844800000),        size: 104,        trackId: 2,        duration: 600,        layer: 0,        alternateGroup: 0,        volume: 0,        matrix: new Uint32Array(unityMatrix),        width: 300,        height: 150      }, {        type: 'edts',        size: 44,        boxes: [{          type: 'elst',          size: 36,          version: 1,          flags: new Uint8Array([0, 0, 0]),          edits: [{            segmentDuration: 0,            mediaTime: BigInt('0x1000000000000000'),            mediaRate: 1.5          }]        }]      }, {        type: 'mdia',        size: 326,        boxes: [{          type: 'mdhd',          version: 1,          flags: new Uint8Array([0, 0, 0]),          creationTime: new Date(2000 - 2082844800000),          modificationTime: new Date(3000 - 2082844800000),          timescale: 90e3,          duration: 600,          language: 'eng',          size: 44        }, {          type: 'hdlr',          version: 1,          flags: new Uint8Array([0, 0, 0]),          handlerType: 'soun',          name: 'one',          size: 37        }, {          type: 'minf',          size: 237,          boxes: [{            type: 'dinf',            size: 36,            boxes: [{              type: 'dref',              size: 28,              version: 1,              flags: new Uint8Array([0, 0, 0]),              dataReferences: [{                type: 'url ',                size: 12,                version: 0,                flags: new Uint8Array([0, 0, 1])              }]            }]          }, {            type: 'stbl',            size: 193,            boxes: [{              type: 'stsd',              size: 89,              version: 1,              flags: new Uint8Array([0, 0, 0]),              sampleDescriptions: [{                channelcount: 0,                dataReferenceIndex: 0,                samplerate: 0,                samplesize: 0,                size: 73,                streamDescriptor: {                  decoderConfig: {                    avgBitrate: 0,                    bufferSize: 0,                    decoderConfigDescriptor: {                      audioObjectType: 0,                      channelConfiguration: 0,                      length: 0,                      samplingFrequencyIndex: 0,                      tag: 0                    },                    maxBitrate: 0,                    objectProfileIndication: 64,                    streamType: 2                  },                  esId: 0,                  flags: {                    0: 0,                    1: 0,                    2: 0                  },                  size: 0,                  streamPriority: 0,                  type: 'esds',                  version: 0                },                type: 'mp4a'              }]            }, {              type: 'stts',              size: 24,              version: 1,              flags: new Uint8Array([0, 0, 0]),              timeToSamples: [{                sampleCount: 1,                sampleDelta: 1              }]            }, {              type: 'stsc',              version: 1,              flags: new Uint8Array([0, 0, 0]),              sampleToChunks: [{                firstChunk: 2,                samplesPerChunk: 3,                sampleDescriptionIndex: 1              }],              size: 28            }, {              type: 'ctts',              size: 24,              version: 1,              flags: new Uint8Array([0, 0, 0]),              compositionOffsets: [                { sampleCount: 1, sampleOffset: -1 }              ]            }, {              type: 'stco',              size: 20,              version: 1,              flags: new Uint8Array([0, 0, 0]),              chunkOffsets: [1]            }]          }]        }]      }]    }]  }]);  assert.equal(result, expected, 'can parse moov');});QUnit.test('can parse an mvex', function(assert) {  var mvex =    box('mvex',        box('trex',            0x00, // version            0x00, 0x00, 0x00, // flags            0x00, 0x00, 0x00, 0x01, // track_ID            0x00, 0x00, 0x00, 0x01, // default_sample_description_index            0x00, 0x00, 0x00, 0x02, // default_sample_duration            0x00, 0x00, 0x00, 0x03, // default_sample_size            0x00, 0x61, 0x00, 0x01)); // default_sample_flags  assert.deepEqual(mp4.tools.inspect(new Uint8Array(mvex)), [{    type: 'mvex',    size: 40,    boxes: [{      type: 'trex',      size: 32,      version: 0,      flags: new Uint8Array([0, 0, 0]),      trackId: 1,      defaultSampleDescriptionIndex: 1,      defaultSampleDuration: 2,      defaultSampleSize: 3,      sampleDependsOn: 0,      sampleIsDependedOn: 1,      sampleHasRedundancy: 2,      samplePaddingValue: 0,      sampleIsDifferenceSample: true,      sampleDegradationPriority: 1    }]  }], 'parsed an mvex');});QUnit.test('can parse a video stsd', function(assert) {  var data = box('stsd',                 0x00, // version 0                 0x00, 0x00, 0x00, // flags                 0x00, 0x00, 0x00, 0x01,                 box('avc1',                     0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, // reserved                     0x00, 0x01, // data_reference_index                     0x00, 0x00, // pre_defined                     0x00, 0x00, // reserved                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00, // pre_defined                     0x01, 0x2c, // width = 300                     0x00, 0x96, // height = 150                     0x00, 0x48, 0x00, 0x00, // horizresolution                     0x00, 0x48, 0x00, 0x00, // vertresolution                     0x00, 0x00, 0x00, 0x00, // reserved                     0x00, 0x01, // frame_count                     0x04,                     typeBytes('avc1'),                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, // compressorname                     0x00, 0x18, // depth = 24                     0x11, 0x11, // pre_defined                     box('avcC',                        0x01, // configurationVersion                        0x00, // AVCProfileIndication??                        0x00, // profile_compatibility                        0x00, // AVCLevelIndication                        0x1c, // lengthSizeMinusOne                        0xe1, // numOfSequenceParameterSets                        0x00, 0x01, // sequenceParameterSetLength                        0x00, // "SPS"                        0x02, // numOfPictureParameterSets                        0x00, 0x02, // pictureParameterSetLength                        0x01, 0x02, // "PPS"                        0x00, 0x01, // pictureParameterSetLength                        0xff), // "PPS"                     box('btrt',                        0x00, 0x00, 0x00, 0x00, // bufferSizeDB                        0x00, 0x00, 0x00, 0x01, // maxBitrate                        0x00, 0x00, 0x00, 0x01), // avgBitrate                     box('pasp',                        0x00, 0x00, 0x00, 0x01, // hSpacing                        0x00, 0x00, 0x00, 0x01))); // vSpacing  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)), [{    type: 'stsd',    size: 163,    version: 0,    flags: new Uint8Array([0, 0, 0]),    sampleDescriptions: [{      type: 'avc1',      size: 147,      dataReferenceIndex: 1,      width: 300,      height: 150,      horizresolution: 72,      vertresolution: 72,      frameCount: 1,      depth: 24,      config: [{        type: 'avcC',        size: 25,        configurationVersion: 1,        avcProfileIndication: 0,        profileCompatibility: 0,        avcLevelIndication: 0,        lengthSizeMinusOne: 0,        sps: [new Uint8Array(1)],        pps: [new Uint8Array([1, 2]),              new Uint8Array([0xff])]      }, {        type: 'btrt',        size: 20,        bufferSizeDB: 0,        maxBitrate: 1,        avgBitrate: 1      }, {        type: 'pasp',        size: 16,        data: new Uint8Array([0, 0, 0, 1, 0, 0, 0, 1])      }]    }]  }]);});QUnit.test('can parse an audio stsd', function(assert) {  var data = box('stsd',                 0x00,                         // version 0                 0x00, 0x00, 0x00,             // flags                 0x00, 0x00, 0x00, 0x01,       // entry_count                 box('mp4a',                     0x00, 0x00, 0x00,                     0x00, 0x00, 0x00,         // reserved                     0x00, 0x01,               // data_reference_index                     0x00, 0x00, 0x00, 0x00,                     0x00, 0x00, 0x00, 0x00,   // reserved                     0x00, 0x02,               // channelcount                     0x00, 0x10,               // samplesize                     0x00, 0x00,               // pre_defined                     0x00, 0x00,               // reserved                     0xbb, 0x80, 0x00, 0x00, // samplerate, fixed-point 16.16                     box('esds',                         0x00, // version 0                         0x00, 0x00, 0x00, // flags                         0x03, // tag, ES_DescrTag                         0x00, // length                         0x00, 0x01, // ES_ID                         0x00, // streamDependenceFlag, URL_Flag, reserved, streamPriority                         // DecoderConfigDescriptor                         0x04, // tag, DecoderConfigDescrTag                         0x0d, // length                         0x40, // objectProfileIndication, AAC Main                         0x15, // streamType, AudioStream. upstream, reserved                         0x00, 0x00, 0xff, // bufferSizeDB                         0x00, 0x00, 0x00, 0xff, // maxBitrate                         0x00, 0x00, 0x00, 0xaa, // avgBitrate                         // DecoderSpecificInfo                         0x05, // tag, DecoderSpecificInfoTag                         0x02, // length                         // audioObjectType, samplingFrequencyIndex, channelConfiguration                         0x11, 0x90,                         // GASpecificConfig                         0x06, 0x01, 0x02)));  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)), [{    version: 0,    flags: new Uint8Array([0, 0, 0]),    type: 'stsd',    size: 91,    sampleDescriptions: [{      type: 'mp4a',      dataReferenceIndex: 1,      channelcount: 2,      samplesize: 16,      samplerate: 48000,      size: 75,      streamDescriptor: {        type: 'esds',        version: 0,        size: 39,        flags: new Uint8Array([0, 0, 0]),        esId: 1,        streamPriority: 0,        decoderConfig: {          objectProfileIndication: 0x40,          streamType: 0x05,          bufferSize: 0xff,          maxBitrate: 0xff,          avgBitrate: 0xaa,          decoderConfigDescriptor: {            tag: 5,            length: 2,            audioObjectType: 2,            samplingFrequencyIndex: 3,            channelConfiguration: 2          }        }      }    }]  }], 'parsed an audio stsd');});QUnit.test('can parse an styp', function(assert) {  assert.deepEqual(mp4.tools.inspect(new Uint8Array(box('styp',    0x61, 0x76, 0x63, 0x31, // major brand    0x00, 0x00, 0x00, 0x02, // minor version    98, 111, 111, 112 // compatible brands  ))), [{    type: 'styp',    size: 4 * 5,    majorBrand: 'avc1',    minorVersion: 2,    compatibleBrands: ['boop']  }], 'parsed an styp');});QUnit.test('can parse a vmhd', function(assert) {  var data = box('vmhd',                 0x00, // version                 0x00, 0x00, 0x00, // flags                 0x00, 0x00, // graphicsmode                 0x00, 0x00,                 0x00, 0x00,                 0x00, 0x00); // opcolor  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'vmhd',              size: 20,              version: 0,              flags: new Uint8Array([0, 0, 0]),              graphicsmode: 0,              opcolor: new Uint16Array([0, 0, 0])            }]);});QUnit.test('can parse an stsz', function(assert) {  var data = box('stsz',                 0x00, // version                 0x00, 0x00, 0x00, // flags                 0x00, 0x00, 0x00, 0x00, // sample_size                 0x00, 0x00, 0x00, 0x03, // sample_count                 0x00, 0x00, 0x00, 0x01, // entry_size                 0x00, 0x00, 0x00, 0x02, // entry_size                 0x00, 0x00, 0x00, 0x03); // entry_size  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'stsz',              size: 32,              version: 0,              flags: new Uint8Array([0, 0, 0]),              sampleSize: 0,              entries: [1, 2, 3]            }]);});QUnit.test('can parse a moof', function(assert) {  var data = box('moof',                 box('mfhd',                     0x00, // version                     0x00, 0x00, 0x00, // flags                     0x00, 0x00, 0x00, 0x04), // sequence_number                 box('traf',                     box('tfhd',                        0x00, // version                        0x00, 0x00, 0x3b, // flags                        0x00, 0x00, 0x00, 0x01, // track_ID                        0x00, 0x00, 0x00, 0x00,                        0x00, 0x00, 0x00, 0x01, // base_data_offset                        0x00, 0x00, 0x00, 0x02, // sample_description_index                        0x00, 0x00, 0x00, 0x03, // default_sample_duration,                        0x00, 0x00, 0x00, 0x04, // default_sample_size                        0x00, 0x00, 0x00, 0x05))); // default_sample_flags  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'moof',              size: 72,              boxes: [{                type: 'mfhd',                size: 16,                version: 0,                flags: new Uint8Array([0, 0, 0]),                sequenceNumber: 4              },              {                type: 'traf',                size: 48,                boxes: [{                  type: 'tfhd',                  version: 0,                  size: 40,                  flags: new Uint8Array([0x00, 0, 0x3b]),                  trackId: 1,                  baseDataOffset: 1,                  sampleDescriptionIndex: 2,                  defaultSampleDuration: 3,                  defaultSampleSize: 4,                  defaultSampleFlags: 5                }]              }]            }]);});QUnit.test('can parse a trun', function(assert) {  var data = box('trun',                 0x00, // version                 0x00, 0x0b, 0x05, // flags                 0x00, 0x00, 0x00, 0x02, // sample_count                 0x00, 0x00, 0x00, 0x01, // data_offset                 // first_sample_flags                 // r:0000 il:10 sdo:01 sido:10 shr:01 spv:111 snss:1                 // dp:1111 1110 1101 1100                 0x09, 0x9f, 0xfe, 0xdc,                 0x00, 0x00, 0x00, 0x09, // sample_duration                 0x00, 0x00, 0x00, 0xff, // sample_size                 0x00, 0x00, 0x00, 0x00, // sample_composition_time_offset                 0x00, 0x00, 0x00, 0x08, // sample_duration                 0x00, 0x00, 0x00, 0xfe, // sample_size                 0x00, 0x00, 0x00, 0x00); // sample_composition_time_offset  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'trun',              version: 0,              size: 48,              flags: new Uint8Array([0, 0x0b, 0x05]),              dataOffset: 1,              samples: [{                duration: 9,                size: 0xff,                flags: {                  isLeading: 2,                  dependsOn: 1,                  isDependedOn: 2,                  hasRedundancy: 1,                  paddingValue: 7,                  isNonSyncSample: 1,                  degradationPriority: 0xfedc                },                compositionTimeOffset: 0              }, {                duration: 8,                size: 0xfe,                compositionTimeOffset: 0              }]            }]);});QUnit.test('can parse a trun with per-sample flags', function(assert) {  var data = box('trun',                 0x00, // version                 0x00, 0x0f, 0x00, // flags                 0x00, 0x00, 0x00, 0x01, // sample_count                 0x00, 0x00, 0x00, 0x09, // sample_duration                 0x00, 0x00, 0x00, 0xff, // sample_size                 // sample_flags                 // r:0000 il:00 sdo:01, sido:11 shr:00 spv:010 snss:0                 // dp: 0001 0010 0011 0100                 0x01, 0xc4, 0x12, 0x34,                 0x00, 0x00, 0x00, 0x00); // sample_composition_time_offset  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'trun',              version: 0,              size: 32,              flags: new Uint8Array([0, 0x0f, 0x00]),              samples: [{                duration: 9,                size: 0xff,                flags: {                  isLeading: 0,                  dependsOn: 1,                  isDependedOn: 3,                  hasRedundancy: 0,                  paddingValue: 2,                  isNonSyncSample: 0,                  degradationPriority: 0x1234                },                compositionTimeOffset: 0              }]            }]);});QUnit.test('can parse an sdtp', function(assert) {  var data = box('sdtp',                 0x00, // version                 0x00, 0x00, 0x00, // flags                 // reserved + sample_depends_on +                 // sample_is_dependend_on + sample_has_redundancy                 0x15,                 // reserved + sample_depends_on +                 // sample_is_dependend_on + sample_has_redundancy                 0x27);  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)), [{    type: 'sdtp',    version: 0,    flags: new Uint8Array([0, 0, 0]),    size: 14,    samples: [{      dependsOn: 1,      isDependedOn: 1,      hasRedundancy: 1    }, {      dependsOn: 2,      isDependedOn: 1,      hasRedundancy: 3    }]  }]);});QUnit.test('can parse a sidx', function(assert) {  var data = box('sidx',                 0x00, // version                 0x00, 0x00, 0x00, // flags                 0x00, 0x00, 0x00, 0x02, // reference_ID                 0x00, 0x00, 0x00, 0x01, // timescale                 0x01, 0x02, 0x03, 0x04, // earliest_presentation_time                 0x00, 0x00, 0x00, 0x00, // first_offset                 0x00, 0x00,             // reserved                 0x00, 0x02,             // reference_count                 // first reference                 0x80, 0x00, 0x00, 0x07, // reference_type(1) + referenced_size(31)                 0x00, 0x00, 0x00, 0x08, // subsegment_duration                 0x80, 0x00, 0x00, 0x09, // starts_with_SAP(1) + SAP_type(3) + SAP_delta_time(28)                 // second reference                 0x00, 0x00, 0x00, 0x03, // reference_type(1) + referenced_size(31)                 0x00, 0x00, 0x00, 0x04, // subsegment_duration                 0x10, 0x00, 0x00, 0x05  // starts_with_SAP(1) + SAP_type(3) + SAP_delta_time(28)                );  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'sidx',              version: 0,              flags: new Uint8Array([0, 0x00, 0x00]),              timescale: 1,              earliestPresentationTime: 0x01020304,              firstOffset: 0,              referenceId: 2,              size: 56,              references: [{                referenceType: 1,                referencedSize: 7,                subsegmentDuration: 8,                startsWithSap: true,                sapType: 0,                sapDeltaTime: 9                }, {                referenceType: 0,                referencedSize: 3,                subsegmentDuration: 4,                startsWithSap: false,                sapType: 1,                sapDeltaTime: 5                }]            }]);});QUnit.test('can parse a version 1 sidx', function(assert) {  var data = box('sidx',                  0x01, // version                  0x00, 0x00, 0x00, // flags                  0x00, 0x00, 0x00, 0x02, // reference_ID                  0x00, 0x00, 0x00, 0x01, // timescale                  0x00, 0x00, 0x00, 0x00, // earliest_presentation_time                  0x01, 0x02, 0x03, 0x04,                  0x00, 0x00, 0x00, 0x00, // first_offset                  0x00, 0x00, 0x00, 0x00,                  0x00, 0x00,             // reserved                  0x00, 0x02,             // reference_count                  // first reference                  0x80, 0x00, 0x00, 0x07, // reference_type(1) + referenced_size(31)                  0x00, 0x00, 0x00, 0x08, // subsegment_duration                  0x80, 0x00, 0x00, 0x09, // starts_with_SAP(1) + SAP_type(3) + SAP_delta_time(28)                  // second reference                  0x00, 0x00, 0x00, 0x03, // reference_type(1) + referenced_size(31)                  0x00, 0x00, 0x00, 0x04, // subsegment_duration                  0x10, 0x00, 0x00, 0x05  // starts_with_SAP(1) + SAP_type(3) + SAP_delta_time(28)  );  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),    [{      type: 'sidx',      version: 1,      flags: new Uint8Array([0, 0x00, 0x00]),      timescale: 1,      earliestPresentationTime: 0x01020304,      firstOffset: 0,      referenceId: 2,      size: 64,      references: [{        referenceType: 1,        referencedSize: 7,        subsegmentDuration: 8,        startsWithSap: true,        sapType: 0,        sapDeltaTime: 9      }, {        referenceType: 0,        referencedSize: 3,        subsegmentDuration: 4,        startsWithSap: false,        sapType: 1,        sapDeltaTime: 5      }]    }]);});QUnit.test('can parse a big version 1 sidx', function(assert) {  var data = box('sidx',                  0x01, // version                  0x00, 0x00, 0x00, // flags                  0x00, 0x00, 0x00, 0x02, // reference_ID                  0x00, 0x00, 0x00, 0x01, // timescale                  0x01, 0x02, 0x03, 0x04, // earliest_presentation_time                  0x05, 0x06, 0x07, 0x08,                  0x08, 0x07, 0x06, 0x05, // first_offset                  0x04, 0x03, 0x02, 0x01,                  0x00, 0x00,             // reserved                  0x00, 0x02,             // reference_count                  // first reference                  0x80, 0x00, 0x00, 0x07, // reference_type(1) + referenced_size(31)                  0x00, 0x00, 0x00, 0x08, // subsegment_duration                  0x80, 0x00, 0x00, 0x09, // starts_with_SAP(1) + SAP_type(3) + SAP_delta_time(28)                  // second reference                  0x00, 0x00, 0x00, 0x03, // reference_type(1) + referenced_size(31)                  0x00, 0x00, 0x00, 0x04, // subsegment_duration                  0x10, 0x00, 0x00, 0x05  // starts_with_SAP(1) + SAP_type(3) + SAP_delta_time(28)  );  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),    [{      type: 'sidx',      version: 1,      flags: new Uint8Array([0, 0x00, 0x00]),      timescale: 1,      earliestPresentationTime: BigInt('0x0102030405060708'),      firstOffset: BigInt('0x0807060504030201'),      referenceId: 2,      size: 64,      references: [{        referenceType: 1,        referencedSize: 7,        subsegmentDuration: 8,        startsWithSap: true,        sapType: 0,        sapDeltaTime: 9      }, {        referenceType: 0,        referencedSize: 3,        subsegmentDuration: 4,        startsWithSap: false,        sapType: 1,        sapDeltaTime: 5      }]    }]);});QUnit.test('can parse an smhd', function(assert) {  var data = box('smhd',                 0x00,             // version                 0x00, 0x00, 0x00, // flags                 0x00, 0xff,       // balance, fixed-point 8.8                 0x00, 0x00);      // reserved  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'smhd',              size: 16,              version: 0,              flags: new Uint8Array([0, 0, 0]),              balance: 0xff / Math.pow(2, 8)            }],            'parsed an smhd');});QUnit.test('can parse a version 0 tfdt', function(assert) {  var data = box('tfdt',                 0x00, // version                 0x00, 0x00, 0x00, // flags                 0x01, 0x02, 0x03, 0x04); // baseMediaDecodeTime  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'tfdt',              version: 0,              size: 16,              flags: new Uint8Array([0, 0, 0]),              baseMediaDecodeTime: 0x01020304            }]);});QUnit.test('can parse a version 1 tfdt and return an unsigned integer value', function(assert) {  var data = box('tfdt',                 0x01, // version                 0x00, 0x00, 0x00, // flags                 0x81, 0x02, 0x03, 0x04,                 0x05, 0x06, 0x07, 0x08); // baseMediaDecodeTime  assert.deepEqual(mp4.tools.inspect(new Uint8Array(data)),            [{              type: 'tfdt',              version: 1,              size: 20,              flags: new Uint8Array([0, 0, 0]),              baseMediaDecodeTime: BigInt('0x8102030405060708')            }]);});QUnit.test('can parse a series of boxes', function(assert) {  var ftyp = [    0x00, 0x00, 0x00, 0x18 // size 4 * 6 = 24  ].concat(typeBytes('ftyp')).concat([    0x69, 0x73, 0x6f, 0x6d, // major brand    0x00, 0x00, 0x00, 0x02, // minor version    98, 101, 101, 112, // compatible brands    98, 111, 111, 112  // compatible brands  ]);  assert.deepEqual(mp4.tools.inspect(new Uint8Array(ftyp.concat(ftyp))),            [{              type: 'ftyp',              size: 4 * 6,              majorBrand: 'isom',              minorVersion: 2,              compatibleBrands: ['beep', 'boop']            }, {              type: 'ftyp',              size: 4 * 6,              majorBrand: 'isom',              minorVersion: 2,              compatibleBrands: ['beep', 'boop']            }],            'parsed two boxes in series');});
 |