Skip to content

Commit d834d35

Browse files
xianshijing-lkclaudegithub-actions[bot]
authored
chore: update rust-sdks to livekit-ffi v0.12.68 (#735)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 5bd5856 commit d834d35

10 files changed

Lines changed: 314 additions & 205 deletions

File tree

examples/local_video/publisher.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import signal
88
import time
9+
from enum import Enum
910

1011
import numpy as np
1112
from livekit import api, rtc
@@ -19,6 +20,13 @@
1920
) from exc
2021

2122

23+
class FrameFormat(str, Enum):
24+
"""Frame format to use for publishing."""
25+
26+
RGBA = "rgba"
27+
I420 = "i420"
28+
29+
2230
def parse_args() -> argparse.Namespace:
2331
parser = argparse.ArgumentParser(
2432
description="Publish a local camera track with optional frame metadata.",
@@ -46,6 +54,13 @@ def parse_args() -> argparse.Namespace:
4654
action="store_true",
4755
help="Attach a monotonically increasing FrameMetadata.frame_id",
4856
)
57+
parser.add_argument(
58+
"--format",
59+
type=FrameFormat,
60+
default=FrameFormat.I420,
61+
choices=list(FrameFormat),
62+
help="Frame format: 'i420' (default, efficient) or 'rgba' (original behavior)",
63+
)
4964
return parser.parse_args()
5065

5166

@@ -147,6 +162,14 @@ def _install_signal_handlers(stop_event: asyncio.Event) -> None:
147162
pass
148163

149164

165+
def _bgr_to_i420(bgr: np.ndarray, width: int, height: int) -> bytes:
166+
"""Convert BGR image to I420 (YUV420p) format efficiently."""
167+
# OpenCV's COLOR_BGR2YUV_I420 outputs planar YUV420p (I420)
168+
# Layout: Y plane (width*height), U plane (width/2 * height/2), V plane (width/2 * height/2)
169+
yuv = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV_I420)
170+
return yuv.tobytes()
171+
172+
150173
async def _capture_loop(
151174
args: argparse.Namespace,
152175
capture: cv2.VideoCapture,
@@ -161,6 +184,9 @@ async def _capture_loop(
161184
frame_id = 1
162185
submitted = 0
163186
last_log_at = time.perf_counter()
187+
use_i420 = args.format == FrameFormat.I420
188+
189+
logging.info("Using frame format: %s", args.format.value)
164190

165191
while not stop_event.is_set():
166192
ok, bgr = await asyncio.to_thread(capture.read)
@@ -174,9 +200,17 @@ async def _capture_loop(
174200

175201
user_timestamp = _unix_time_us()
176202
timestamp_us = (time.perf_counter_ns() - started_at_ns) // 1_000
177-
rgba = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGBA)
178-
rgba = np.ascontiguousarray(rgba)
179-
frame = rtc.VideoFrame(width, height, rtc.VideoBufferType.RGBA, rgba.tobytes())
203+
204+
if use_i420:
205+
# Direct BGR -> I420 conversion (single step, more efficient)
206+
i420_data = _bgr_to_i420(bgr, width, height)
207+
frame = rtc.VideoFrame(width, height, rtc.VideoBufferType.I420, i420_data)
208+
else:
209+
# Original path: BGR -> RGBA -> I420 (in FFI layer)
210+
rgba = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGBA)
211+
rgba = np.ascontiguousarray(rgba)
212+
frame = rtc.VideoFrame(width, height, rtc.VideoBufferType.RGBA, rgba.tobytes())
213+
180214
metadata = _metadata_for_frame(
181215
args,
182216
user_timestamp=user_timestamp,
@@ -191,7 +225,10 @@ async def _capture_loop(
191225
now = time.perf_counter()
192226
if now - last_log_at >= 2.0:
193227
logging.info(
194-
"published %s frames at ~%.1f fps", submitted, submitted / (now - last_log_at)
228+
"published %s frames at ~%.1f fps (format=%s)",
229+
submitted,
230+
submitted / (now - last_log_at),
231+
args.format.value,
195232
)
196233
submitted = 0
197234
last_log_at = now

livekit-rtc/livekit/rtc/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
)
5959
from .participant import (
6060
ConnectionQuality,
61+
DegradationPreference,
6162
LocalParticipant,
6263
Participant,
6364
RemoteParticipant,
@@ -138,6 +139,7 @@
138139
"ConnectionQuality",
139140
"ConnectionState",
140141
"DataPacketKind",
142+
"DegradationPreference",
141143
"TrackPublishOptions",
142144
"IceTransportType",
143145
"ContinualGatheringPolicy",

livekit-rtc/livekit/rtc/_proto/room_pb2.py

Lines changed: 168 additions & 166 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

livekit-rtc/livekit/rtc/_proto/room_pb2.pyi

Lines changed: 48 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

livekit-rtc/livekit/rtc/_proto/track_pb2.py

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

livekit-rtc/livekit/rtc/_proto/track_pb2.pyi

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)