Allow only one packet with no dts in stream init (#41129)

* Allow only one packet with no dts in stream init

* Call finalize_stream() on exit
This commit is contained in:
uvjustin 2020-10-12 00:52:51 +08:00 committed by GitHub
parent c7bbba9d48
commit 6c18feb4ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -103,6 +103,7 @@ def _stream_worker_internal(hass, stream, quit_event):
def peek_first_pts():
nonlocal first_pts, audio_stream
missing_dts = False
def empty_stream_dict():
return {
@ -117,10 +118,13 @@ def _stream_worker_internal(hass, stream, quit_event):
while first_packet[video_stream] is None:
packet = next(container.demux())
if (
packet.stream == video_stream
and packet.is_keyframe
and packet.dts is not None
):
packet.dts is None
): # Allow single packet with no dts, raise error on second
if missing_dts:
raise av.AVError
missing_dts = True
continue
if packet.stream == video_stream and packet.is_keyframe:
first_packet[video_stream] = packet
initial_packets.append(packet)
# Get first_pts from subsequent frame to first keyframe
@ -128,8 +132,13 @@ def _stream_worker_internal(hass, stream, quit_event):
[pts is None for pts in {**first_packet, **first_pts}.values()]
) and (len(initial_packets) < PACKETS_TO_WAIT_FOR_AUDIO):
packet = next(container.demux((video_stream, audio_stream)))
if packet.dts is None:
continue # Discard packets with no dts
if (
packet.dts is None
): # Allow single packet with no dts, raise error on second
if missing_dts:
raise av.AVError
missing_dts = True
continue
if (
first_packet[packet.stream] is None
): # actually video already found above so only for audio
@ -158,6 +167,7 @@ def _stream_worker_internal(hass, stream, quit_event):
_LOGGER.error(
"Error demuxing stream while finding first packet: %s", str(ex)
)
finalize_stream()
return False
return True
@ -203,7 +213,7 @@ def _stream_worker_internal(hass, stream, quit_event):
def finalize_stream():
if not stream.keepalive:
# End of stream, clear listeners and stop thread
for fmt, _ in outputs.items():
for fmt in stream.outputs.keys():
hass.loop.call_soon_threadsafe(stream.outputs[fmt].put, None)
if not peek_first_pts():