Skip to content

Commit c713e49

Browse files
committed
fix camera stream frame timestamp issue for MS Windows + MacOS
1 parent e866f64 commit c713e49

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

camera_stream.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ def __init__(self, src=None, backend=None,
125125
# set these to null values initially
126126
self.grabbed = 0
127127
self.frame = None
128-
self.threadID = -1
129128

130129
# set the initial timestamps to zero
131130
self.timestamp = 0
132131
self.timestamp_last_read = 0
132+
self.use_timestamps = False
133133

134134
# set internal framecounters to -1
135135
self.framecounter = -1
@@ -142,20 +142,24 @@ def __init__(self, src=None, backend=None,
142142
# set some sensible backends for real-time video capture from
143143
# directly connected hardware on a per-OS basis,
144144
# that can we overidden via the open() method
145+
# + remember timestamps only seem to work on linux
145146
if sys.platform.startswith('linux'): # all Linux
146147
self.backend_default = cv2.CAP_V4L
148+
self.use_timestamps = True
147149
elif sys.platform.startswith('win'): # MS Windows
148150
self.backend_default = cv2.CAP_DSHOW
151+
self.use_timestamps = False
149152
elif sys.platform.startswith('darwin'): # macOS
150153
self.backend_default = cv2.CAP_AVFOUNDATION
154+
self.use_timestamps = False
151155
else:
152156
self.backend_default = cv2.CAP_ANY # auto-detect via OpenCV
153157

154158
# if a source was specified at init, proceed to open device
155159
if not (src is None):
156160
self.open(src, backend)
157161

158-
def open(self, src, backend=None):
162+
def open(self, src=0, backend=None):
159163

160164
# determine backend to specified by user
161165
if (backend is None):
@@ -177,8 +181,8 @@ def open(self, src, backend=None):
177181
(self.grabbed, self.frame) = self.camera.read()
178182
self.timestamp = self.camera.get(cv2.CAP_PROP_POS_MSEC)
179183
self.framecounter += 1
180-
logging.info("CAM %d - GRAB - frame %d @ time %f",
181-
self.threadID, self.framecounter, self.timestamp)
184+
logging.info("GRAB - frame %d @ time %f",
185+
self.framecounter, self.timestamp)
182186

183187
# only start the thread if in-fact the camera read was successful
184188
if (self.grabbed):
@@ -213,19 +217,18 @@ def update(self):
213217
if not (self.suspend):
214218
self.camera.grab()
215219
latest_timestamp = self.camera.get(cv2.CAP_PROP_POS_MSEC)
216-
if (latest_timestamp > self.timestamp):
220+
if ((latest_timestamp > self.timestamp)
221+
or (self.use_timestamps is False)):
217222
(self.grabbed, self.frame) = self.camera.retrieve()
218223
self.framecounter += 1
219-
logging.info("CAM %d - GRAB - frame %d @ time %f",
220-
self.threadID, self.framecounter,
221-
latest_timestamp)
222-
logging.debug("CAM %d - GRAB - inter-frame diff (ms) %f",
223-
self.threadID,
224+
logging.info("GRAB - frame %d @ time %f",
225+
self.framecounter, latest_timestamp)
226+
logging.debug("GRAB - inter-frame diff (ms) %f",
224227
latest_timestamp - self.timestamp)
225228
self.timestamp = latest_timestamp
226229
else:
227-
logging.info("CAM %d - GRAB - same timestamp skip %d",
228-
self.threadID, latest_timestamp)
230+
logging.info("GRAB - same timestamp skip %d",
231+
latest_timestamp)
229232

230233
def grab(self):
231234
# return status of most recent grab by the thread
@@ -245,11 +248,11 @@ def read(self):
245248
self.framecounter_last_read = self.framecounter
246249

247250
for skip in range(1, frame_offset):
248-
logging.info("CAM %d - SKIP - frame %d", self.threadID,
249-
self.framecounter_last_read - frame_offset + skip)
251+
logging.info("SKIP - frame %d", self.framecounter_last_read
252+
- frame_offset + skip)
250253

251-
logging.info("CAM %d - READ - frame %d @ time %f",
252-
self.threadID, self.framecounter, self.timestamp)
254+
logging.info("READ - frame %d @ time %f",
255+
self.framecounter, self.timestamp)
253256

254257
# return the frame most recently read
255258
if (self.tapi):
@@ -285,7 +288,7 @@ def set(self, property_name, property_value):
285288
(self.grabbed, self.frame) = self.camera.read()
286289
self.timestamp = self.camera.get(cv2.CAP_PROP_POS_MSEC)
287290
self.framecounter += 1
288-
logging.info("CAM %d - GRAB - frame %d @ time %f", self.threadID,
291+
logging.info("GRAB - frame %d @ time %f",
289292
self.framecounter, self.timestamp)
290293

291294
# restart thread by unsuspending it

0 commit comments

Comments
 (0)