Fixed underlying camera reliability issues.

This commit is contained in:
Emiliana 2020-08-08 14:59:00 +02:00
parent b29ecbc059
commit 1d662f723f
3 changed files with 57 additions and 12 deletions

View file

@ -12,12 +12,6 @@ def resolve(name):
lib = None
# int DSHOWCAPTURE_EXPORT get_frame(void *cap, int timeout, unsigned char *buffer, int size);
# void DSHOWCAPTURE_EXPORT stop_capture(void *cap);
# void DSHOWCAPTURE_EXPORT destroy_capture(void *cap);
# int DSHOWCAPTURE_EXPORT capturing(void *cap);
# void DSHOWCAPTURE_EXPORT lib_test(int n, int width, int height, int fps);
def create_frame_buffer(width, height):
buffer = bytearray(width * height * 4)
char_array = c_char * len(buffer)
@ -37,20 +31,24 @@ class DShowCapture():
lib.get_devices.argtypes = [c_void_p]
lib.get_device.argtypes = [c_void_p, c_int, c_char_p, c_int]
lib.capture_device.argtypes = [c_void_p, c_int, c_int, c_int, c_int]
lib.capture_device_default.argtypes = [c_void_p, c_int]
lib.get_width.argtypes = [c_void_p]
lib.get_height.argtypes = [c_void_p]
lib.get_fps.argtypes = [c_void_p]
lib.get_flipped.argtypes = [c_void_p]
lib.get_colorspace.argtypes = [c_void_p]
lib.capturing.argtypes = [c_void_p]
lib.get_frame.argtypes = [c_void_p, c_int, c_char_p, c_int]
lib.get_size.argtypes = [c_void_p]
lib.stop_capture.argtypes = [c_void_p]
lib.destroy_capture.argtypes = [c_void_p]
lib.capturing.argtypes = [c_void_p]
self.lib = lib
self.cap = lib.create_capture()
self.name_buffer = create_string_buffer(255);
self.buffer = None
self.have_devices = False
self.size = None
self.real_size = None
def __del__(self):
if not self.buffer is None:
@ -75,8 +73,28 @@ class DShowCapture():
self.width = self.get_width()
self.height = self.get_height()
self.flipped = self.get_flipped()
self.colorspace = self.get_colorspace()
self.size = self.width * self.height * 4
self.buffer = create_frame_buffer(self.width, self.height)
else:
self.size = None
self.real_size = None
return ret;
def capture_device_default(self, cam):
if not self.have_devices:
self.get_devices()
ret = self.lib.capture_device_default(self.cap, cam) == 1
if ret:
self.width = self.get_width()
self.height = self.get_height()
self.flipped = self.get_flipped()
self.colorspace = self.get_colorspace()
self.size = self.width * self.height * 4
self.buffer = create_frame_buffer(self.width, self.height)
else:
self.size = None
self.real_size = None
return ret;
def get_width(self):
@ -95,19 +113,44 @@ class DShowCapture():
return self.lib.get_colorspace(self.cap)
def capturing(self):
return self.lib.capturing(self.cap)
return self.lib.capturing(self.cap) == 1
def get_frame(self, timeout):
if self.size is None:
return None
if self.lib.get_frame(self.cap, timeout, self.buffer, self.size) == 0:
return None
img = Image.frombuffer('RGBA', (self.width, self.height), self.buffer, 'raw', 'BGRA', 0, 1)
img = np.array(img)
img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR);
if not self.flipped:
if self.real_size is None:
self.real_size = self.lib.get_size(self.cap)
img = np.frombuffer(self.buffer, dtype=np.uint8)[0:self.real_size]
if self.colorspace in [100, 101]:
img = cv2.cvtColor(img.reshape((self.height,self.width,4)), cv2.COLOR_BGRA2BGR);
if not self.flipped:
img = cv2.flip(img, 0)
return img
elif self.colorspace == 200:
img = cv2.cvtColor(img.reshape((3 * self.height // 2,self.width,1)), cv2.COLOR_YUV2BGR_I420);
elif self.colorspace == 201:
img = cv2.cvtColor(img.reshape((3 * self.height // 2,self.width,1)), cv2.COLOR_YUV2BGR_NV12);
elif self.colorspace == 202:
img = cv2.cvtColor(img.reshape((3 * self.height // 2,self.width,1)), cv2.COLOR_YUV2BGR_YV12);
elif self.colorspace == 203:
img = cv2.cvtColor(img.reshape((self.height,self.width,1)), cv2.COLOR_GRAY2BGR);
elif self.colorspace == 300:
img = cv2.cvtColor(img.reshape((self.height,self.width,2)), cv2.COLOR_YUV2BGR_YVYU);
elif self.colorspace == 301:
img = cv2.cvtColor(img.reshape((self.height,self.width,2)), cv2.COLOR_YUV2BGR_YUY2);
elif self.colorspace == 302:
img = cv2.cvtColor(img.reshape((self.height,self.width,2)), cv2.COLOR_YUV2BGR_UYVY);
elif self.colorspace == 303:
return None
if self.flipped:
img = cv2.flip(img, 0)
return img
def stop_capture(self):
self.size = None
self.real_size = None
return self.lib.stop_capture(self.cap)
def destroy_capture(self):
@ -115,6 +158,8 @@ class DShowCapture():
return 0
ret = self.lib.destroy_capture(self.cap)
self.cap = None
self.size = None
self.real_size = None
return ret
if __name__ == "__main__":