Skip to content

Commit f23edd4

Browse files
committed
wip
1 parent 5e7e3bf commit f23edd4

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

livekit-rtc/livekit/rtc/_utils.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from collections import deque
1818
import ctypes
1919
import random
20-
from typing import Callable, Generator, Generic, List, TypeVar
20+
from typing import Callable, Generator, Generic, List, TypeVar, Union
2121

2222
logger = logging.getLogger("livekit")
2323

@@ -40,8 +40,25 @@ def task_done_logger(task: asyncio.Task) -> None:
4040
return
4141

4242

43+
def _buffer_supported_or_raise(
44+
data: Union[bytes, bytearray, memoryview],
45+
) -> None:
46+
"""Validate a buffer for FFI use.
47+
48+
Raises clear errors for non-contiguous or sliced memoryviews.
49+
"""
50+
if isinstance(data, memoryview):
51+
if not data.contiguous:
52+
raise ValueError("memoryview must be contiguous")
53+
if data.nbytes != len(data.obj):
54+
raise ValueError("sliced memoryviews are not supported")
55+
elif not isinstance(data, (bytes, bytearray)):
56+
raise TypeError(f"expected bytes, bytearray, or memoryview, got {type(data)}")
57+
58+
4359
def get_address(data) -> int:
4460
if isinstance(data, memoryview):
61+
_buffer_supported_or_raise(data)
4562
if not data.readonly:
4663
return ctypes.addressof(ctypes.c_char.from_buffer(data))
4764
data = data.obj

livekit-rtc/livekit/rtc/apm.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,15 @@ def process_stream(self, data: AudioFrame) -> None:
4848
Important:
4949
Audio frames must be exactly 10 ms in duration.
5050
"""
51-
bdata = data.data.cast("b")
51+
if isinstance(data._data, bytes) or (
52+
isinstance(data._data, memoryview) and data._data.readonly
53+
):
54+
data._data = bytearray(data._data)
5255

5356
req = proto_ffi.FfiRequest()
5457
req.apm_process_stream.apm_handle = self._ffi_handle.handle
55-
req.apm_process_stream.data_ptr = get_address(memoryview(bdata))
56-
req.apm_process_stream.size = len(bdata)
58+
req.apm_process_stream.data_ptr = get_address(data._data)
59+
req.apm_process_stream.size = len(data._data)
5760
req.apm_process_stream.sample_rate = data.sample_rate
5861
req.apm_process_stream.num_channels = data.num_channels
5962

@@ -73,12 +76,15 @@ def process_reverse_stream(self, data: AudioFrame) -> None:
7376
Important:
7477
Audio frames must be exactly 10 ms in duration.
7578
"""
76-
bdata = data.data.cast("b")
79+
if isinstance(data._data, bytes) or (
80+
isinstance(data._data, memoryview) and data._data.readonly
81+
):
82+
data._data = bytearray(data._data)
7783

7884
req = proto_ffi.FfiRequest()
7985
req.apm_process_reverse_stream.apm_handle = self._ffi_handle.handle
80-
req.apm_process_reverse_stream.data_ptr = get_address(memoryview(bdata))
81-
req.apm_process_reverse_stream.size = len(bdata)
86+
req.apm_process_reverse_stream.data_ptr = get_address(data._data)
87+
req.apm_process_reverse_stream.size = len(data._data)
8288
req.apm_process_reverse_stream.sample_rate = data.sample_rate
8389
req.apm_process_reverse_stream.num_channels = data.num_channels
8490

livekit-rtc/livekit/rtc/audio_frame.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import ctypes
1616
from ._ffi_client import FfiHandle
1717
from ._proto import audio_frame_pb2 as proto_audio
18-
from ._utils import get_address
18+
from ._utils import _buffer_supported_or_raise, get_address
1919
from typing import Any, Union
2020

2121

@@ -49,8 +49,7 @@ def __init__(
4949
Raises:
5050
ValueError: If the length of `data` is smaller than the required size.
5151
"""
52-
if isinstance(data, memoryview):
53-
data = data.obj # type: ignore[assignment]
52+
_buffer_supported_or_raise(data)
5453

5554
min_size = num_channels * samples_per_channel * ctypes.sizeof(ctypes.c_int16)
5655
data_len = len(data)

livekit-rtc/livekit/rtc/video_frame.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from ._proto import ffi_pb2 as proto
1919
from typing import List, Optional
2020
from ._ffi_client import FfiClient, FfiHandle
21-
from ._utils import get_address
21+
from ._utils import _buffer_supported_or_raise, get_address
2222

2323
from typing import Any
2424

@@ -48,6 +48,8 @@ def __init__(
4848
(e.g., RGBA, BGRA, RGB24, etc.).
4949
data (Union[bytes, bytearray, memoryview]): The raw pixel data for the video frame.
5050
"""
51+
_buffer_supported_or_raise(data)
52+
5153
self._width = width
5254
self._height = height
5355
self._type = type

0 commit comments

Comments
 (0)