reactor-runtime 2.7.5__tar.gz → 2.7.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/PKG-INFO +1 -1
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/pyproject.toml +1 -1
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/internal/output_buffer.py +73 -41
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/chunk_encoder.py +88 -11
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/config.py +18 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/markers.py +10 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/session_recorder.py +14 -2
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtime_api.py +10 -13
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/headless/headless_runtime.py +35 -17
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime.egg-info/PKG-INFO +1 -1
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/README.md +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/setup.cfg +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/api/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/config.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/experiment/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/experiment/session.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/defaults.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/driver/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/driver/pipeline_executor.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/driver/step_result.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/connected.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/event.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/messages.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/upload.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/internal/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/internal/input_buffer.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/internal/reactor_core.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/decorators.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/handlers.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/reactor_model.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/pipeline/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/pipeline/idle.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/pipeline/input_state.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/pipeline/reactor_pipeline.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/descriptors.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/input.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/output.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/upload.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/model_state.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/base.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/file.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/otlp.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/helpers.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/nvml_sampler.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/plotting/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/plotting/plot_profiling.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/profiler.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/singleton.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/torch_chunk_profiler.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/chunk_uploader.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/sinks.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/track_resolver.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/headless/config.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/headless/input_feeder.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/http/config.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/http/http_runtime.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/http/types.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/schema.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/schema_validator.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/__main__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/commands/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/commands/run.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/commands/schema.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/main.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/utils/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/utils/config.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/utils/runtime.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/audio_track.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/client.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/frame_conversion.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/ice_connection.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/video_track.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/config.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/events.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/client.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/av1.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/base.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/factory.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/h264.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/h265.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/opus.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/vp8.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/decoders/vp9.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/av1.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/base.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/factory.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/h264.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/h265.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/opus.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/vp8.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/encoders/vp9.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/gst.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/gst_helpers.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/probes/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/probes/fps_probe.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/receiver/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/receiver/audio.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/receiver/base.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/receiver/video.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sdp/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sdp/bundle.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sdp/codec.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sdp/extmap.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sdp/ice.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sender/__init__.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sender/audio.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sender/base.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sender/video.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/settings.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/signals.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/ice_uris.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/interface.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/media.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/types.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/launch.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/loader.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/log.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/messages.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/paths.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/ports.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/utils/typing.py +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime.egg-info/SOURCES.txt +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime.egg-info/dependency_links.txt +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime.egg-info/requires.txt +0 -0
- {reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime.egg-info/top_level.txt +0 -0
|
@@ -102,6 +102,18 @@ def split_batch(bundle: MediaBundle) -> List[MediaBundle]:
|
|
|
102
102
|
return result
|
|
103
103
|
|
|
104
104
|
|
|
105
|
+
class _FlushMarker:
|
|
106
|
+
"""Sentinel placed in :class:`OutputBuffer`'s queue by :meth:`flush`.
|
|
107
|
+
|
|
108
|
+
Consumed by the emission thread, which resets ``_last_emitted`` and
|
|
109
|
+
dispatches a fresh black bundle with ``is_fresh_black=True``. Doing
|
|
110
|
+
the reset in-thread keeps it atomic with the per-tick state read.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
_FLUSH_MARKER: _FlushMarker = _FlushMarker()
|
|
115
|
+
|
|
116
|
+
|
|
105
117
|
class OutputBuffer:
|
|
106
118
|
"""Rate-controlled emission buffer.
|
|
107
119
|
|
|
@@ -124,10 +136,12 @@ class OutputBuffer:
|
|
|
124
136
|
# Ordered list of per-tick observers. Callbacks fire in
|
|
125
137
|
# registration order on every emission tick; an exception in
|
|
126
138
|
# one callback is logged and does not block the others.
|
|
127
|
-
self._callbacks: List[Callable[[MediaBundle, bool], None]] = []
|
|
139
|
+
self._callbacks: List[Callable[[MediaBundle, bool, bool], None]] = []
|
|
128
140
|
self._callbacks_lock: threading.Lock = threading.Lock()
|
|
129
141
|
|
|
130
|
-
|
|
142
|
+
# Holds MediaBundle plus the _FlushMarker sentinel; the
|
|
143
|
+
# emission loop discriminates by isinstance.
|
|
144
|
+
self._q: queue.Queue[object] = queue.Queue(maxsize=queue_depth)
|
|
131
145
|
|
|
132
146
|
# FPS control — store both rate and period to avoid 1/fps on every tick
|
|
133
147
|
self._fixed_fps: float = 0.0
|
|
@@ -150,29 +164,18 @@ class OutputBuffer:
|
|
|
150
164
|
# Callbacks
|
|
151
165
|
# ------------------------------------------------------------------
|
|
152
166
|
|
|
153
|
-
def add_callback(self, fn: Callable[[MediaBundle, bool], None]) -> None:
|
|
154
|
-
"""Register a per-tick callback
|
|
167
|
+
def add_callback(self, fn: Callable[[MediaBundle, bool, bool], None]) -> None:
|
|
168
|
+
"""Register a per-tick callback ``(bundle, duplicate, is_fresh_black)``.
|
|
155
169
|
|
|
156
|
-
Idempotent
|
|
157
|
-
|
|
158
|
-
:meth:`remove_callback` which has always been a no-op on
|
|
159
|
-
already-unregistered functions — callers shouldn't have to
|
|
160
|
-
track registration state.
|
|
161
|
-
|
|
162
|
-
The callback receives ``(bundle, duplicate)`` on every emission
|
|
163
|
-
tick. Callbacks fire in registration order and are isolated
|
|
164
|
-
from each other: an exception raised by one is logged and the
|
|
165
|
-
remaining callbacks still fire.
|
|
170
|
+
Idempotent — re-registering the same ``fn`` is a no-op.
|
|
171
|
+
Callbacks fire in registration order with exceptions isolated.
|
|
166
172
|
"""
|
|
167
173
|
with self._callbacks_lock:
|
|
168
174
|
if fn not in self._callbacks:
|
|
169
175
|
self._callbacks.append(fn)
|
|
170
176
|
|
|
171
|
-
def remove_callback(self, fn: Callable[[MediaBundle, bool], None]) -> None:
|
|
172
|
-
"""Deregister a previously added callback.
|
|
173
|
-
|
|
174
|
-
No-op if *fn* was never registered.
|
|
175
|
-
"""
|
|
177
|
+
def remove_callback(self, fn: Callable[[MediaBundle, bool, bool], None]) -> None:
|
|
178
|
+
"""Deregister a previously added callback (no-op if not registered)."""
|
|
176
179
|
with self._callbacks_lock:
|
|
177
180
|
try:
|
|
178
181
|
self._callbacks.remove(fn)
|
|
@@ -288,27 +291,30 @@ class OutputBuffer:
|
|
|
288
291
|
# Stage 3: Emission loop
|
|
289
292
|
# ------------------------------------------------------------------
|
|
290
293
|
|
|
291
|
-
def _dispatch(
|
|
294
|
+
def _dispatch(
|
|
295
|
+
self,
|
|
296
|
+
bundle: MediaBundle,
|
|
297
|
+
duplicate: bool,
|
|
298
|
+
*,
|
|
299
|
+
is_fresh_black: bool = False,
|
|
300
|
+
) -> None:
|
|
292
301
|
"""Fire every registered callback in order with error isolation.
|
|
293
302
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
303
|
+
Callbacks receive ``(bundle, duplicate, is_fresh_black)``.
|
|
304
|
+
``is_fresh_black`` is ``True`` only on the synthesised black
|
|
305
|
+
the sentinel path emits at session boundaries; callbacks
|
|
306
|
+
choose how to interpret that separately from ``duplicate``.
|
|
307
|
+
Exceptions in one callback are logged and don't block the
|
|
308
|
+
rest.
|
|
298
309
|
"""
|
|
299
310
|
with self._callbacks_lock:
|
|
300
311
|
callbacks = list(self._callbacks)
|
|
301
312
|
for fn in callbacks:
|
|
302
313
|
try:
|
|
303
|
-
fn(bundle, duplicate)
|
|
314
|
+
fn(bundle, duplicate, is_fresh_black)
|
|
304
315
|
except Exception as ex:
|
|
305
|
-
#
|
|
306
|
-
#
|
|
307
|
-
# structured fields so log queries on ``exc_type`` /
|
|
308
|
-
# ``exc_msg`` / ``callback`` work without traceback
|
|
309
|
-
# parsing. Without these explicit fields a silent
|
|
310
|
-
# malfunction in a downstream callback looks like
|
|
311
|
-
# "feature X didn't fire" with no obvious cause.
|
|
316
|
+
# Structured fields so log queries on exc_type /
|
|
317
|
+
# exc_msg / callback work without traceback parsing.
|
|
312
318
|
logger.exception(
|
|
313
319
|
"OutputBuffer callback raised; continuing with remaining callbacks",
|
|
314
320
|
callback=repr(fn),
|
|
@@ -322,13 +328,31 @@ class OutputBuffer:
|
|
|
322
328
|
while not self._emission_stop.is_set():
|
|
323
329
|
interval = self._interval
|
|
324
330
|
|
|
325
|
-
|
|
331
|
+
item: object
|
|
326
332
|
try:
|
|
327
|
-
|
|
333
|
+
item = self._q.get_nowait()
|
|
328
334
|
except queue.Empty:
|
|
329
|
-
|
|
335
|
+
item = None
|
|
330
336
|
|
|
331
|
-
|
|
337
|
+
bundle: Optional[MediaBundle] = None
|
|
338
|
+
sentinel_consumed = False
|
|
339
|
+
if isinstance(item, _FlushMarker):
|
|
340
|
+
self._last_emitted = None
|
|
341
|
+
sentinel_consumed = True
|
|
342
|
+
elif isinstance(item, MediaBundle):
|
|
343
|
+
bundle = item
|
|
344
|
+
|
|
345
|
+
if sentinel_consumed:
|
|
346
|
+
# Session-boundary black: tagged so the wire
|
|
347
|
+
# forwards it (otherwise the client would stay
|
|
348
|
+
# frozen on the previous frame), the recorder
|
|
349
|
+
# ignores it.
|
|
350
|
+
self._dispatch(
|
|
351
|
+
self._create_black_bundle(),
|
|
352
|
+
True,
|
|
353
|
+
is_fresh_black=True,
|
|
354
|
+
)
|
|
355
|
+
elif bundle is not None:
|
|
332
356
|
vtracks = bundle.get_tracks_by_kind(TrackKind.VIDEO)
|
|
333
357
|
if vtracks:
|
|
334
358
|
vd = vtracks[0].data
|
|
@@ -464,11 +488,19 @@ class OutputBuffer:
|
|
|
464
488
|
self._drain_queue()
|
|
465
489
|
|
|
466
490
|
def flush(self) -> None:
|
|
467
|
-
"""
|
|
491
|
+
"""Drop pending bundles and request a session-boundary reset.
|
|
492
|
+
|
|
493
|
+
The emission thread performs the actual reset of
|
|
494
|
+
``_last_emitted`` when it dequeues the sentinel. Then the
|
|
495
|
+
next tick emits a fresh black bundle tagged ``is_fresh_black``
|
|
496
|
+
— forwarded by the wire, ignored by the recorder.
|
|
497
|
+
"""
|
|
468
498
|
self._drain_queue()
|
|
469
|
-
self._last_emitted = None
|
|
470
|
-
black = self._create_black_bundle()
|
|
471
499
|
try:
|
|
472
|
-
self._q.put_nowait(
|
|
500
|
+
self._q.put_nowait(_FLUSH_MARKER)
|
|
473
501
|
except queue.Full:
|
|
474
|
-
|
|
502
|
+
# Same thread as submit(), so unreachable in practice.
|
|
503
|
+
logger.warning(
|
|
504
|
+
"OutputBuffer.flush: queue full immediately after drain; "
|
|
505
|
+
"reset sentinel dropped"
|
|
506
|
+
)
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/chunk_encoder.py
RENAMED
|
@@ -61,6 +61,31 @@ def _build_argv(
|
|
|
61
61
|
is fed at exactly ``sample_rate * dt`` samples per video frame
|
|
62
62
|
(see ``SessionRecorder._next_audio_chunk``) so its byte-derived
|
|
63
63
|
DTS still tracks wall-clock 1:1 with video's PTS.
|
|
64
|
+
|
|
65
|
+
Social-media compatibility (REA-2482):
|
|
66
|
+
|
|
67
|
+
* ``-pix_fmt yuv420p`` + ``-profile:v main`` on the *output*. With
|
|
68
|
+
rgb24 input and no output pix_fmt, libx264 auto-selects yuv444p
|
|
69
|
+
(Hi444PP profile), which macOS VideoToolbox cannot decode and
|
|
70
|
+
every major social uploader rejects. Forcing yuv420p+Main is
|
|
71
|
+
the universally-compatible H.264 sub-profile.
|
|
72
|
+
* ``-vf setpts=PTS-STARTPTS`` re-anchors the wallclock-stamped
|
|
73
|
+
video PTS to session-relative. Without it every segment's
|
|
74
|
+
``tfdt baseMediaDecodeTime`` carries the Unix-epoch-derived
|
|
75
|
+
value (~1.78e9), which some players treat as the playback
|
|
76
|
+
start time and some uploaders refuse outright. Subtracting
|
|
77
|
+
``STARTPTS`` preserves *relative* frame spacing (so the
|
|
78
|
+
dynamic-FPS comment above still holds) while shifting chunk 0
|
|
79
|
+
to PTS=0. Note: mid-session clips still carry a non-zero
|
|
80
|
+
``tfdt`` (e.g. 32 s in for a clip starting at session t=32) —
|
|
81
|
+
that's the SDK's concern (REA-2558), not ours.
|
|
82
|
+
* Silent AAC stub for video-only models: ``-f lavfi -i anullsrc``
|
|
83
|
+
synthesises an infinite silent mono 48 kHz stream inside
|
|
84
|
+
libavfilter — no extra subprocess, no Python audio thread, no
|
|
85
|
+
pipe. Paired with ``-shortest`` so the encoder terminates on
|
|
86
|
+
the video pipe's EOF. Required by Instagram and broadens
|
|
87
|
+
compatibility on every other platform; encoding silence costs
|
|
88
|
+
<1% of a core and ~16 kbps × duration on disk.
|
|
64
89
|
"""
|
|
65
90
|
# ``-probesize 32 -analyzeduration 0`` on every input: rawvideo /
|
|
66
91
|
# s16le are fully described by ``-f`` + format flags, so ffmpeg's
|
|
@@ -117,16 +142,61 @@ def _build_argv(
|
|
|
117
142
|
"1024",
|
|
118
143
|
"-i",
|
|
119
144
|
f"pipe:{audio_read_fd}",
|
|
120
|
-
"-map",
|
|
121
|
-
"0:v",
|
|
122
|
-
"-map",
|
|
123
|
-
"1:a",
|
|
124
145
|
]
|
|
146
|
+
else:
|
|
147
|
+
# Synthetic silent audio (REA-2482). ``lavfi anullsrc`` is a
|
|
148
|
+
# virtual generator inside libavfilter — no extra subprocess
|
|
149
|
+
# spawned, no audio pipe opened on our side.
|
|
150
|
+
#
|
|
151
|
+
# ``-re`` paces the lavfi input at native rate (one
|
|
152
|
+
# wallclock-second of silence per real second). Without it,
|
|
153
|
+
# lavfi is an unpaced infinite generator: the input thread
|
|
154
|
+
# produces silent samples as fast as ffmpeg's filter graph
|
|
155
|
+
# asks, racing ahead of the wallclock-stamped video on idle
|
|
156
|
+
# sessions and risking thread-queue exhaustion / stalled
|
|
157
|
+
# teardown. With ``-re``, the silent stream tracks wallclock
|
|
158
|
+
# the same way the real pipe-fed audio path does (which
|
|
159
|
+
# writes exactly ``sample_rate * dt`` samples per video frame
|
|
160
|
+
# in ``SessionRecorder._feed_loop``).
|
|
161
|
+
#
|
|
162
|
+
# We pair this with ``-shortest`` below so the encoder
|
|
163
|
+
# terminates with the video pipe's EOF (anullsrc is infinite
|
|
164
|
+
# by itself).
|
|
165
|
+
argv += [
|
|
166
|
+
"-re",
|
|
167
|
+
"-f",
|
|
168
|
+
"lavfi",
|
|
169
|
+
"-i",
|
|
170
|
+
"anullsrc=cl=mono:r=48000",
|
|
171
|
+
]
|
|
172
|
+
# Explicit stream mappings: now that there is always a second
|
|
173
|
+
# input (either the real audio pipe or the lavfi silent stub),
|
|
174
|
+
# both branches funnel through the same -map pair.
|
|
175
|
+
argv += [
|
|
176
|
+
"-map",
|
|
177
|
+
"0:v",
|
|
178
|
+
"-map",
|
|
179
|
+
"1:a",
|
|
180
|
+
]
|
|
125
181
|
# video encoder
|
|
126
182
|
vcodec = "libx264" if config.video.codec == "h264" else "libx265"
|
|
127
183
|
argv += [
|
|
128
184
|
"-c:v",
|
|
129
185
|
vcodec,
|
|
186
|
+
# Social-media-compat output format (see docstring). The first
|
|
187
|
+
# -pix_fmt earlier in argv is the *input* (rgb24); this second
|
|
188
|
+
# -pix_fmt applies to the encoder output because it sits after
|
|
189
|
+
# all -i flags.
|
|
190
|
+
"-pix_fmt",
|
|
191
|
+
"yuv420p",
|
|
192
|
+
"-profile:v",
|
|
193
|
+
"main",
|
|
194
|
+
# Re-anchor wallclock-stamped PTS to session-relative; see
|
|
195
|
+
# docstring. Single arithmetic op per frame inside the
|
|
196
|
+
# existing filter graph — no extra encode, no decode (input
|
|
197
|
+
# is rawvideo).
|
|
198
|
+
"-vf",
|
|
199
|
+
"setpts=PTS-STARTPTS",
|
|
130
200
|
"-preset",
|
|
131
201
|
config.video.preset,
|
|
132
202
|
"-crf",
|
|
@@ -141,13 +211,20 @@ def _build_argv(
|
|
|
141
211
|
"-force_key_frames",
|
|
142
212
|
f"expr:gte(t,n_forced*{config.chunk_seconds})",
|
|
143
213
|
]
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
214
|
+
# Audio encoder runs unconditionally now: real audio (when
|
|
215
|
+
# has_audio=True) or the lavfi silent stub (when False) — either
|
|
216
|
+
# way we want an AAC track in every output segment.
|
|
217
|
+
argv += [
|
|
218
|
+
"-c:a",
|
|
219
|
+
config.audio.codec,
|
|
220
|
+
"-b:a",
|
|
221
|
+
f"{config.audio.bitrate_kbps}k",
|
|
222
|
+
]
|
|
223
|
+
if not has_audio:
|
|
224
|
+
# ``lavfi anullsrc`` produces samples forever; without
|
|
225
|
+
# -shortest the encoder would keep writing silent audio
|
|
226
|
+
# frames after the video pipe EOFs, never terminating.
|
|
227
|
+
argv += ["-shortest"]
|
|
151
228
|
# HLS+fMP4 muxer (was ``-f dash``: dash's segment-rename trips
|
|
152
229
|
# ENOENT on macOS, killing the encoder ~10s in). Same byte-level
|
|
153
230
|
# output, more robust segment-close, 0-indexed by default — which
|
|
@@ -96,6 +96,24 @@ class RecordingConfig:
|
|
|
96
96
|
# that frame. Clip requests before any real frame fail with
|
|
97
97
|
# ``no media generated yet``. Set to ``False`` to record from
|
|
98
98
|
# session arm time and include the leading pre-roll in clips.
|
|
99
|
+
#
|
|
100
|
+
# **Timeline note (REA-2482).** The encoder applies
|
|
101
|
+
# ``setpts=PTS-STARTPTS`` on the video output to keep segment PTS
|
|
102
|
+
# session-relative rather than Unix-epoch-relative. That filter
|
|
103
|
+
# zeroes media time at the *first packet fed* to ffmpeg. In the
|
|
104
|
+
# default ``skip_leading_black=True`` mode, that is also where
|
|
105
|
+
# :class:`~reactor_runtime.recording.markers.MarkerBookkeeper`
|
|
106
|
+
# anchors its timeline (via ``mark_first_real_frame``), so markers
|
|
107
|
+
# and media bytes share the same origin and clip ranges resolve
|
|
108
|
+
# exactly. In the legacy ``skip_leading_black=False`` mode the
|
|
109
|
+
# marker bookkeeper keeps its origin at recorder arm time
|
|
110
|
+
# (``session_start``), so the two timelines diverge by however
|
|
111
|
+
# long the recorder waited for the first emission tick — usually
|
|
112
|
+
# one frame interval (<33 ms) but worst-case longer if the
|
|
113
|
+
# OutputBuffer hasn't started emitting yet at recorder arm. Clips
|
|
114
|
+
# served from that early window cover slightly *later* content
|
|
115
|
+
# than their marker range advertises; the clip length itself is
|
|
116
|
+
# unchanged.
|
|
99
117
|
skip_leading_black: bool = True
|
|
100
118
|
video_track: Optional[str] = None
|
|
101
119
|
audio_track: Optional[str] = None
|
|
@@ -5,6 +5,16 @@ Markers are wall-clock seconds aligned with ffmpeg's
|
|
|
5
5
|
``-use_wallclock_as_timestamps`` input. When ``anchor_at_first_frame``
|
|
6
6
|
is set (``RecordingConfig.skip_leading_black``), ``t=0`` is the first
|
|
7
7
|
real frame fed to the encoder, not recorder arm time.
|
|
8
|
+
|
|
9
|
+
The encoder additionally applies ``setpts=PTS-STARTPTS`` on the video
|
|
10
|
+
output (REA-2482), which zeroes media PTS at the *first packet fed* to
|
|
11
|
+
ffmpeg. With ``anchor_at_first_frame=True`` that's the same instant
|
|
12
|
+
the bookkeeper anchors on, so markers and media share an origin. With
|
|
13
|
+
``anchor_at_first_frame=False`` the bookkeeper's origin stays at
|
|
14
|
+
recorder arm time while the media origin slips to the first emission
|
|
15
|
+
tick; the gap is typically a single frame interval but can be longer
|
|
16
|
+
if the OutputBuffer hadn't started emitting yet at arm time. See
|
|
17
|
+
``RecordingConfig.skip_leading_black`` for the user-facing contract.
|
|
8
18
|
"""
|
|
9
19
|
|
|
10
20
|
from __future__ import annotations
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/session_recorder.py
RENAMED
|
@@ -250,10 +250,22 @@ class SessionRecorder:
|
|
|
250
250
|
# OutputBuffer integration
|
|
251
251
|
# ------------------------------------------------------------------
|
|
252
252
|
|
|
253
|
-
def _on_bundle_sync(
|
|
254
|
-
|
|
253
|
+
def _on_bundle_sync(
|
|
254
|
+
self,
|
|
255
|
+
bundle: MediaBundle,
|
|
256
|
+
duplicate: bool,
|
|
257
|
+
is_fresh_black: bool = False,
|
|
258
|
+
) -> None:
|
|
259
|
+
"""Enqueue a bundle for the feed worker; non-blocking.
|
|
260
|
+
|
|
261
|
+
Session-boundary synthesised black (``is_fresh_black``) is not
|
|
262
|
+
real model output and is invisible to the recording timeline:
|
|
263
|
+
no feed-queue write, no ``mark_first_real_frame`` consideration.
|
|
264
|
+
"""
|
|
255
265
|
if self._disabled or not self._started:
|
|
256
266
|
return
|
|
267
|
+
if is_fresh_black:
|
|
268
|
+
return
|
|
257
269
|
now = time.monotonic()
|
|
258
270
|
if duplicate:
|
|
259
271
|
if self._config.skip_leading_black and not self._markers.recording_started:
|
|
@@ -350,22 +350,19 @@ class Runtime(ModelStateMachine, ABC):
|
|
|
350
350
|
logger.warning("Failed to send app message", error=e)
|
|
351
351
|
|
|
352
352
|
def _send_out_app_bundle_sync(
|
|
353
|
-
self,
|
|
353
|
+
self,
|
|
354
|
+
media_bundle: MediaBundle,
|
|
355
|
+
duplicate: bool,
|
|
356
|
+
is_fresh_black: bool = False,
|
|
354
357
|
) -> None:
|
|
355
|
-
"""
|
|
356
|
-
|
|
357
|
-
Silently fails if the event loop is closed (expected during shutdown).
|
|
358
|
-
|
|
359
|
-
When *duplicate* is ``True`` the bundle is a re-emission of the
|
|
360
|
-
last frame (queue was empty, video-only). We skip forwarding
|
|
361
|
-
entirely: the video track already serves the last pushed frame,
|
|
362
|
-
and pushing the same frame again only wastes event-loop time.
|
|
358
|
+
"""OutputBuffer callback — forward real frames + session-boundary black.
|
|
363
359
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
360
|
+
Drops keepalive duplicates (the wire track already shows that
|
|
361
|
+
frame) but forwards ``is_fresh_black`` bundles so the client
|
|
362
|
+
transitions off the previous session's last frame on flush.
|
|
363
|
+
Silently fails if the event loop is closed (shutdown).
|
|
367
364
|
"""
|
|
368
|
-
if duplicate:
|
|
365
|
+
if duplicate and not is_fresh_black:
|
|
369
366
|
return
|
|
370
367
|
if self.loop.is_closed():
|
|
371
368
|
return
|
|
@@ -70,19 +70,26 @@ class HeadlessRuntime(Runtime):
|
|
|
70
70
|
# Runtime API implementation - MODEL -> CLIENT (stdout)
|
|
71
71
|
# ===============================
|
|
72
72
|
|
|
73
|
-
def _send_out_app_bundle_sync(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
def _send_out_app_bundle_sync(
|
|
74
|
+
self,
|
|
75
|
+
media_bundle,
|
|
76
|
+
duplicate: bool,
|
|
77
|
+
is_fresh_black: bool = False,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""Forward every bundle to :meth:`send_out_app_bundle`.
|
|
80
|
+
|
|
81
|
+
Unlike the base class, headless does not drop duplicates here
|
|
82
|
+
— the async path counts them for the ``ignore_duplicates``
|
|
83
|
+
feature. Silently fails if the event loop is closed.
|
|
80
84
|
"""
|
|
81
85
|
if self.loop.is_closed():
|
|
82
86
|
return
|
|
83
87
|
try:
|
|
84
88
|
asyncio.run_coroutine_threadsafe(
|
|
85
|
-
self.send_out_app_bundle(
|
|
89
|
+
self.send_out_app_bundle(
|
|
90
|
+
media_bundle, duplicate, is_fresh_black=is_fresh_black
|
|
91
|
+
),
|
|
92
|
+
self.loop,
|
|
86
93
|
)
|
|
87
94
|
except RuntimeError:
|
|
88
95
|
pass
|
|
@@ -105,19 +112,30 @@ class HeadlessRuntime(Runtime):
|
|
|
105
112
|
output = json.dumps(data, indent=2)
|
|
106
113
|
print(f"\n[RUNTIME] {output}", flush=True)
|
|
107
114
|
|
|
108
|
-
async def send_out_app_bundle(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
async def send_out_app_bundle(
|
|
116
|
+
self,
|
|
117
|
+
media_bundle,
|
|
118
|
+
duplicate: bool,
|
|
119
|
+
*,
|
|
120
|
+
is_fresh_black: bool = False,
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Extract the video frame from ``media_bundle`` and write as PNG.
|
|
123
|
+
|
|
124
|
+
Skips ``is_fresh_black`` bundles (synthesised session-boundary
|
|
125
|
+
black, not model output) and — when ``ignore_duplicates`` is
|
|
126
|
+
set — ``duplicate`` keepalives.
|
|
116
127
|
"""
|
|
117
128
|
if self.file_path is None:
|
|
118
129
|
return
|
|
119
130
|
|
|
120
|
-
|
|
131
|
+
if is_fresh_black:
|
|
132
|
+
self._duplicates_skipped += 1
|
|
133
|
+
logger.debug(
|
|
134
|
+
"Skipped fresh-black session-boundary frame",
|
|
135
|
+
total_skipped=self._duplicates_skipped,
|
|
136
|
+
)
|
|
137
|
+
return
|
|
138
|
+
|
|
121
139
|
if self.config.ignore_duplicates and duplicate:
|
|
122
140
|
self._duplicates_skipped += 1
|
|
123
141
|
logger.debug(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/driver/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/driver/step_result.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/connected.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/event.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/messages.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/events/upload.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/internal/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/decorators.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/handlers.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/model/reactor_model.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/pipeline/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/pipeline/idle.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/descriptors.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/input.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/interface/tracks/output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/base.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/file.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/backends/otlp.py
RENAMED
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/nvml_sampler.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/profiling/plotting/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/chunk_uploader.py
RENAMED
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/recording/track_resolver.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/headless/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/runtimes/http/http_runtime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/serve/commands/schema.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/audio_track.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/aiortc/video_track.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/gst.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/sdp/ice.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/settings.py
RENAMED
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime/transports/gstreamer/signals.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.7.5 → reactor_runtime-2.7.7}/src/reactor_runtime.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|