mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-07 11:45:24 +03:00
Fix durations and decrase keyframe interval to ensure smooth scrubbing
This commit is contained in:
parent
186403cd3e
commit
637e118018
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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]]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user