consisten one behind
This commit is contained in:
@@ -97,13 +97,13 @@ def receive_record_relay_and_detect(stream_url, output_path, relay_url,
|
||||
)
|
||||
|
||||
# Scene detection: CUDA decode (GPU) → select filter (CPU, lightweight)
|
||||
# → showinfo → MJPEG piped to stdout (avoids image2 muxer one-frame buffer)
|
||||
# → showinfo → MJPEG piped to stdout
|
||||
select_expr = f"gt(scene,{scene_threshold})"
|
||||
scene_stream = stream.filter("select", select_expr).filter("showinfo")
|
||||
scene_out = ffmpeg.output(
|
||||
scene_stream, "pipe:1",
|
||||
f="image2pipe", vcodec="mjpeg",
|
||||
vsync="vfr", flush_packets=1, **{"q:v": "2"},
|
||||
flush_packets=1, **{"q:v": "2", "fps_mode": "passthrough"},
|
||||
)
|
||||
|
||||
return ffmpeg.merge_outputs(file_out, relay_out, scene_out).global_args(*GLOBAL_ARGS)
|
||||
|
||||
@@ -10,10 +10,8 @@ Architecture:
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from queue import Queue, Empty
|
||||
from threading import Thread
|
||||
|
||||
from cht.config import (
|
||||
@@ -244,10 +242,9 @@ class StreamManager:
|
||||
- stderr: parses showinfo lines, queues pts_time values
|
||||
- stdout: reads JPEG frames from pipe, pairs with queued timestamps,
|
||||
writes files to disk, fires callbacks immediately
|
||||
|
||||
showinfo fires before the JPEG encoder, so timestamps are always
|
||||
queued before the corresponding JPEG data arrives on stdout.
|
||||
"""
|
||||
from queue import Queue, Empty
|
||||
import os
|
||||
ts_queue = Queue()
|
||||
|
||||
def _read_stderr():
|
||||
@@ -269,13 +266,10 @@ class StreamManager:
|
||||
buf = b""
|
||||
raw_fd = proc.stdout.fileno()
|
||||
while True:
|
||||
# os.read on the raw fd returns as soon as ANY data is available
|
||||
# (no Python buffered-IO blocking waiting to fill a buffer)
|
||||
chunk = os.read(raw_fd, 65536)
|
||||
if not chunk:
|
||||
break
|
||||
buf += chunk
|
||||
# Split JPEG frames by SOI (0xFFD8) and EOI (0xFFD9) markers
|
||||
while True:
|
||||
soi = buf.find(b"\xff\xd8")
|
||||
if soi < 0:
|
||||
@@ -283,12 +277,11 @@ class StreamManager:
|
||||
break
|
||||
eoi = buf.find(b"\xff\xd9", soi + 2)
|
||||
if eoi < 0:
|
||||
buf = buf[soi:] # keep from SOI, need more data
|
||||
buf = buf[soi:]
|
||||
break
|
||||
jpeg_data = buf[soi:eoi + 2]
|
||||
buf = buf[eoi + 2:]
|
||||
|
||||
# Get timestamp (showinfo fires before encode, so it's queued)
|
||||
try:
|
||||
pts_time = ts_queue.get(timeout=2.0)
|
||||
except Empty:
|
||||
|
||||
Reference in New Issue
Block a user