diff --git a/dshowcapture.py b/dshowcapture.py index 7b9706e..f91650f 100644 --- a/dshowcapture.py +++ b/dshowcapture.py @@ -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__": diff --git a/dshowcapture/dshowcapture_x64.dll b/dshowcapture/dshowcapture_x64.dll index 95c28a2..eb8a233 100644 Binary files a/dshowcapture/dshowcapture_x64.dll and b/dshowcapture/dshowcapture_x64.dll differ diff --git a/dshowcapture/dshowcapture_x86.dll b/dshowcapture/dshowcapture_x86.dll index 6ea61db..5cb2b62 100644 Binary files a/dshowcapture/dshowcapture_x86.dll and b/dshowcapture/dshowcapture_x86.dll differ