synchronize timestamp offsets between h.264 and AAC streams
Showing
4 changed files
with
27 additions
and
16 deletions
... | @@ -30,18 +30,17 @@ window.videojs.Hls.AacStream = function() { | ... | @@ -30,18 +30,17 @@ window.videojs.Hls.AacStream = function() { |
30 | 30 | ||
31 | this.tags = []; | 31 | this.tags = []; |
32 | 32 | ||
33 | // (pts:uint, pes_size:int, dataAligned:Boolean):void | 33 | // (pts:uint):void |
34 | this.setNextTimeStamp = function(pts, pes_size, dataAligned) { | 34 | this.setTimeStampOffset = function(pts) { |
35 | |||
36 | // on the first invocation, capture the starting PTS value | ||
37 | pts_offset = pts; | 35 | pts_offset = pts; |
38 | 36 | ||
39 | // keep track of the last time a metadata tag was written out | 37 | // keep track of the last time a metadata tag was written out |
40 | // set the initial value so metadata will be generated before any | 38 | // set the initial value so metadata will be generated before any |
41 | // payload data | 39 | // payload data |
42 | lastMetaPts = pts - 1000; | 40 | lastMetaPts = pts - 1000; |
41 | }; | ||
43 | 42 | ||
44 | // on subsequent invocations, calculate the PTS based on the starting offset | 43 | // (pts:uint, pes_size:int, dataAligned:Boolean):void |
45 | this.setNextTimeStamp = function(pts, pes_size, dataAligned) { | 44 | this.setNextTimeStamp = function(pts, pes_size, dataAligned) { |
46 | next_pts = pts - pts_offset; | 45 | next_pts = pts - pts_offset; |
47 | pes_length = pes_size; | 46 | pes_length = pes_size; |
... | @@ -52,9 +51,6 @@ window.videojs.Hls.AacStream = function() { | ... | @@ -52,9 +51,6 @@ window.videojs.Hls.AacStream = function() { |
52 | } | 51 | } |
53 | }; | 52 | }; |
54 | 53 | ||
55 | this.setNextTimeStamp(pts, pes_size, dataAligned); | ||
56 | }; | ||
57 | |||
58 | // (data:ByteArray, o:int = 0, l:int = 0):void | 54 | // (data:ByteArray, o:int = 0, l:int = 0):void |
59 | this.writeBytes = function(data, offset, length) { | 55 | this.writeBytes = function(data, offset, length) { |
60 | var | 56 | var | ... | ... |
... | @@ -258,12 +258,12 @@ | ... | @@ -258,12 +258,12 @@ |
258 | 258 | ||
259 | this.tags = []; | 259 | this.tags = []; |
260 | 260 | ||
261 | //(pts:uint, dts:uint, dataAligned:Boolean):void | 261 | //(pts:uint):void |
262 | this.setNextTimeStamp = function(pts, dts, dataAligned) { | 262 | this.setTimeStampOffset = function(pts) { |
263 | // on the first invocation, capture the starting PTS value | ||
264 | pts_offset = pts; | 263 | pts_offset = pts; |
264 | }; | ||
265 | 265 | ||
266 | // on subsequent invocations, calculate the PTS based on the starting offset | 266 | //(pts:uint, dts:uint, dataAligned:Boolean):void |
267 | this.setNextTimeStamp = function(pts, dts, dataAligned) { | 267 | this.setNextTimeStamp = function(pts, dts, dataAligned) { |
268 | // We could end up with a DTS less than 0 here. We need to deal with that! | 268 | // We could end up with a DTS less than 0 here. We need to deal with that! |
269 | next_pts = pts - pts_offset; | 269 | next_pts = pts - pts_offset; |
... | @@ -275,9 +275,6 @@ | ... | @@ -275,9 +275,6 @@ |
275 | } | 275 | } |
276 | }; | 276 | }; |
277 | 277 | ||
278 | this.setNextTimeStamp(pts, dts, dataAligned); | ||
279 | }; | ||
280 | |||
281 | this.finishFrame = function() { | 278 | this.finishFrame = function() { |
282 | if (h264Frame) { | 279 | if (h264Frame) { |
283 | // Push SPS before EVERY IDR frame for seeking | 280 | // Push SPS before EVERY IDR frame for seeking | ... | ... |
... | @@ -19,7 +19,10 @@ | ... | @@ -19,7 +19,10 @@ |
19 | streamBuffer = new Uint8Array(MP2T_PACKET_LENGTH), | 19 | streamBuffer = new Uint8Array(MP2T_PACKET_LENGTH), |
20 | streamBufferByteCount = 0, | 20 | streamBufferByteCount = 0, |
21 | h264Stream = new H264Stream(), | 21 | h264Stream = new H264Stream(), |
22 | aacStream = new AacStream(); | 22 | aacStream = new AacStream(), |
23 | h264HasTimeStampOffset = false, | ||
24 | aacHasTimeStampOffset = false, | ||
25 | timeStampOffset; | ||
23 | 26 | ||
24 | // expose the stream metadata | 27 | // expose the stream metadata |
25 | self.stream = { | 28 | self.stream = { |
... | @@ -344,10 +347,24 @@ | ... | @@ -344,10 +347,24 @@ |
344 | } | 347 | } |
345 | 348 | ||
346 | if (pid === self.stream.programMapTable[STREAM_TYPES.h264]) { | 349 | if (pid === self.stream.programMapTable[STREAM_TYPES.h264]) { |
350 | if (!h264HasTimeStampOffset) { | ||
351 | h264HasTimeStampOffset = true; | ||
352 | if (timeStampOffset === undefined) { | ||
353 | timeStampOffset = pts; | ||
354 | } | ||
355 | h264Stream.setTimeStampOffset(timeStampOffset); | ||
356 | } | ||
347 | h264Stream.setNextTimeStamp(pts, | 357 | h264Stream.setNextTimeStamp(pts, |
348 | dts, | 358 | dts, |
349 | dataAlignmentIndicator); | 359 | dataAlignmentIndicator); |
350 | } else if (pid === self.stream.programMapTable[STREAM_TYPES.adts]) { | 360 | } else if (pid === self.stream.programMapTable[STREAM_TYPES.adts]) { |
361 | if (!aacHasTimeStampOffset) { | ||
362 | aacHasTimeStampOffset = true; | ||
363 | if (timeStampOffset === undefined) { | ||
364 | timeStampOffset = pts; | ||
365 | } | ||
366 | aacStream.setTimeStampOffset(timeStampOffset); | ||
367 | } | ||
351 | aacStream.setNextTimeStamp(pts, | 368 | aacStream.setNextTimeStamp(pts, |
352 | pesPacketSize, | 369 | pesPacketSize, |
353 | dataAlignmentIndicator); | 370 | dataAlignmentIndicator); | ... | ... |
... | @@ -70,6 +70,7 @@ test('starting PTS values can be negative', function() { | ... | @@ -70,6 +70,7 @@ test('starting PTS values can be negative', function() { |
70 | nalUnitTypes.access_unit_delimiter_rbsp | 70 | nalUnitTypes.access_unit_delimiter_rbsp |
71 | ]); | 71 | ]); |
72 | 72 | ||
73 | h264Stream.setTimeStampOffset(-100); | ||
73 | h264Stream.setNextTimeStamp(-100, -100, true); | 74 | h264Stream.setNextTimeStamp(-100, -100, true); |
74 | h264Stream.writeBytes(accessUnitDelimiter, 0, accessUnitDelimiter.byteLength); | 75 | h264Stream.writeBytes(accessUnitDelimiter, 0, accessUnitDelimiter.byteLength); |
75 | h264Stream.setNextTimeStamp(-99, -99, true); | 76 | h264Stream.setNextTimeStamp(-99, -99, true); | ... | ... |
-
Please register or sign in to post a comment