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, meta = client.pullFrame() # index, meta = client.pullFrameThread() # alternative method for multithreading if index is None: print("timeout") else: data = client.shmem_list[index][0:meta.size] print("data : ",data[0:min(10,meta.size)]) print("width : ", meta.width) print("height : ", meta.height) print("slot : ", meta.slot) print("time : ", meta.mstimestamp) print("size required : ", meta.width * meta.height * 3) print("size copied : ", meta.size) print()
class QShmemProcess(QMultiProcess): """A multiprocess with Qt signals and reading RGB images from shared memory. Shared memory client is instantiated on demand (by calling activate) """ timeout = 1.0 class Signals(QtCore.QObject): pong = QtCore.Signal(object) # demo outgoing signal # **** define here backend methods that correspond to incoming slots # **** def c__ping(self, message=""): print("c__ping:", message) self.send_out__(MessageObject("pong", lis=[1, 2, 3])) def c__activate(self, n_buffer: int = None, image_dimensions: tuple = None, shmem_name: str = None): # if not defined, use default values # if n_buffer is None: n_buffer = self.n_buffer # if image_dimensions is None: image_dimensions = self.image_dimensions # if shmem_name is None: shmem_name = self.shmem_name self.logger.debug("c__activate") self.listening = True # self.image_dimensions = image_dimensions self.client = ShmemRGBClient( name=shmem_name, n_ringbuffer=n_buffer, # size of ring buffer width=image_dimensions[0], height=image_dimensions[1], # client timeouts if nothing has been received in 1000 milliseconds mstimeout=int(self.timeout * 1000), verbose=self.shmem_verbose) self.shmem_name = shmem_name self.n_buffer = n_buffer self.image_dimensions = image_dimensions self.postActivate_() def c__deactivate(self): """Init shmem variables to None """ self.logger.debug("c__deactivate") self.preDeactivate_() self.listening = False # self.image_dimensions = None self.client = None # shared memory client created when activate is called # **** parameter_defs = { # "n_buffer" : (int, 10), # "image_dimensions" : (tuple, (1920//4, 1080//4)), # "image_dimensions" : tuple, "shmem_verbose": (bool, False), # "shmem_name" : None } def __init__(self, name="QShmemProcess", **kwargs): super().__init__(name) parameterInitCheck(QShmemProcess.parameter_defs, kwargs, self) """ if self.shmem_name is None: self.shmem_name = "valkkashmemclient"+str(id(self)) else: assert(isinstance(self.shmem_name, str)) self.shmem_name_default = self.shmem_name """ def preRun_(self): self.logger.debug("preRun_") self.c__deactivate() # init variables def postRun_(self): """Clear shmem variables """ self.c__deactivate() def run(self): self.preRun_() while self.loop: if self.listening: self.cycle_() self.readPipes__(timeout=0) # timeout = 0 == just poll else: self.readPipes__(timeout=self.timeout) # timeout of 1 sec self.postRun_() # indicate front end qt thread to exit self.back_pipe.send(None) self.logger.debug("bye!") def cycle_(self): """Receives frames from the shmem client and does something with them Typically launch qt signals """ index, meta = self.client.pullFrame() if (index is None): self.logger.debug("Client timed out..") return self.logger.debug("Client index = %s", index) if meta.size < 1: return data = self.client.shmem_list[index][0:meta.size] img = data.reshape((meta.height, meta.width, 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) """ self.logger.debug("got frame %s", img.shape) # res=self.analyzer(img) # does something .. returns something .. def postActivate_(self): """Whatever you need to do after creating the shmem client. Overwrite in child classes """ pass def preDeactivate_(self): """Whatever you need to do prior to deactivating the shmem client. Overwrite in child classes """ pass # *** frontend *** def activate(self, **kwargs): # save values to front-end also: self.shmem_name = kwargs["shmem_name"] self.n_buffer = kwargs["n_buffer"] self.image_dimensions = kwargs["image_dimensions"] # this sets the values at back-end: self.sendMessageToBack(MessageObject("activate", **kwargs)) def deactivate(self): self.sendMessageToBack(MessageObject("deactivate")) def ping(self, message=""): """Test call """ self.sendMessageToBack(MessageObject("ping", message=message))