Stream Timestamp Fixes (#22912)

* reset timestamps for streams that do not do so when first requested

* update inline comments to be more descriptive
This commit is contained in:
Jason Hunter 2019-04-09 02:24:51 -04:00 committed by Paulus Schoutsen
parent 590eead128
commit 43487aa0d6
2 changed files with 23 additions and 3 deletions

View File

@ -85,7 +85,7 @@ class M3U8Renderer:
for sequence in segments:
segment = track.get_segment(sequence)
playlist.extend([
"#EXTINF:{:.04},".format(float(segment.duration)),
"#EXTINF:{:.04f},".format(float(segment.duration)),
"./segment/{}.ts".format(segment.sequence),
])

View File

@ -55,10 +55,16 @@ def stream_worker(hass, stream, quit_event):
audio_frame = generate_audio_frame()
outputs = {}
first_packet = True
# Holds the buffers for each stream provider
outputs = {}
# Keep track of the number of segments we've processed
sequence = 1
# Holds the generated silence that needs to be muxed into the output
audio_packets = {}
# The presentation timestamp of the first video packet we recieve
first_pts = 0
# The decoder timestamp of the latest packet we processed
last_dts = None
while not quit_event.is_set():
@ -82,10 +88,18 @@ def stream_worker(hass, stream, quit_event):
continue
last_dts = packet.dts
# Reset timestamps from a 0 time base for this stream
packet.dts -= first_pts
packet.pts -= first_pts
# Reset segment on every keyframe
if packet.is_keyframe:
# Save segment to outputs
# Calculate the segment duration by multiplying the presentation
# timestamp by the time base, which gets us total seconds.
# By then dividing by the seqence, we can calculate how long
# each segment is, assuming the stream starts from 0.
segment_duration = (packet.pts * packet.time_base) / sequence
# Save segment to outputs
for fmt, buffer in outputs.items():
buffer.output.close()
del audio_packets[buffer.astream]
@ -112,6 +126,12 @@ def stream_worker(hass, stream, quit_event):
# First video packet tends to have a weird dts/pts
if first_packet:
# If we are attaching to a live stream that does not reset
# timestamps for us, we need to do it ourselves by recording
# the first presentation timestamp and subtracting it from
# subsequent packets we recieve.
if (packet.pts * packet.time_base) > 1:
first_pts = packet.pts
packet.dts = 0
packet.pts = 0
first_packet = False