webrtc/athena: speed up first time stream connection (#38184)

* move streamrequest to models file, prewarm in webrtcd

* cleanup

* debug

* change print to logger.info
This commit is contained in:
stef
2026-06-16 16:48:16 -04:00
committed by GitHub
parent 4cefe7239d
commit f3b1f97afa
4 changed files with 31 additions and 18 deletions
+1 -1
View File
@@ -581,7 +581,7 @@ def getNetworks():
@dispatcher.add_method
def startStream(sdp: str, video_enabled: bool | None = None) -> dict:
from openpilot.system.webrtc.webrtcd import StreamRequestBody
from openpilot.system.webrtc.models import StreamRequestBody
bridge_services_in = []
# get live car params to avoid stale notCar edge case
+2 -3
View File
@@ -7,7 +7,7 @@ from teleoprtc.tracks import TiciVideoStreamTrack
from aiortc import MediaStreamError
from cereal import messaging
from openpilot.common.realtime import DT_MDL, DT_DMON
from openpilot.common.realtime import DT_MDL
from openpilot.common.params import Params
@@ -30,8 +30,7 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack):
}
def __init__(self, camera_type: str, video_enabled: bool = True):
dt = DT_DMON if camera_type == "driver" else DT_MDL
super().__init__(camera_type, dt)
super().__init__(camera_type, DT_MDL)
self._sock = self._make_sock(camera_type)
self._pts = 0
+9
View File
@@ -0,0 +1,9 @@
from dataclasses import dataclass, field
@dataclass
class StreamRequestBody:
sdp: str
initCamera: str
video_enabled: bool = True
bridge_services_in: list[str] = field(default_factory=list)
bridge_services_out: list[str] = field(default_factory=list)
+19 -14
View File
@@ -10,7 +10,6 @@ import contextlib
import json
import uuid
import logging
from dataclasses import dataclass, field
from typing import Any, TYPE_CHECKING
# aiortc and its dependencies have lots of internal warnings :(
@@ -22,13 +21,13 @@ import capnp
from aiohttp import web
if TYPE_CHECKING:
from aiortc.rtcdatachannel import RTCDataChannel
import aioice.ice
from openpilot.system.webrtc.models import StreamRequestBody
from openpilot.system.webrtc.schema import generate_field
from openpilot.common.params import Params
from cereal import messaging, log
import aioice.ice
# socket trick: route lookup for 8.8.8.8 (nothing is sent or actually connected to)
# return the source interfaces IP which is the default interface of the device
@@ -254,9 +253,10 @@ class StreamSession:
enabled: bool | None = None,
debug_mode: bool = False
):
from aiortc.mediastreams import VideoStreamTrack
if debug_mode:
from aiortc.mediastreams import VideoStreamTrack
from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack
from teleoprtc import WebRTCAnswerBuilder
from teleoprtc.builder import WebRTCAnswerBuilder
self.identifier = str(uuid.uuid4())
self.params = Params()
@@ -370,15 +370,6 @@ class StreamSession:
await self.stream.stop()
@dataclass
class StreamRequestBody:
sdp: str
initCamera: str
video_enabled: bool = True
bridge_services_in: list[str] = field(default_factory=list)
bridge_services_out: list[str] = field(default_factory=list)
async def get_stream(request: 'web.Request'):
stream_dict, debug_mode = request.app['streams'], request.app['debug']
raw_body = await request.json()
@@ -455,11 +446,25 @@ async def error_middleware(request: 'web.Request', handler):
return web.json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500)
def prewarm_stream_session_imports(debug_mode: bool = False) -> None:
if debug_mode:
from aiortc.mediastreams import VideoStreamTrack
assert VideoStreamTrack
from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack
from teleoprtc.builder import WebRTCAnswerBuilder
assert LiveStreamVideoStreamTrack
assert WebRTCAnswerBuilder
def webrtcd_thread(host: str, port: int, debug: bool):
logging.basicConfig(level=logging.CRITICAL, handlers=[logging.StreamHandler()])
logging_level = logging.DEBUG if debug else logging.INFO
logging.getLogger("WebRTCStream").setLevel(logging_level)
logging.getLogger("webrtcd").setLevel(logging_level)
prewarm_start = time.monotonic()
prewarm_stream_session_imports(debug)
prewarm_end = time.monotonic()
logging.getLogger("webrtcd").info(f"webrtc prewarm finished in {(prewarm_end - prewarm_start) * 1000} ms")
app = web.Application(middlewares=[error_middleware])