blob: fd4d653b5a4c2374ebe7a5ff1dd49a211ff0b4c1 [file] [log] [blame]
from multiprocessing import Process, Queue
class BaseCamera(object):
process = {} # background process that reads frames from camera
frame = {} # frame queue
last_frame = {}
def __init__(self, device):
"""Start the background camera process if it isn't running yet."""
self.device = device
BaseCamera.last_frame[self.device] = None
if self.device not in BaseCamera.process:
BaseCamera.process[self.device] = None
if BaseCamera.process[self.device] is None:
BaseCamera.frame[device] = Queue(100)
# start background frame process
BaseCamera.process[self.device] = Process(target=self._process, args=(self.device))
BaseCamera.process[self.device].start()
# wait until frames are available
BaseCamera.last_frame[self.device] = self.get_frame()
def get_frame(self):
"""Return the current camera frame."""
if BaseCamera.last_frame[self.device] is None:
BaseCamera.last_frame[self.device] = BaseCamera.frame[self.device].get(block=True)
return BaseCamera.last_frame[self.device]
elif not BaseCamera.frame[self.device].empty():
BaseCamera.last_frame[self.device] = BaseCamera.frame[self.device].get()
return BaseCamera.last_frame[self.device]
else:
return BaseCamera.last_frame[self.device]
def frames(self):
""""Generator that returns frames from the camera."""
raise NotImplementedError('Must be implemented by subclasses.')
def _process(self, device):
"""Camera background process."""
frames_iterator = self.frames()
for frame in frames_iterator:
BaseCamera.frame[device].put(frame, block=True)
BaseCamera.process[device] = None