a35f70c6 by David LaPalomento

Add tfdt to track fragment boxes

According to the byte stream format registry, a media segment should contain at least one track fragment decode timestamp box.
1 parent 31946efc
...@@ -37,6 +37,7 @@ DataView = window.DataView; ...@@ -37,6 +37,7 @@ DataView = window.DataView;
37 stsz: [], 37 stsz: [],
38 stts: [], 38 stts: [],
39 styp: [], 39 styp: [],
40 tfdt: [],
40 tfhd: [], 41 tfhd: [],
41 traf: [], 42 traf: [],
42 trak: [], 43 trak: [],
...@@ -406,7 +407,12 @@ traf = function(track) { ...@@ -406,7 +407,12 @@ traf = function(track) {
406 (track.id & 0xFF000000) >> 24, 407 (track.id & 0xFF000000) >> 24,
407 (track.id & 0xFF0000) >> 16, 408 (track.id & 0xFF0000) >> 16,
408 (track.id & 0xFF00) >> 8, 409 (track.id & 0xFF00) >> 8,
409 (track.id & 0xFF), 410 (track.id & 0xFF) // track_ID
411 ])),
412 box(types.tfdt, new Uint8Array([
413 0x00, // version 0
414 0x00, 0x00, 0x00, // flags
415 0x00, 0x00, 0x00, 0x00 // baseMediaDecodeTime
410 ])), 416 ])),
411 trun(track)); 417 trun(track));
412 }; 418 };
...@@ -445,11 +451,12 @@ trun = function(track) { ...@@ -445,11 +451,12 @@ trun = function(track) {
445 451
446 bytes = [ 452 bytes = [
447 0x00, // version 0 453 0x00, // version 0
448 0x00, 0x0f, 0x00, // flags 454 0x00, 0x0f, 0x01, // flags
449 (samples.length & 0xFF000000) >>> 24, 455 (samples.length & 0xFF000000) >>> 24,
450 (samples.length & 0xFF0000) >>> 16, 456 (samples.length & 0xFF0000) >>> 16,
451 (samples.length & 0xFF00) >>> 8, 457 (samples.length & 0xFF00) >>> 8,
452 samples.length & 0xFF // sample_count 458 samples.length & 0xFF, // sample_count
459 0x00, 0x00, 0x00, 0x00 // data_offset
453 ]; 460 ];
454 461
455 for (i = 0; i < samples.length; i++) { 462 for (i = 0; i < samples.length; i++) {
......
...@@ -339,12 +339,19 @@ test('generates a minimal moof', function() { ...@@ -339,12 +339,19 @@ test('generates a minimal moof', function() {
339 equal(moof[0].boxes[0].type, 'mfhd', 'generated an mfhd box'); 339 equal(moof[0].boxes[0].type, 'mfhd', 'generated an mfhd box');
340 equal(moof[0].boxes[0].sequenceNumber, 7, 'included the sequence_number'); 340 equal(moof[0].boxes[0].sequenceNumber, 7, 'included the sequence_number');
341 equal(moof[0].boxes[1].type, 'traf', 'generated a traf box'); 341 equal(moof[0].boxes[1].type, 'traf', 'generated a traf box');
342 equal(moof[0].boxes[1].boxes.length, 2, 'generated track fragment info'); 342 equal(moof[0].boxes[1].boxes.length, 3, 'generated track fragment info');
343 equal(moof[0].boxes[1].boxes[0].type, 'tfhd', 'generated a tfhd box'); 343 equal(moof[0].boxes[1].boxes[0].type, 'tfhd', 'generated a tfhd box');
344 equal(moof[0].boxes[1].boxes[0].trackId, 17, 'wrote the first track id'); 344 equal(moof[0].boxes[1].boxes[0].trackId, 17, 'wrote the first track id');
345 equal(moof[0].boxes[1].boxes[0].type, 'tfhd', 'generated a tfhd box'); 345 equal(moof[0].boxes[1].boxes[0].baseDataOffset, undefined, 'did not set a base data offset');
346 trun = moof[0].boxes[1].boxes[1]; 346
347 equal(moof[0].boxes[1].boxes[1].type, 'tfdt', 'generated a tfdt box');
348 ok(moof[0].boxes[1].boxes[1].baseMediaDecodeTime >= 0,
349 'media decode time is non-negative');
350
351 trun = moof[0].boxes[1].boxes[2];
347 equal(trun.type, 'trun', 'generated a trun box'); 352 equal(trun.type, 'trun', 'generated a trun box');
353 equal(typeof trun.dataOffset, 'number', 'has a data offset');
354 ok(trun.dataOffset >= 0, 'has a non-negative data offset');
348 equal(trun.samples.length, 2, 'wrote two samples'); 355 equal(trun.samples.length, 2, 'wrote two samples');
349 356
350 equal(trun.samples[0].duration, 9000, 'wrote a sample duration'); 357 equal(trun.samples[0].duration, 9000, 'wrote a sample duration');
...@@ -381,7 +388,7 @@ test('can generate a traf without samples', function() { ...@@ -381,7 +388,7 @@ test('can generate a traf without samples', function() {
381 }]), 388 }]),
382 moof = videojs.inspectMp4(data); 389 moof = videojs.inspectMp4(data);
383 390
384 equal(moof[0].boxes[1].boxes[1].samples.length, 0, 'generated no samples'); 391 equal(moof[0].boxes[1].boxes[2].samples.length, 0, 'generated no samples');
385 }); 392 });
386 393
387 test('generates an mdat', function() { 394 test('generates an mdat', function() {
......
...@@ -671,7 +671,7 @@ test('can parse a moof', function() { ...@@ -671,7 +671,7 @@ test('can parse a moof', function() {
671 type: 'tfhd', 671 type: 'tfhd',
672 version: 0, 672 version: 0,
673 size: 40, 673 size: 40,
674 flags: new Uint8Array([0, 0, 0x3b]), 674 flags: new Uint8Array([0x00, 0, 0x3b]),
675 trackId: 1, 675 trackId: 1,
676 baseDataOffset: 1, 676 baseDataOffset: 1,
677 sampleDescriptionIndex: 2, 677 sampleDescriptionIndex: 2,
......
...@@ -880,7 +880,13 @@ validateTrackFragment = function(track, metadata) { ...@@ -880,7 +880,13 @@ validateTrackFragment = function(track, metadata) {
880 equal(tfhd.type, 'tfhd', 'wrote a track fragment header'); 880 equal(tfhd.type, 'tfhd', 'wrote a track fragment header');
881 equal(tfhd.trackId, metadata.trackId, 'wrote the track id'); 881 equal(tfhd.trackId, metadata.trackId, 'wrote the track id');
882 882
883 trun = track.boxes[1]; 883 equal(track.boxes[1].type,
884 'tfdt',
885 'wrote a track fragment decode time box');
886 ok(track.boxes[1].baseMediaDecodeTime >= 0, 'base decode time is valid');
887
888 trun = track.boxes[2];
889 ok(trun.dataOffset >= 0, 'set data offset');
884 ok(trun.samples.length > 0, 'generated media samples'); 890 ok(trun.samples.length > 0, 'generated media samples');
885 for (i = 0; i < trun.samples.length; i++) { 891 for (i = 0; i < trun.samples.length; i++) {
886 sample = trun.samples[i]; 892 sample = trun.samples[i];
......