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.
Showing
4 changed files
with
29 additions
and
9 deletions
... | @@ -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]; | ... | ... |
-
Please register or sign in to post a comment