diff --git a/src/h264-stream.js b/src/h264-stream.js index e122f1a9..c8de69e8 100644 --- a/src/h264-stream.js +++ b/src/h264-stream.js @@ -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._oldExtraData.extraDataExists() && (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)); diff --git a/test/h264-stream_test.js b/test/h264-stream_test.js index 92360361..d36fb448 100644 --- a/test/h264-stream_test.js +++ b/test/h264-stream_test.js @@ -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; });