Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 1 | from multiprocessing import Process, Queue |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 2 | |
| 3 | |
| 4 | class BaseCamera(object): |
Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 5 | process = {} # background process that reads frames from camera |
Shad Ansari | c9f48d3 | 2021-10-25 19:03:34 +0000 | [diff] [blame] | 6 | frame = {} # frame queue |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 7 | |
Shad Ansari | 60ca8cc | 2021-11-02 18:46:44 +0000 | [diff] [blame] | 8 | def __init__(self, device=None, idle=False): |
Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 9 | """Start the background camera process if it isn't running yet.""" |
Shad Ansari | c0726e6 | 2021-10-04 22:38:53 +0000 | [diff] [blame] | 10 | self.device = device |
Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 11 | if self.device not in BaseCamera.process: |
| 12 | BaseCamera.process[self.device] = None |
| 13 | if BaseCamera.process[self.device] is None: |
Shad Ansari | c9f48d3 | 2021-10-25 19:03:34 +0000 | [diff] [blame] | 14 | |
Shad Ansari | 60ca8cc | 2021-11-02 18:46:44 +0000 | [diff] [blame] | 15 | self.frame[device] = Queue(100) |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 16 | |
Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 17 | # start background frame process |
| 18 | BaseCamera.process[self.device] = Process(target=self._process, args=(self.device)) |
| 19 | BaseCamera.process[self.device].start() |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 20 | |
| 21 | # wait until frames are available |
Shad Ansari | 60ca8cc | 2021-11-02 18:46:44 +0000 | [diff] [blame] | 22 | _ = self.get_frame() |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 23 | |
| 24 | def get_frame(self): |
| 25 | """Return the current camera frame.""" |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 26 | |
Shad Ansari | 60ca8cc | 2021-11-02 18:46:44 +0000 | [diff] [blame] | 27 | # blocks |
| 28 | return BaseCamera.frame[self.device].get(block=True) |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 29 | |
Shad Ansari | 341ca3a | 2021-09-30 12:10:00 -0700 | [diff] [blame] | 30 | def frames(self): |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 31 | """"Generator that returns frames from the camera.""" |
Shad Ansari | 341ca3a | 2021-09-30 12:10:00 -0700 | [diff] [blame] | 32 | raise NotImplementedError('Must be implemented by subclasses.') |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 33 | |
Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 34 | def _process(self, device): |
| 35 | """Camera background process.""" |
Shad Ansari | 30a2373 | 2021-09-29 23:07:21 -0700 | [diff] [blame] | 36 | frames_iterator = self.frames() |
| 37 | for frame in frames_iterator: |
Shad Ansari | c9f48d3 | 2021-10-25 19:03:34 +0000 | [diff] [blame] | 38 | BaseCamera.frame[device].put(frame, block=True) |
Shad Ansari | 4ae1168 | 2021-10-22 18:51:53 +0000 | [diff] [blame] | 39 | |
Shad Ansari | 26682be | 2021-10-26 03:52:35 +0000 | [diff] [blame] | 40 | BaseCamera.process[device] = None |