reactor-runtime 2.3.0__tar.gz → 2.3.2__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.3.0 → reactor_runtime-2.3.2}/PKG-INFO +1 -1
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/pyproject.toml +1 -1
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/driver/pipeline_executor.py +11 -2
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/reactor_model.py +30 -3
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/pipeline/reactor_pipeline.py +17 -4
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/profiler.py +15 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtime_api.py +0 -67
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/headless/headless_runtime.py +0 -2
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/http/http_runtime.py +0 -2
- reactor_runtime-2.3.2/src/reactor_runtime/transports/gstreamer/probes/__init__.py +5 -0
- reactor_runtime-2.3.2/src/reactor_runtime/transports/gstreamer/probes/fps_probe.py +119 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/PKG-INFO +1 -1
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/SOURCES.txt +2 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/README.md +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/setup.cfg +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/api/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/commands/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/commands/init.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/commands/run.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/commands/schema.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/main.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/utils/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/utils/config.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/utils/runtime.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_cli/utils/version.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/config.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/defaults.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/driver/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/driver/step_result.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/connected.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/event.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/messages.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/upload.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/internal/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/internal/input_buffer.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/internal/output_buffer.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/internal/reactor_core.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/decorators.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/handlers.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/pipeline/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/pipeline/idle.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/pipeline/input_state.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/descriptors.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/input.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/output.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/upload.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/model_state.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/base.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/file.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/otlp.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/helpers.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/plotting/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/plotting/plot_profiling.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/singleton.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/headless/config.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/headless/input_feeder.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/http/config.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/http/types.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/schema.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/schema_validator.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/audio_track.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/client.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/frame_conversion.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/ice_connection.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/video_track.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/config.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/events.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/client.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/av1.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/base.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/factory.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/h264.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/h265.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/vp8.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/decoders/vp9.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/av1.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/base.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/factory.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/h264.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/h265.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/opus.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/vp8.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/encoders/vp9.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/gst.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/gst_helpers.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/receiver/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/receiver/audio.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/receiver/base.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/receiver/video.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sdp/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sdp/bundle.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sdp/codec.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sdp/extmap.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sdp/ice.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sender/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sender/audio.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sender/base.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/sender/video.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/settings.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/signals.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/ice_uris.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/interface.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/media.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/types.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/utils/launch.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/utils/loader.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/utils/log.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/utils/messages.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/utils/typing.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/dependency_links.txt +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/entry_points.txt +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/requires.txt +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/top_level.txt +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/README.md +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/__init__.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/config.yml +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/model.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/pipeline.py +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/reactor.yaml +0 -0
- {reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/template/requirements.txt +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import asyncio
|
|
7
|
+
import dataclasses
|
|
7
8
|
import inspect
|
|
8
9
|
from typing import Any, Dict, Iterator, List, Optional, Type
|
|
9
10
|
|
|
@@ -144,7 +145,7 @@ class PipelineExecutor(Iterator[StepResult]):
|
|
|
144
145
|
raise ValueError(f"Unknown event {name!r}. Available events: {available}")
|
|
145
146
|
|
|
146
147
|
try:
|
|
147
|
-
entry.event_cls(**kwargs)
|
|
148
|
+
event = entry.event_cls(**kwargs)
|
|
148
149
|
except TypeError as exc:
|
|
149
150
|
raise TypeError(f"Invalid arguments for event {name!r}: {exc}") from None
|
|
150
151
|
|
|
@@ -155,7 +156,15 @@ class PipelineExecutor(Iterator[StepResult]):
|
|
|
155
156
|
if not ok:
|
|
156
157
|
raise ValueError(f"Validation failed for event {name!r}: {reason}")
|
|
157
158
|
|
|
158
|
-
|
|
159
|
+
# Mirror production dispatch (reactor_model._invoke): splat the
|
|
160
|
+
# full set of event dataclass fields into the handler kwargs so
|
|
161
|
+
# callers that omit optional fields get the dataclass default
|
|
162
|
+
# (e.g. ``None``), not the raw ``FieldInfo`` sentinel that is
|
|
163
|
+
# still present in the handler function's ``__defaults__``.
|
|
164
|
+
handler_kwargs = {
|
|
165
|
+
f.name: getattr(event, f.name) for f in dataclasses.fields(event)
|
|
166
|
+
}
|
|
167
|
+
return self._run(self._send_event(entry, **handler_kwargs))
|
|
159
168
|
|
|
160
169
|
def push_media(self, track_name: str, data: Any) -> None:
|
|
161
170
|
"""Push a media frame into an input buffer.
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/reactor_model.py
RENAMED
|
@@ -12,7 +12,8 @@ from __future__ import annotations
|
|
|
12
12
|
|
|
13
13
|
import asyncio
|
|
14
14
|
import dataclasses
|
|
15
|
-
|
|
15
|
+
import os
|
|
16
|
+
from typing import Any, Callable, List, Optional, Tuple, Type
|
|
16
17
|
|
|
17
18
|
from reactor_runtime.interface.events.connected import Connected, Disconnected
|
|
18
19
|
from reactor_runtime.interface.events.event import Event
|
|
@@ -96,12 +97,22 @@ class ReactorModel(ReactorCore):
|
|
|
96
97
|
dispatch_table = build_dispatch_table(handlers)
|
|
97
98
|
|
|
98
99
|
dispatcher = asyncio.create_task(self._dispatcher(handlers, dispatch_table))
|
|
100
|
+
crash: Optional[BaseException] = None
|
|
99
101
|
try:
|
|
100
102
|
await self.run()
|
|
101
103
|
except asyncio.CancelledError:
|
|
102
104
|
logger.info("Model cancelled")
|
|
103
|
-
except Exception:
|
|
104
|
-
|
|
105
|
+
except Exception as exc:
|
|
106
|
+
# Don't swallow-and-return: log, clean up via finally, then
|
|
107
|
+
# fail-fast (REA-1740). ``ReactorPipeline.run()`` contains
|
|
108
|
+
# its own per-session crashes, so this only fires for custom
|
|
109
|
+
# ``run()`` overrides.
|
|
110
|
+
crash = exc
|
|
111
|
+
logger.exception(
|
|
112
|
+
"run() crashed — terminating the process",
|
|
113
|
+
model=type(self).__name__,
|
|
114
|
+
exc_type=type(exc).__name__,
|
|
115
|
+
)
|
|
105
116
|
finally:
|
|
106
117
|
dispatcher.cancel()
|
|
107
118
|
try:
|
|
@@ -109,6 +120,22 @@ class ReactorModel(ReactorCore):
|
|
|
109
120
|
except asyncio.CancelledError:
|
|
110
121
|
pass
|
|
111
122
|
|
|
123
|
+
if crash is not None:
|
|
124
|
+
self._fail_fast(crash)
|
|
125
|
+
|
|
126
|
+
def _fail_fast(self, exc: BaseException) -> None:
|
|
127
|
+
"""Terminate the process after an unrecoverable ``run()`` error.
|
|
128
|
+
|
|
129
|
+
Uses :func:`os._exit` (not ``sys.exit``) so the whole process
|
|
130
|
+
goes away regardless of thread. Override in subclasses or
|
|
131
|
+
tests.
|
|
132
|
+
"""
|
|
133
|
+
logger.critical(
|
|
134
|
+
"Terminating process after unhandled run() exception",
|
|
135
|
+
exc_type=type(exc).__name__,
|
|
136
|
+
)
|
|
137
|
+
os._exit(1)
|
|
138
|
+
|
|
112
139
|
# ------------------------------------------------------------------
|
|
113
140
|
# run() — override with your generation loop
|
|
114
141
|
# ------------------------------------------------------------------
|
|
@@ -241,6 +241,10 @@ class ReactorPipeline(ReactorModel):
|
|
|
241
241
|
except BufferClosed:
|
|
242
242
|
logger.debug("Input buffer closed, ending session")
|
|
243
243
|
break
|
|
244
|
+
# Any other exception propagates up through the outer
|
|
245
|
+
# try/finally (gen close + state reset) and out of
|
|
246
|
+
# ``run()`` — ``_lifecycle`` then fails-fast via
|
|
247
|
+
# ``_fail_fast`` (REA-1740).
|
|
244
248
|
|
|
245
249
|
if output is Idle:
|
|
246
250
|
await asyncio.sleep(0.005)
|
|
@@ -251,10 +255,19 @@ class ReactorPipeline(ReactorModel):
|
|
|
251
255
|
else:
|
|
252
256
|
await self.emit(output)
|
|
253
257
|
finally:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
+
# Swallow exceptions from ``gen.close()`` only so a buggy
|
|
259
|
+
# ``inference()`` ``finally`` cannot mask the original
|
|
260
|
+
# exception on its way up to ``_lifecycle``.
|
|
261
|
+
try:
|
|
262
|
+
if is_async:
|
|
263
|
+
await gen.aclose()
|
|
264
|
+
else:
|
|
265
|
+
gen.close()
|
|
266
|
+
except Exception:
|
|
267
|
+
logger.exception(
|
|
268
|
+
"generator.close() raised during teardown",
|
|
269
|
+
model=type(self).__name__,
|
|
270
|
+
)
|
|
258
271
|
self.state = None
|
|
259
272
|
for buf in self._input_buffers.values():
|
|
260
273
|
buf.reset()
|
|
@@ -613,6 +613,18 @@ class ProfilerTimer:
|
|
|
613
613
|
)
|
|
614
614
|
self._start = None
|
|
615
615
|
|
|
616
|
+
def cancel(self) -> None:
|
|
617
|
+
"""Discard the timer run without recording a measurement.
|
|
618
|
+
|
|
619
|
+
Safe to call whether or not the timer is currently running. Used to
|
|
620
|
+
reset state when the caller's scope is aborted before ``.stop()``
|
|
621
|
+
can fire (e.g. generator exit, session interruption before first
|
|
622
|
+
output). After ``cancel()``, the timer is idle and ``.start()``
|
|
623
|
+
will succeed.
|
|
624
|
+
"""
|
|
625
|
+
self._start = None
|
|
626
|
+
self.elapsed_ms = None
|
|
627
|
+
|
|
616
628
|
|
|
617
629
|
class _NoOpTimer:
|
|
618
630
|
"""No-op timer for when profiling is disabled."""
|
|
@@ -625,6 +637,9 @@ class _NoOpTimer:
|
|
|
625
637
|
def stop(self) -> None:
|
|
626
638
|
pass
|
|
627
639
|
|
|
640
|
+
def cancel(self) -> None:
|
|
641
|
+
pass
|
|
642
|
+
|
|
628
643
|
|
|
629
644
|
class _NoOpSection:
|
|
630
645
|
"""No-op context manager for when profiling is disabled."""
|
|
@@ -41,7 +41,6 @@ logger = get_logger(__name__)
|
|
|
41
41
|
|
|
42
42
|
_IDLING_INTERVAL_ENV_VAR = "IDLING_INTERVAL_SECONDS"
|
|
43
43
|
_DEFAULT_IDLING_INTERVAL = 30.0
|
|
44
|
-
_MAX_SESSION_DURATION_ENV_VAR = "MAX_SESSION_DURATION_SECONDS"
|
|
45
44
|
|
|
46
45
|
|
|
47
46
|
# ---------------------------------------------------------------------------
|
|
@@ -70,10 +69,6 @@ class RuntimeConfig:
|
|
|
70
69
|
# Priority: ENV > CLI > default. Set to None to use default.
|
|
71
70
|
idling_interval: Optional[float] = None
|
|
72
71
|
|
|
73
|
-
# Maximum session duration in seconds. If set, sessions will be automatically
|
|
74
|
-
# stopped after this duration. Priority: ENV > CLI. Set to None to disable.
|
|
75
|
-
max_session_duration: Optional[float] = None
|
|
76
|
-
|
|
77
72
|
profiling_output_dir: Optional[str] = None
|
|
78
73
|
|
|
79
74
|
def __post_init__(self) -> None:
|
|
@@ -102,20 +97,6 @@ class RuntimeConfig:
|
|
|
102
97
|
if self.idling_interval is None:
|
|
103
98
|
self.idling_interval = _DEFAULT_IDLING_INTERVAL
|
|
104
99
|
|
|
105
|
-
# Resolve max_session_duration: ENV > CLI (no default - disabled if not set)
|
|
106
|
-
max_env = os.getenv(_MAX_SESSION_DURATION_ENV_VAR)
|
|
107
|
-
if max_env:
|
|
108
|
-
try:
|
|
109
|
-
self.max_session_duration = float(max_env)
|
|
110
|
-
except ValueError:
|
|
111
|
-
logger.warning(
|
|
112
|
-
"Invalid max session duration env value",
|
|
113
|
-
env_var=_MAX_SESSION_DURATION_ENV_VAR,
|
|
114
|
-
value=max_env,
|
|
115
|
-
)
|
|
116
|
-
if self.max_session_duration is not None and self.max_session_duration <= 0:
|
|
117
|
-
self.max_session_duration = None
|
|
118
|
-
|
|
119
100
|
@staticmethod
|
|
120
101
|
def parser() -> argparse.ArgumentParser:
|
|
121
102
|
"""Return an argument parser for runtime-specific CLI arguments.
|
|
@@ -146,12 +127,6 @@ class RuntimeConfig:
|
|
|
146
127
|
help=f"Idling event interval ({_IDLING_INTERVAL_ENV_VAR} env overrides). "
|
|
147
128
|
f"Default: {_DEFAULT_IDLING_INTERVAL}s",
|
|
148
129
|
)
|
|
149
|
-
parser.add_argument(
|
|
150
|
-
"--max-session-duration",
|
|
151
|
-
type=float,
|
|
152
|
-
default=None,
|
|
153
|
-
help=f"Max session seconds ({_MAX_SESSION_DURATION_ENV_VAR} env overrides).",
|
|
154
|
-
)
|
|
155
130
|
parser.add_argument(
|
|
156
131
|
"--profiling-dir",
|
|
157
132
|
type=str,
|
|
@@ -196,9 +171,6 @@ class Runtime(ModelStateMachine, ABC):
|
|
|
196
171
|
# Idling task - sends periodic IDLING events when in READY state
|
|
197
172
|
self._idling_task: Optional[asyncio.Task] = None
|
|
198
173
|
|
|
199
|
-
# Max session duration task - stops session after configured duration
|
|
200
|
-
self._max_session_duration_task: Optional[asyncio.Task] = None
|
|
201
|
-
|
|
202
174
|
# Graceful shutdown state (for SIGTERM handling)
|
|
203
175
|
self._shutdown_pending: bool = False
|
|
204
176
|
self._shutdown_event: asyncio.Event = asyncio.Event()
|
|
@@ -334,7 +306,6 @@ class Runtime(ModelStateMachine, ABC):
|
|
|
334
306
|
self._cancel_orphan_timeout()
|
|
335
307
|
|
|
336
308
|
if previous_state == ModelState.WAITING:
|
|
337
|
-
self._start_max_session_duration_timeout()
|
|
338
309
|
if self.model is not None:
|
|
339
310
|
self.model._push_event(Connected())
|
|
340
311
|
logger.info("Pushed Connected event to model")
|
|
@@ -373,7 +344,6 @@ class Runtime(ModelStateMachine, ABC):
|
|
|
373
344
|
``@disconnected`` asynchronously on its own thread.
|
|
374
345
|
"""
|
|
375
346
|
self._cancel_orphan_timeout()
|
|
376
|
-
self._cancel_max_session_duration_timeout()
|
|
377
347
|
|
|
378
348
|
if self.model is not None:
|
|
379
349
|
self.model._push_event(Disconnected())
|
|
@@ -805,43 +775,6 @@ class Runtime(ModelStateMachine, ABC):
|
|
|
805
775
|
self._orphan_task.cancel()
|
|
806
776
|
self._orphan_task = None
|
|
807
777
|
|
|
808
|
-
# -----------------------------------------------------------------
|
|
809
|
-
# Max session duration
|
|
810
|
-
# -----------------------------------------------------------------
|
|
811
|
-
|
|
812
|
-
def _start_max_session_duration_timeout(self) -> None:
|
|
813
|
-
"""Start the max session duration timeout task.
|
|
814
|
-
|
|
815
|
-
If max_session_duration is configured, the session will be automatically
|
|
816
|
-
stopped when the duration expires. This provides a hard limit on session
|
|
817
|
-
lifetime regardless of client activity.
|
|
818
|
-
"""
|
|
819
|
-
if (
|
|
820
|
-
self.config.max_session_duration is None
|
|
821
|
-
or self.config.max_session_duration <= 0
|
|
822
|
-
):
|
|
823
|
-
return
|
|
824
|
-
self._cancel_max_session_duration_timeout()
|
|
825
|
-
|
|
826
|
-
async def coro() -> None:
|
|
827
|
-
try:
|
|
828
|
-
await asyncio.sleep(self.config.max_session_duration) # type: ignore[arg-type]
|
|
829
|
-
if self.current_state in (
|
|
830
|
-
ModelState.STREAMING,
|
|
831
|
-
ModelState.ORPHANED,
|
|
832
|
-
):
|
|
833
|
-
self.send(ModelEvent.STOP_SESSION)
|
|
834
|
-
except asyncio.CancelledError:
|
|
835
|
-
pass
|
|
836
|
-
|
|
837
|
-
self._max_session_duration_task = asyncio.create_task(coro())
|
|
838
|
-
|
|
839
|
-
def _cancel_max_session_duration_timeout(self) -> None:
|
|
840
|
-
"""Cancel the max session duration timeout if running."""
|
|
841
|
-
if self._max_session_duration_task is not None:
|
|
842
|
-
self._max_session_duration_task.cancel()
|
|
843
|
-
self._max_session_duration_task = None
|
|
844
|
-
|
|
845
778
|
# -----------------------------------------------------------------
|
|
846
779
|
# Idling
|
|
847
780
|
# -----------------------------------------------------------------
|
|
@@ -397,14 +397,12 @@ async def serve(
|
|
|
397
397
|
- output_root: Root directory for output (default: "./output")
|
|
398
398
|
- no_ignore_duplicates: If True, write all frames including duplicates (default: False)
|
|
399
399
|
- orphan_timeout: Seconds to wait before stopping orphaned session (default: 30.0)
|
|
400
|
-
- max_session_duration: Maximum session duration in seconds (default: None, disabled)
|
|
401
400
|
"""
|
|
402
401
|
config = HeadlessRuntimeConfig(
|
|
403
402
|
reactor_config=reactor_config,
|
|
404
403
|
output_root=kwargs.get("output_root", "./output"),
|
|
405
404
|
ignore_duplicates=not kwargs.get("no_ignore_duplicates", False),
|
|
406
405
|
orphan_timeout=kwargs.get("orphan_timeout", 30.0),
|
|
407
|
-
max_session_duration=kwargs.get("max_session_duration"),
|
|
408
406
|
profiling_output_dir=kwargs.get("profiling_output_dir"),
|
|
409
407
|
)
|
|
410
408
|
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/http/http_runtime.py
RENAMED
|
@@ -647,7 +647,6 @@ async def serve(
|
|
|
647
647
|
- host: Host to bind to (default: "0.0.0.0")
|
|
648
648
|
- port: Port to bind to (default: 8080)
|
|
649
649
|
- orphan_timeout: Seconds to wait before stopping orphaned session (default: 30.0)
|
|
650
|
-
- max_session_duration: Maximum session duration in seconds (default: None, disabled)
|
|
651
650
|
- webrtc_port_range: WebRTC ICE UDP port range as tuple (min, max) (default: None)
|
|
652
651
|
- stun_servers: List of STUN server URLs (default: None, uses Google STUN)
|
|
653
652
|
- turn_servers: List of TURN servers in format "username;credential;url" (default: None)
|
|
@@ -669,7 +668,6 @@ async def serve(
|
|
|
669
668
|
host=kwargs.get("host", "0.0.0.0"),
|
|
670
669
|
port=kwargs.get("port", 8080),
|
|
671
670
|
orphan_timeout=kwargs.get("orphan_timeout", 30.0),
|
|
672
|
-
max_session_duration=kwargs.get("max_session_duration"),
|
|
673
671
|
webrtc_port_range=kwargs.get("webrtc_port_range"),
|
|
674
672
|
stun_servers=kwargs.get("stun_servers"),
|
|
675
673
|
turn_servers=kwargs.get("turn_servers"),
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Copyright (c) 2026 Reactor Technologies, Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Buffer-count FPS probes on GStreamer pads.
|
|
5
|
+
Each :class:`FpsProbe` instance is independent: attach one probe per pad /
|
|
6
|
+
measurement site (e.g. after ``videoconvert``, after an encoder, on a queue src pad).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
from typing import Any, Optional
|
|
13
|
+
|
|
14
|
+
from reactor_runtime.transports.gstreamer.gst import Gst
|
|
15
|
+
from reactor_runtime.utils.log import get_logger
|
|
16
|
+
|
|
17
|
+
logger = get_logger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class FpsProbe:
|
|
21
|
+
"""
|
|
22
|
+
Install a ``Gst.PadProbeType.BUFFER`` probe that reports buffers per second
|
|
23
|
+
over a rolling wall-clock window (default 1s of monotonic time).
|
|
24
|
+
Instances do not share state. Typical usage::
|
|
25
|
+
probe_videoconvert = FpsProbe("video_after_videoconvert")
|
|
26
|
+
probe_videoconvert.attach(videoconvert.get_static_pad("src"))
|
|
27
|
+
probe_encoder = FpsProbe("video_after_encoder")
|
|
28
|
+
probe_encoder.attach(encoder_element.get_static_pad("src"))
|
|
29
|
+
``last_fps`` is updated at the end of each completed window. Each completed
|
|
30
|
+
window is logged at INFO.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
name: str,
|
|
36
|
+
*,
|
|
37
|
+
window_ns: Optional[int] = None,
|
|
38
|
+
) -> None:
|
|
39
|
+
self._name = name
|
|
40
|
+
self._window_ns = int(Gst.SECOND if window_ns is None else window_ns)
|
|
41
|
+
if self._window_ns <= 0:
|
|
42
|
+
raise ValueError("window_ns must be positive")
|
|
43
|
+
|
|
44
|
+
self._pad: Optional[Gst.Pad] = None
|
|
45
|
+
self._probe_id: Optional[int] = None
|
|
46
|
+
self._window_start_ns: Optional[int] = None
|
|
47
|
+
self._count = 0
|
|
48
|
+
self._last_fps: Optional[float] = None
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def name(self) -> str:
|
|
52
|
+
return self._name
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def last_fps(self) -> Optional[float]:
|
|
56
|
+
"""Buffers per second from the last completed ``window_ns`` interval."""
|
|
57
|
+
return self._last_fps
|
|
58
|
+
|
|
59
|
+
def attach(self, pad: Gst.Pad) -> None:
|
|
60
|
+
"""
|
|
61
|
+
Add this probe on *pad* (usually a src pad, downstream of the element under test).
|
|
62
|
+
Raises:
|
|
63
|
+
RuntimeError: if this instance already has a probe installed.
|
|
64
|
+
"""
|
|
65
|
+
if self._probe_id:
|
|
66
|
+
raise RuntimeError(
|
|
67
|
+
f"FpsProbe({self._name!r}) is already attached; call detach() first"
|
|
68
|
+
)
|
|
69
|
+
self._pad = pad
|
|
70
|
+
self._window_start_ns = None
|
|
71
|
+
self._count = 0
|
|
72
|
+
self._probe_id = pad.add_probe(
|
|
73
|
+
Gst.PadProbeType.BUFFER,
|
|
74
|
+
self._buffer_probe,
|
|
75
|
+
None, # user_data (PyGObject passes this as the 3rd callback arg)
|
|
76
|
+
)
|
|
77
|
+
if not self._probe_id:
|
|
78
|
+
self._pad = None
|
|
79
|
+
raise RuntimeError(f"FpsProbe({self._name!r}): pad.add_probe() failed")
|
|
80
|
+
|
|
81
|
+
def detach(self) -> None:
|
|
82
|
+
"""Remove the probe from the pad, if installed."""
|
|
83
|
+
if self._pad is not None and self._probe_id is not None:
|
|
84
|
+
self._pad.remove_probe(self._probe_id)
|
|
85
|
+
self._pad = None
|
|
86
|
+
self._probe_id = None
|
|
87
|
+
self._window_start_ns = None
|
|
88
|
+
self._count = 0
|
|
89
|
+
self._last_fps = None
|
|
90
|
+
|
|
91
|
+
def _buffer_probe(
|
|
92
|
+
self,
|
|
93
|
+
_pad: Gst.Pad,
|
|
94
|
+
info: Gst.PadProbeInfo,
|
|
95
|
+
_user_data: Any,
|
|
96
|
+
) -> Gst.PadProbeReturn:
|
|
97
|
+
buf = info.get_buffer()
|
|
98
|
+
if buf is None:
|
|
99
|
+
return Gst.PadProbeReturn.OK
|
|
100
|
+
|
|
101
|
+
now = time.monotonic_ns()
|
|
102
|
+
window_start = self._window_start_ns
|
|
103
|
+
if window_start is None:
|
|
104
|
+
self._window_start_ns = now
|
|
105
|
+
return Gst.PadProbeReturn.OK
|
|
106
|
+
|
|
107
|
+
self._count += 1
|
|
108
|
+
elapsed = now - window_start
|
|
109
|
+
if elapsed >= self._window_ns:
|
|
110
|
+
# buffers / second for the window that just ended
|
|
111
|
+
fps = self._count * 1_000_000_000 / elapsed
|
|
112
|
+
self._last_fps = fps
|
|
113
|
+
logger.info(
|
|
114
|
+
f"gstreamer_fps_probe name={self._name} fps={fps:.2f} buffers={self._count} window_s={elapsed / 1e9:.3f}",
|
|
115
|
+
)
|
|
116
|
+
self._window_start_ns = now
|
|
117
|
+
self._count = 0
|
|
118
|
+
|
|
119
|
+
return Gst.PadProbeReturn.OK
|
|
@@ -101,6 +101,8 @@ src/reactor_runtime/transports/gstreamer/encoders/h265.py
|
|
|
101
101
|
src/reactor_runtime/transports/gstreamer/encoders/opus.py
|
|
102
102
|
src/reactor_runtime/transports/gstreamer/encoders/vp8.py
|
|
103
103
|
src/reactor_runtime/transports/gstreamer/encoders/vp9.py
|
|
104
|
+
src/reactor_runtime/transports/gstreamer/probes/__init__.py
|
|
105
|
+
src/reactor_runtime/transports/gstreamer/probes/fps_probe.py
|
|
104
106
|
src/reactor_runtime/transports/gstreamer/receiver/__init__.py
|
|
105
107
|
src/reactor_runtime/transports/gstreamer/receiver/audio.py
|
|
106
108
|
src/reactor_runtime/transports/gstreamer/receiver/base.py
|
|
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.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/driver/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/driver/step_result.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/connected.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/event.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/messages.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/events/upload.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/internal/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/decorators.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/model/handlers.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/pipeline/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/pipeline/idle.py
RENAMED
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/descriptors.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/input.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/interface/tracks/output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/base.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/file.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/backends/otlp.py
RENAMED
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/profiling/plotting/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/runtimes/headless/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/audio_track.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/aiortc/video_track.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/__init__.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/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
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/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
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/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.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime/transports/gstreamer/settings.py
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/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
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{reactor_runtime-2.3.0 → reactor_runtime-2.3.2}/src/reactor_runtime.egg-info/entry_points.txt
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
|