4fd2994e by David LaPalomento

@mikrohard: wait for an SPS to inject metadata tags. Closes #280

Merge branch 'missing-extradata'. Issue 2 from #279.
2 parents 63c045e6 86b0e096
......@@ -6,6 +6,7 @@ CHANGELOG
* @dmlap add a contribflow configuration ([view](https://github.com/videojs/videojs-contrib-hls/pull/276))
* @ntadej Do not unnecessarily reset to the live point when refreshing playlists. Clean up playlist loader timeouts. ([view](https://github.com/videojs/videojs-contrib-hls/pull/274))
* @gkatsev ensure segments without an initial IDR are not displayed in 4
* @mikrohard: wait for an SPS to inject metadata tags. ([view](https://github.com/videojs/videojs-contrib-hls/pull/280))
--------------------
......
......@@ -80,7 +80,8 @@
// Check if keyframe and the length of tags.
// This makes sure we write metadata on the first frame of a segment.
if (this._h264Frame.keyFrame || this.tags.length === 0) {
if (this._oldExtraData.extraDataExists() &&
(this._h264Frame.keyFrame || this.tags.length === 0)) {
// Push extra data on every IDR frame in case we did a stream change + seek
this.tags.push(this._oldExtraData.metaDataTag(this._h264Frame.pts));
this.tags.push(this._oldExtraData.extraDataTag(this._h264Frame.pts));
......
......@@ -3,42 +3,43 @@ module('H264 Stream');
var
nalUnitTypes = window.videojs.Hls.NALUnitType,
FlvTag = window.videojs.Hls.FlvTag;
FlvTag = window.videojs.Hls.FlvTag,
accessUnitDelimiter = new Uint8Array([
0x00,
0x00,
0x01,
nalUnitTypes.access_unit_delimiter_rbsp
]),
seqParamSet = new Uint8Array([
0x00,
0x00,
0x01,
0x60 | nalUnitTypes.seq_parameter_set_rbsp,
0x00, // profile_idc
0x00, // constraint_set flags
0x00, // level_idc
// seq_parameter_set_id ue(v) 0 => 1
// log2_max_frame_num_minus4 ue(v) 1 => 010
// pic_order_cnt_type ue(v) 0 => 1
// log2_max_pic_order_cnt_lsb_minus4 ue(v) 1 => 010
// max_num_ref_frames ue(v) 1 => 010
// gaps_in_frame_num_value_allowed u(1) 0
// pic_width_in_mbs_minus1 ue(v) 0 => 1
// pic_height_in_map_units_minus1 ue(v) 0 => 1
// frame_mbs_only_flag u(1) 1
// direct_8x8_inference_flag u(1) 0
// frame_cropping_flag u(1) 0
// vui_parameters_present_flag u(1) 0
// 1010 1010 0100 1110 00(00 0000)
0xAA,
0x4E,
0x00
]);
test('metadata is generated for IDRs after a full NAL unit is written', function() {
var
h264Stream = new videojs.Hls.H264Stream(),
accessUnitDelimiter = new Uint8Array([
0x00,
0x00,
0x01,
nalUnitTypes.access_unit_delimiter_rbsp
]),
seqParamSet = new Uint8Array([
0x00,
0x00,
0x01,
0x60 | nalUnitTypes.seq_parameter_set_rbsp,
0x00, // profile_idc
0x00, // constraint_set flags
0x00, // level_idc
// seq_parameter_set_id ue(v) 0 => 1
// log2_max_frame_num_minus4 ue(v) 1 => 010
// pic_order_cnt_type ue(v) 0 => 1
// log2_max_pic_order_cnt_lsb_minus4 ue(v) 1 => 010
// max_num_ref_frames ue(v) 1 => 010
// gaps_in_frame_num_value_allowed u(1) 0
// pic_width_in_mbs_minus1 ue(v) 0 => 1
// pic_height_in_map_units_minus1 ue(v) 0 => 1
// frame_mbs_only_flag u(1) 1
// direct_8x8_inference_flag u(1) 0
// frame_cropping_flag u(1) 0
// vui_parameters_present_flag u(1) 0
// 1010 1010 0100 1110 00(00 0000)
0xAA,
0x4E,
0x00
]),
idr = new Uint8Array([
0x00,
0x00,
......@@ -65,13 +66,7 @@ test('starting PTS values can be negative', function() {
H264ExtraData = videojs.Hls.H264ExtraData,
oldExtraData = H264ExtraData.prototype.extraDataTag,
oldMetadata = H264ExtraData.prototype.metaDataTag,
h264Stream,
accessUnitDelimiter = new Uint8Array([
0x00,
0x00,
0x01,
nalUnitTypes.access_unit_delimiter_rbsp
]);
h264Stream;
H264ExtraData.prototype.extraDataTag = function() {
return 'extraDataTag';
......@@ -92,10 +87,6 @@ test('starting PTS values can be negative', function() {
// flush out the last tag
h264Stream.writeBytes(accessUnitDelimiter, 0, accessUnitDelimiter.byteLength);
// shift the metadata and extradata tags out, since we don't care about them here
h264Stream.tags.shift();
h264Stream.tags.shift();
strictEqual(h264Stream.tags.length, 3, 'three tags are ready');
strictEqual(h264Stream.tags[0].pts, 0, 'the first PTS is zero');
strictEqual(h264Stream.tags[0].dts, 0, 'the first DTS is zero');
......@@ -114,13 +105,7 @@ test('make sure we add metadata and extra data at the beginning of a stream', fu
H264ExtraData = videojs.Hls.H264ExtraData,
oldExtraData = H264ExtraData.prototype.extraDataTag,
oldMetadata = H264ExtraData.prototype.metaDataTag,
h264Stream,
accessUnitDelimiter = new Uint8Array([
0x00,
0x00,
0x01,
nalUnitTypes.access_unit_delimiter_rbsp
]);
h264Stream;
H264ExtraData.prototype.extraDataTag = function() {
return 'extraDataTag';
......@@ -133,6 +118,8 @@ test('make sure we add metadata and extra data at the beginning of a stream', fu
h264Stream.setTimeStampOffset(0);
h264Stream.setNextTimeStamp(0, 0, true);
// the sps provides the metadata for the stream
h264Stream.writeBytes(seqParamSet, 0, seqParamSet.byteLength);
h264Stream.writeBytes(accessUnitDelimiter, 0, accessUnitDelimiter.byteLength);
// make sure that keyFrame is set to false but that we don't have any tags currently written out
......@@ -148,11 +135,6 @@ test('make sure we add metadata and extra data at the beginning of a stream', fu
strictEqual(h264Stream.tags[0], 'metaDataTag', 'the first tag is the metaDataTag');
strictEqual(h264Stream.tags[1], 'extraDataTag', 'the second tag is the extraDataTag');
strictEqual(h264Stream.tags[2].pts, 0, 'the first PTS is 0');
strictEqual(h264Stream.tags[2].dts, 0, 'the first DTS is 0');
strictEqual(h264Stream.tags[3].pts, 5, 'the second PTS is 5');
strictEqual(h264Stream.tags[3].dts, 5, 'the second DTS is 5');
H264ExtraData.prototype.extraDataTag = oldExtraData;
H264ExtraData.prototype.metaDataTag = oldMetadata;
});
......