<rtf>""" from valkka.api2 import ShmemRGBClient width = 1920 // 4 height = 1080 // 4 shmem_name = "lesson_4" # This identifies posix shared memory - must be same as in the server side shmem_buffers = 10 # Size of the shmem ringbuffer client = ShmemRGBClient( name=shmem_name, n_ringbuffer=shmem_buffers, width=width, height=height, mstimeout= 1000, # client timeouts if nothing has been received in 1000 milliseconds verbose=False) """<rtf> The *mstimeout* defines the semaphore timeout in milliseconds, i.e. the time when the client returns even if no frame was received: <rtf>""" while True: index, isize = client.pull() if (index == None): print("timeout") else: data = client.shmem_list[index][0:isize] print("got data: ", data[0:min(10, isize)]) """<rtf> The *client.shmem_list* is a list of numpy arrays, while *isize* defines the extent of data in the array. This example simply prints out the first ten bytes of the RGB image. </rtf>"""
class QValkkaShmemProcess(ValkkaProcess): """A multiprocess with Qt signals and reading RGB images from shared memory """ incoming_signal_defs = { # each key corresponds to a front- and backend methods "test_": { "test_int": int, "test_str": str }, "stop_": [], "ping_": { "message": str } } outgoing_signal_defs = {"pong_o": {"message": str}} # For each outgoing signal, create a Qt signal with the same name. The # frontend Qt thread will read processes communication pipe and emit these # signals. class Signals(QtCore.QObject): # pong_o =QtCore.pyqtSignal(object) pong_o = QtCore.Signal(object) parameter_defs = { "n_buffer": (int, 10), "image_dimensions": tuple, "shmem_name": str, "verbose": (bool, False) } def __init__(self, name, affinity=-1, **kwargs): super().__init__(name, affinity, **kwargs) self.signals = self.Signals() parameterInitCheck(QValkkaShmemProcess.parameter_defs, kwargs, self) typeCheck(self.image_dimensions[0], int) typeCheck(self.image_dimensions[1], int) def report(self, *args): if (self.verbose): print(self.pre, *args) def preRun_(self): """Create the shared memory client immediately after fork """ self.report("preRun_") super().preRun_() self.client = ShmemRGBClient( name=self.shmem_name, n_ringbuffer=self.n_buffer, # size of ring buffer width=self.image_dimensions[0], height=self.image_dimensions[1], # client timeouts if nothing has been received in 1000 milliseconds mstimeout=1000, verbose=False) def cycle_(self): index, isize = self.client.pull() if (index is None): print(self.pre, "Client timed out..") else: print(self.pre, "Client index, size =", index, isize) data = self.client.shmem_list[index] img = data.reshape( (self.image_dimensions[1], self.image_dimensions[0], 3)) """ # WARNING: the x-server doesn't like this, i.e., we're creating a window from a separate python multiprocess, so the program will crash print(self.pre,"Visualizing with OpenCV") cv2.imshow("openCV_window",img) cv2.waitKey(1) """ print(self.pre, ">>>", data[0:10]) # res=self.analyzer(img) # does something .. returns something .. # *** backend methods corresponding to incoming signals *** def stop_(self): self.running = False def test_(self, test_int=0, test_str="nada"): print(self.pre, "test_ signal received with", test_int, test_str) def ping_(self, message="nada"): print(self.pre, "At backend: ping_ received", message, "sending it back to front") self.sendSignal_(name="pong_o", message=message) # ** frontend methods launching incoming signals def stop(self): self.sendSignal(name="stop_") def test(self, **kwargs): dictionaryCheck(self.incoming_signal_defs["test_"], kwargs) kwargs["name"] = "test_" self.sendSignal(**kwargs) def ping(self, **kwargs): dictionaryCheck(self.incoming_signal_defs["ping_"], kwargs) kwargs["name"] = "ping_" self.sendSignal(**kwargs) # ** frontend methods handling received outgoing signals *** def pong_o(self, message="nada"): print(self.pre, "At frontend: pong got message", message) ns = Namespace() ns.message = message self.signals.pong_o.emit(ns)