Fix durations and decrase keyframe interval to ensure smooth scrubbing

This commit is contained in:
Nick Mowen 2023-11-29 07:53:58 -07:00
parent 186403cd3e
commit 637e118018
2 changed files with 23 additions and 26 deletions

View File

@ -27,9 +27,8 @@ logger = logging.getLogger(__name__)
FOLDER_PREVIEW_FRAMES = "preview_frames" FOLDER_PREVIEW_FRAMES = "preview_frames"
PREVIEW_OUTPUT_FPS = 1 PREVIEW_OUTPUT_FPS = 1
PREVIEW_SEGMENT_DURATION = 3600 # one hour PREVIEW_SEGMENT_DURATION = 3600 # one hour
PREVIEW_KEYFRAME_INTERVAL = ( # important to have lower keyframe to maintain scrubbing performance
PREVIEW_SEGMENT_DURATION / 10 PREVIEW_KEYFRAME_INTERVAL = 60
) # maximum of 8 keyframes per segment
def get_cache_image_name(camera: str, frame_time: float) -> str: def get_cache_image_name(camera: str, frame_time: float) -> str:
@ -50,7 +49,7 @@ class FFMpegConverter(threading.Thread):
inter_process_queue: mp.Queue, inter_process_queue: mp.Queue,
): ):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.name = f"{config.name}_output_converter" self.name = f"{config.name}_preview_converter"
self.camera = config.name self.camera = config.name
self.frame_times = frame_times self.frame_times = frame_times
self.inter_process_queue = inter_process_queue self.inter_process_queue = inter_process_queue
@ -69,17 +68,22 @@ class FFMpegConverter(threading.Thread):
def run(self) -> None: def run(self) -> None:
# generate input list # generate input list
last = self.frame_times[0] item_count = len(self.frame_times)
playlist = [] playlist = []
for t in self.frame_times: for t_idx in range(0, item_count):
playlist.append(f"file '{get_cache_image_name(self.camera, t)}'") if t_idx == item_count - 1:
playlist.append(f"duration {t - last}") # last frame does not get a duration
last = t
# last frame must be included again with no duration
playlist.append( playlist.append(
f"file '{get_cache_image_name(self.camera, self.frame_times[-1])}'" f"file '{get_cache_image_name(self.camera, self.frame_times[t_idx])}'"
)
continue
playlist.append(
f"file '{get_cache_image_name(self.camera, self.frame_times[t_idx])}'"
)
playlist.append(
f"duration {self.frame_times[t_idx + 1] - self.frame_times[t_idx]}"
) )
p = sp.run( p = sp.run(
@ -98,7 +102,7 @@ class FFMpegConverter(threading.Thread):
( (
INSERT_PREVIEW, INSERT_PREVIEW,
{ {
Previews.id: f"{end}-{start}", Previews.id: f"{self.camera}_{end}",
Previews.camera: self.camera, Previews.camera: self.camera,
Previews.path: self.path, Previews.path: self.path,
Previews.start_time: start, Previews.start_time: start,
@ -176,8 +180,7 @@ class PreviewRecorder:
self.last_output_time = frame_time self.last_output_time = frame_time
return True return True
# TODO think of real motion box logic to use if len(motion_boxes) > 0:
if len(motion_boxes) % 2 == 1:
self.last_output_time = frame_time self.last_output_time = frame_time
return True return True

View File

@ -312,17 +312,14 @@ def yuv_crop_and_resize(frame, region, height=None):
# copy u2 # copy u2
yuv_cropped_frame[ yuv_cropped_frame[
size + uv_channel_y_offset : size + uv_channel_y_offset + uv_crop_height, size + uv_channel_y_offset : size + uv_channel_y_offset + uv_crop_height,
size // 2 size // 2 + uv_channel_x_offset : size // 2
+ uv_channel_x_offset : size // 2
+ uv_channel_x_offset + uv_channel_x_offset
+ uv_crop_width, + uv_crop_width,
] = frame[u2[1] : u2[3], u2[0] : u2[2]] ] = frame[u2[1] : u2[3], u2[0] : u2[2]]
# copy v1 # copy v1
yuv_cropped_frame[ yuv_cropped_frame[
size size + size // 4 + uv_channel_y_offset : size
+ size // 4
+ uv_channel_y_offset : size
+ size // 4 + size // 4
+ uv_channel_y_offset + uv_channel_y_offset
+ uv_crop_height, + uv_crop_height,
@ -331,14 +328,11 @@ def yuv_crop_and_resize(frame, region, height=None):
# copy v2 # copy v2
yuv_cropped_frame[ yuv_cropped_frame[
size size + size // 4 + uv_channel_y_offset : size
+ size // 4
+ uv_channel_y_offset : size
+ size // 4 + size // 4
+ uv_channel_y_offset + uv_channel_y_offset
+ uv_crop_height, + uv_crop_height,
size // 2 size // 2 + uv_channel_x_offset : size // 2
+ uv_channel_x_offset : size // 2
+ uv_channel_x_offset + uv_channel_x_offset
+ uv_crop_width, + uv_crop_width,
] = frame[v2[1] : v2[3], v2[0] : v2[2]] ] = frame[v2[1] : v2[3], v2[0] : v2[2]]