mirror of https://github.com/commaai/cereal.git
169 lines
4.4 KiB
Cython
169 lines
4.4 KiB
Cython
# distutils: language = c++
|
|
# cython: c_string_encoding=ascii, language_level=3
|
|
|
|
import sys
|
|
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
|
|
from libcpp cimport bool
|
|
from libcpp.string cimport string
|
|
|
|
from .visionipc cimport VisionIpcServer as cppVisionIpcServer
|
|
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:
|
|
VISION_STREAM_ROAD
|
|
VISION_STREAM_DRIVER
|
|
VISION_STREAM_WIDE_ROAD
|
|
VISION_STREAM_MAP
|
|
|
|
|
|
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
|
|
|
|
|
|
cdef class VisionIpcClient:
|
|
cdef cppVisionIpcClient * client
|
|
cdef VisionIpcBufExtra extra
|
|
|
|
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)
|
|
|
|
def __dealloc__(self):
|
|
del self.client
|
|
|
|
@property
|
|
def width(self):
|
|
return self.client.buffers[0].width if self.client.num_buffers else None
|
|
|
|
@property
|
|
def height(self):
|
|
return self.client.buffers[0].height if self.client.num_buffers else None
|
|
|
|
@property
|
|
def stride(self):
|
|
return self.client.buffers[0].stride if self.client.num_buffers else None
|
|
|
|
@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
|
|
|
|
def recv(self, int timeout_ms=100):
|
|
buf = self.client.recv(&self.extra, timeout_ms)
|
|
if not buf:
|
|
return None
|
|
return VisionBuf.create(buf)
|
|
|
|
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)
|