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