Skip to content

Commit d7879c9

Browse files
Merge pull request #743 from roboflow/fix/byte-track-0-fps
Fix/byte track 0 fps with webrtc
2 parents f6e130c + 34da916 commit d7879c9

File tree

6 files changed

+142
-146
lines changed

6 files changed

+142
-146
lines changed

inference/core/interfaces/camera/entities.py

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
import logging
2-
import time
3-
from collections import deque
42
from dataclasses import dataclass
53
from datetime import datetime
64
from enum import Enum
7-
from threading import Event, Lock
85
from typing import Callable, Dict, Optional, Tuple, Union
96

107
import numpy as np
118

12-
from inference.core import logger
13-
from inference.core.utils.function import experimental
14-
159
FrameTimestamp = datetime
1610
FrameID = int
1711

@@ -103,59 +97,4 @@ def initialize_source_properties(self, properties: Dict[str, float]):
10397
pass
10498

10599

106-
class WebRTCVideoFrameProducer(VideoFrameProducer):
107-
@experimental(
108-
reason="Usage of WebRTCVideoFrameProducer with `InferencePipeline` is an experimental feature."
109-
"Please report any issues here: https://github.com/roboflow/inference/issues"
110-
)
111-
def __init__(
112-
self, to_inference_queue: deque, to_inference_lock: Lock, stop_event: Event
113-
):
114-
self.to_inference_queue: deque = to_inference_queue
115-
self.to_inference_lock: Lock = to_inference_lock
116-
self._stop_event = stop_event
117-
self._w: Optional[int] = None
118-
self._h: Optional[int] = None
119-
self._fps_buff = []
120-
self._is_opened = True
121-
122-
def grab(self) -> bool:
123-
return self._is_opened
124-
125-
def retrieve(self) -> Tuple[bool, np.ndarray]:
126-
while not self._stop_event.is_set() and not self.to_inference_queue:
127-
time.sleep(0.1)
128-
if self._stop_event.is_set():
129-
logger.info("Received termination signal, closing.")
130-
self._is_opened = False
131-
return False, None
132-
with self.to_inference_lock:
133-
img = self.to_inference_queue.pop()
134-
return True, img
135-
136-
def release(self):
137-
self._is_opened = False
138-
139-
def isOpened(self) -> bool:
140-
return self._is_opened
141-
142-
def discover_source_properties(self) -> SourceProperties:
143-
max_ts = max(self._fps_buff, key=lambda x: x["ts"]) if self._fps_buff else 0
144-
min_ts = min(self._fps_buff, key=lambda x: x["ts"]) if self._fps_buff else 0
145-
if max_ts == min_ts:
146-
max_ts += 0.1
147-
fps = len(self._fps_buff) / (max_ts - min_ts)
148-
return SourceProperties(
149-
width=self._w,
150-
height=self._h,
151-
total_frames=-1,
152-
is_file=False,
153-
fps=fps,
154-
is_reconnectable=False,
155-
)
156-
157-
def initialize_source_properties(self, properties: Dict[str, float]):
158-
pass
159-
160-
161100
VideoSourceIdentifier = Union[str, int, Callable[[], VideoFrameProducer]]

inference/core/interfaces/stream_manager/manager_app/entities.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class InitialiseWebRTCPipelinePayload(InitialisePipelinePayload):
9292
stream_output: Optional[List[str]] = Field(default_factory=list)
9393
data_output: Optional[List[str]] = Field(default_factory=list)
9494
webrtc_peer_timeout: float = 1
95+
webcam_fps: Optional[float] = None
9596

9697

9798
class ConsumeResultsPayload(BaseModel):

inference/core/interfaces/stream_manager/manager_app/inference_pipeline_manager.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import signal
44
import threading
5+
import time
56
from collections import deque
67
from dataclasses import asdict
78
from functools import partial
@@ -10,7 +11,6 @@
1011
from types import FrameType
1112
from typing import Deque, Dict, Optional, Tuple
1213

13-
from aiortc import RTCPeerConnection
1414
from pydantic import ValidationError
1515

1616
from inference.core import logger
@@ -19,10 +19,7 @@
1919
RoboflowAPINotAuthorizedError,
2020
RoboflowAPINotNotFoundError,
2121
)
22-
from inference.core.interfaces.camera.entities import (
23-
VideoFrame,
24-
WebRTCVideoFrameProducer,
25-
)
22+
from inference.core.interfaces.camera.entities import VideoFrame
2623
from inference.core.interfaces.camera.exceptions import StreamOperationNotAllowedError
2724
from inference.core.interfaces.http.orjson_utils import (
2825
serialise_single_workflow_result_element,
@@ -41,12 +38,13 @@
4138
InitialisePipelinePayload,
4239
InitialiseWebRTCPipelinePayload,
4340
OperationStatus,
44-
WebRTCOffer,
4541
)
4642
from inference.core.interfaces.stream_manager.manager_app.serialisation import (
4743
describe_error,
4844
)
4945
from inference.core.interfaces.stream_manager.manager_app.webrtc import (
46+
RTCPeerConnectionWithFPS,
47+
WebRTCVideoFrameProducer,
5048
init_rtc_peer_connection,
5149
)
5250
from inference.core.workflows.execution_engine.entities.base import WorkflowImageData
@@ -202,18 +200,13 @@ def _start_webrtc(self, request_id: str, payload: dict):
202200
watchdog = BasePipelineWatchDog()
203201

204202
webrtc_offer = parsed_payload.webrtc_offer
203+
webcam_fps = parsed_payload.webcam_fps
205204
to_inference_queue = deque()
206205
to_inference_lock = Lock()
207206
from_inference_queue = deque()
208207
from_inference_lock = Lock()
209208

210209
stop_event = Event()
211-
webrtc_producer = partial(
212-
WebRTCVideoFrameProducer,
213-
to_inference_lock=to_inference_lock,
214-
to_inference_queue=to_inference_queue,
215-
stop_event=stop_event,
216-
)
217210

218211
def start_loop(loop: asyncio.AbstractEventLoop):
219212
asyncio.set_event_loop(loop)
@@ -232,10 +225,19 @@ def start_loop(loop: asyncio.AbstractEventLoop):
232225
from_inference_lock=from_inference_lock,
233226
webrtc_peer_timeout=parsed_payload.webrtc_peer_timeout,
234227
feedback_stop_event=stop_event,
228+
webcam_fps=webcam_fps,
235229
),
236230
loop,
237231
)
238-
peer_connection = future.result()
232+
peer_connection: RTCPeerConnectionWithFPS = future.result()
233+
234+
webrtc_producer = partial(
235+
WebRTCVideoFrameProducer,
236+
to_inference_lock=to_inference_lock,
237+
to_inference_queue=to_inference_queue,
238+
stop_event=stop_event,
239+
webrtc_video_transform_track=peer_connection.video_transform_track,
240+
)
239241

240242
def webrtc_sink(
241243
prediction: Dict[str, WorkflowImageData], video_frame: VideoFrame

0 commit comments

Comments
 (0)