def run(self): self.client = ShmemRGBClient( name=self.shmem_name, n_ringbuffer=self.shmem_n_buffer, width=self.width, height=self.height, # client timeouts if nothing has been received in 1000 milliseconds mstimeout=1000, verbose=False) while self.loop: """ print("Idling") time.sleep(1) """ #""" index, meta = self.client.pullFrameThread( ) # releases Python GIL while waiting for a frame if (index is None): # print(self.pre, "VideoShmemThread: client timed out..") pass else: # print(self.pre, "VideoShmemThread: client index, w, h =", index, meta.width, meta.height) data = self.client.shmem_list[index] img = data.reshape((meta.height, meta.width, 3)) pixmap = numpy2QPixmap(img) self.signals.pixmap.emit(pixmap) # """ print(self.pre, "exit")
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 run(self): self.client = ShmemRGBClient( name=self.shmem_name, n_ringbuffer=self.shmem_n_buffer, width=self.width, height=self.height, # client timeouts if nothing has been received in 1000 milliseconds mstimeout=1000, # mstimeout=100, verbose=False) while self.loop: """ print("Idling") time.sleep(1) """ # """ # print("pullFrameThread>") index, meta = self.client.pullFrameThread( # index, meta = self.client.pullFrame( ) # releases Python GIL while waiting for a frame # print("<pullFrameThread") if (index is None): # print(self.pre, "VideoShmemThread: client timed out..") pass else: # print(self.pre, "VideoShmemThread: client index, w, h =", index, meta.width, meta.height) data = self.client.shmem_list[index] # print(data[0:10]) self.img = data.copy().reshape((meta.height, meta.width, 3)) # print(img[0:10]) """WARNING - reshape does not necessarily create a copy of the data, but uses memview instead - imagine that a memview is passed donwstreams, where it eventually goes to another python thread - ..but in that pullFrameThread call above, we have released the GIL, so it migh happen that the cpp code is modifying the data while the downstream python thread is accessing it simultaneously and - ..crassssh """ """DEBUG: test without actually sending the object into Qt infrastructure # which one of these two lines is the problem? pixmap = numpy2QPixmap(img) self.signals.pixmap.emit(pixmap) """ # send numpy array into the signal/slot system # instead of QPixmap..? #""" self.signals.image.emit(self.img) #""" # could also just send the # index of the shmem array # & do everything at the canvas widget # # 1) 12h test without pixmap or signal # 1b) use here self.pixmap instead of pixmap, in order to keep the reference # https://wiki.python.org/moin/PyQt/Threading%2C_Signals_and_Slots # 2) 12h test sending the img # 3) 12h test sending the index only # # """ print(self.pre, "exit")
def create_client_(self): 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) self.postCreateClient_()
def preRun_(self): """Create the shared memory client after fork """ 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], mstimeout= 1000, # client timeouts if nothing has been received in 1000 milliseconds verbose=False)
def create_client_(self): print( "inside create_client of multiprocess \n shmem name is {} for process number " .format(self.shmem_name)) 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) self.postCreateClient_()
def activate_(self, n_buffer, image_dimensions, shmem_name): """Shared mem info is given. Now we can create the shmem client """ self.active = 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=1000, verbose=False) self.postActivate_()
def c__registerClient(self, n_buffer: int = None, image_dimensions: tuple = None, shmem_name: str = None, ipc_index: int = None): """Shared mem info is given. Now we can create the shmem client There can be several shmem clients """ self.logger.debug("c__registerClient") event_fd, pipe = singleton.ipc.get2(ipc_index) singleton.ipc.wait( ipc_index) # wait till the shmem server has been created # this flag is controlled by QShmemClientProcess.c__setMasterProcess singleton.ipc.clear(ipc_index) shmem_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=1000, verbose=False) shmem_client.useEventFd(event_fd) fd = event_fd.getFd() client = self.Client(fd=fd, pipe=pipe, shmem_client=shmem_client) self.clients[ipc_index] = client self.clients_by_fd[fd] = client self.logger.debug("c__registerClient: fd=%s", fd) self.rlis.append(fd) if len(self.clients) == 1: self.logger.debug("c__registerClient: first client registered") self.firstClientRegistered_() self.logger.debug("c__registerClient: number of clients is %s", len(self.clients))
def c__activateRGB24Client(self, name=None, n_ringbuffer=None, width=None, height=None, ipc_index=None ): """This will activate a shared memory client that reads RGB24 frames from shared memory libValkka c++ side (as defined in your filterchain) """ print("c__activateRGB24Client called with", name, n_ringbuffer, width, height) client = ShmemRGBClient( name=name, n_ringbuffer=n_ringbuffer, width=width, height=height, mstimeout=self.mstimeout, verbose=False ) eventfd = getEventFd(ipc_index) client.useEventFd(eventfd) # do not forget! # let's get a posix file descriptor, i.e. a plain integer: fd = eventfd.getFd() self.client_by_fd[fd] = client
The parameters used both in the server side (above) and on the client side (below) **must be exactly the same** and the client program should be started *after* the server program (and while the server is running). Otherwise undefined behaviour will occur. The used shmem_name(s) should be same in both server and client, but different for another server/client pair. <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, 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)])