Watch for broken frames using JPEG end bytes, and log error
This commit is contained in:
parent
d2488c566a
commit
68380385cb
1 changed files with 17 additions and 0 deletions
|
|
@ -8,6 +8,7 @@ from typing import BinaryIO, List, NamedTuple, Optional, Tuple, Type, Union
|
||||||
|
|
||||||
from labthings import ClientEvent, StrictLock
|
from labthings import ClientEvent, StrictLock
|
||||||
|
|
||||||
|
JPEG_END_BYTES: bytes = b"\xff\xd9"
|
||||||
|
|
||||||
# Class to store a frames metadata
|
# Class to store a frames metadata
|
||||||
class TrackerFrame(NamedTuple):
|
class TrackerFrame(NamedTuple):
|
||||||
|
|
@ -42,6 +43,8 @@ class FrameStream(io.BytesIO):
|
||||||
# We use a ClientEvent so that each thread can call getvalue() independantly
|
# We use a ClientEvent so that each thread can call getvalue() independantly
|
||||||
self.new_frame: ClientEvent = ClientEvent()
|
self.new_frame: ClientEvent = ClientEvent()
|
||||||
|
|
||||||
|
self._bad_frame: bool = False
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.start_tracking()
|
self.start_tracking()
|
||||||
return super().__enter__()
|
return super().__enter__()
|
||||||
|
|
@ -79,6 +82,20 @@ class FrameStream(io.BytesIO):
|
||||||
3. Store the new frame image
|
3. Store the new frame image
|
||||||
4. Set the new_frame event
|
4. Set the new_frame event
|
||||||
"""
|
"""
|
||||||
|
# If we get a bad frame, and the last frame was good
|
||||||
|
if s[-2:] != JPEG_END_BYTES and not self._bad_frame:
|
||||||
|
# TODO: Handle this more cleverly. Automatically lower bitrate to compensate?
|
||||||
|
# Log error
|
||||||
|
logging.error(
|
||||||
|
"Incomplete frame data recieved. Camera bandwidth may have been exceeded. Consider lowing resolution, framerate, or target bitrate."
|
||||||
|
)
|
||||||
|
# Record that last frame was bad
|
||||||
|
self._bad_frame = True
|
||||||
|
# If the last frame was bad, but this frame was good
|
||||||
|
elif self._bad_frame and s[-2:] == JPEG_END_BYTES:
|
||||||
|
# Clear the bad frame record
|
||||||
|
self._bad_frame = False
|
||||||
|
# If we're tracking frame size
|
||||||
if self.tracking:
|
if self.tracking:
|
||||||
frame = TrackerFrame(size=len(s), time=time.time())
|
frame = TrackerFrame(size=len(s), time=time.time())
|
||||||
self.frames.append(frame)
|
self.frames.append(frame)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue