cereal/visionipc/visionipc_pyx.pyx

169 lines
4.4 KiB
Cython
Raw Permalink Normal View History

# distutils: language = c++
# cython: c_string_encoding=ascii, language_level=3
import sys
2021-08-30 13:00:09 +08:00
import numpy as np
cimport numpy as cnp
from cython.view cimport array
from libc.string cimport memcpy
from libc.stdint cimport uint32_t, uint64_t
2021-08-30 13:00:09 +08:00
from libcpp cimport bool
from libcpp.string cimport string
from .visionipc cimport VisionIpcServer as cppVisionIpcServer
2021-08-30 13:00:09 +08:00
from .visionipc cimport VisionIpcClient as cppVisionIpcClient
from .visionipc cimport VisionBuf as cppVisionBuf
from .visionipc cimport VisionIpcBufExtra
from .visionipc cimport get_endpoint_name as cpp_get_endpoint_name
def get_endpoint_name(string name, VisionStreamType stream):
return cpp_get_endpoint_name(name, stream).decode('utf-8')
cpdef enum VisionStreamType:
2021-11-30 10:12:50 +08:00
VISION_STREAM_ROAD
VISION_STREAM_DRIVER
VISION_STREAM_WIDE_ROAD
VISION_STREAM_MAP
2021-08-30 13:00:09 +08:00
2023-07-25 14:59:08 +08:00
cdef class VisionBuf:
@staticmethod
cdef create(cppVisionBuf * cbuf):
buf = VisionBuf()
buf.buf = cbuf
return buf
@property
def data(self):
return np.asarray(<cnp.uint8_t[:self.buf.len]> self.buf.addr)
@property
def width(self):
return self.buf.width
@property
def height(self):
return self.buf.height
@property
def stride(self):
return self.buf.stride
@property
def uv_offset(self):
return self.buf.uv_offset
@property
def rgb(self):
return self.buf.rgb
cdef class VisionIpcServer:
cdef cppVisionIpcServer * server
def __init__(self, string name):
self.server = new cppVisionIpcServer(name, NULL, NULL)
def create_buffers(self, VisionStreamType tp, size_t num_buffers, bool rgb, size_t width, size_t height):
self.server.create_buffers(tp, num_buffers, rgb, width, height)
def create_buffers_with_sizes(self, VisionStreamType tp, size_t num_buffers, bool rgb, size_t width, size_t height, size_t size, size_t stride, size_t uv_offset):
self.server.create_buffers_with_sizes(tp, num_buffers, rgb, width, height, size, stride, uv_offset)
def send(self, VisionStreamType tp, const unsigned char[:] data, uint32_t frame_id=0, uint64_t timestamp_sof=0, uint64_t timestamp_eof=0):
cdef cppVisionBuf * buf = self.server.get_buffer(tp)
# Populate buffer
assert buf.len == len(data)
memcpy(buf.addr, &data[0], len(data))
buf.set_frame_id(frame_id)
cdef VisionIpcBufExtra extra
extra.frame_id = frame_id
extra.timestamp_sof = timestamp_sof
extra.timestamp_eof = timestamp_eof
self.server.send(buf, &extra, False)
def start_listener(self):
self.server.start_listener()
def __dealloc__(self):
del self.server
2021-08-30 13:00:09 +08:00
cdef class VisionIpcClient:
cdef cppVisionIpcClient * client
cdef VisionIpcBufExtra extra
2021-08-30 13:00:09 +08:00
def __cinit__(self, string name, VisionStreamType stream, bool conflate, CLContext context = None):
if context:
self.client = new cppVisionIpcClient(name, stream, conflate, context.device_id, context.context)
else:
self.client = new cppVisionIpcClient(name, stream, conflate, NULL, NULL)
2021-08-30 13:00:09 +08:00
def __dealloc__(self):
del self.client
@property
def width(self):
return self.client.buffers[0].width if self.client.num_buffers else None
2021-08-30 13:00:09 +08:00
@property
def height(self):
return self.client.buffers[0].height if self.client.num_buffers else None
2021-09-02 06:13:05 +08:00
@property
def stride(self):
return self.client.buffers[0].stride if self.client.num_buffers else None
2021-08-30 13:00:09 +08:00
@property
def uv_offset(self):
return self.client.buffers[0].uv_offset if self.client.num_buffers else None
@property
def rgb(self):
return self.client.buffers[0].rgb if self.client.num_buffers else None
@property
def buffer_len(self):
return self.client.buffers[0].len if self.client.num_buffers else None
@property
def num_buffers(self):
return self.client.num_buffers
@property
def frame_id(self):
return self.extra.frame_id
@property
def timestamp_sof(self):
return self.extra.timestamp_sof
@property
def timestamp_eof(self):
return self.extra.timestamp_eof
@property
def valid(self):
return self.extra.valid
2021-08-30 13:00:09 +08:00
def recv(self, int timeout_ms=100):
buf = self.client.recv(&self.extra, timeout_ms)
if not buf:
2021-08-30 13:00:09 +08:00
return None
2023-07-25 14:59:08 +08:00
return VisionBuf.create(buf)
2021-08-30 13:00:09 +08:00
def connect(self, bool blocking):
return self.client.connect(blocking)
def is_connected(self):
return self.client.is_connected()
@staticmethod
def available_streams(string name, bool block):
return cppVisionIpcClient.getAvailableStreams(name, block)