1

I have the following issue with live view with my python ctypes interface to Canon EDSDK version 13.11.10 for windows 10: EdsDownloadEvfImage call takes about 2.6 secs. I am not sure how to improve the speed since this is a call to EDSDK function.

Below is some timing info for the different functions called during download. These are called after receiving notification for change of display to PC. These tests were done on a Canon EOS Rebel SL3.

downloadEvfData: EdsCreateMemoryStream ok. time: 0.000
downloadEvfData: EdsCreateEvfImageRef ok. time: 0.000
downloadEvfData: EdsDownloadEvfImage ok, time: 2.589
downloadEvfData: Length Ok = c_ulonglong(160035)
downloadEvfData: Get length ok. time: 0.002
downloadEvfData: Get pointer ok. time: 0.000
downlaodEvfData: copy bytes time: 0.000
downloadEvfData: full fn time: 2.598


downloadEvfData: EdsCreateMemoryStream ok. time: 0.000
downloadEvfData: EdsCreateEvfImageRef ok. time: 0.000
downloadEvfData: EdsDownloadEvfImage ok, time: 2.587
downloadEvfData: Length Ok = c_ulonglong(159924) 
downloadEvfData: Get length ok. time: 0.002
downloadEvfData: Get pointer ok. time: 0.001
downlaodEvfData: copy bytes time: 0.000
downloadEvfData: full fn time: 2.596

Once I get the notification for evf output change to PC - I start spawning threads at about the desired frame rate to start download process - the following functions are called for each frame of live data {get stream, get evf image reference, download evf image, get evf related parameters like zoom values, get length, get pointer, release evf image ref, release stream.}

I can't seem to do any better than 2-3 fps.

Below is a sample code from my download function using the Canon EDSDK version 13.11.10 for windows 10:

from ctypes import *

err = c_int32(-1)        
evfStream = c_void_p()
evfImageRef = c_void_p()

err = self.EDSDK64Dll.EdsCreateMemoryStream(0, byref(evfStream))

err = self.EDSDK64Dll.EdsCreateEvfImageRef(evfStream, byref(evfImageRef))

err = self.EDSDK64Dll.EdsDownloadEvfImage(inCameraRef, evfImageRef)

outLength = c_uint64(0)
err = self.EDSDK64Dll.EdsGetLength(evfStream, byref(outLength))

image_data = (c_ubyte * outLength.value)()
p_image_data = (POINTER(c_ubyte))(image_data)
# get the pointer to the starting memory location of the stream
err = self.EDSDK64Dll.EdsGetPointer(evfStream, byref(p_image_data))

# copy over the data from obtained location of image_data
# check if ctypes string_at can be used to speed up copy
arr_bytes = bytearray(string_at(p_image_data, outLength.value)) 

im = (Image.open(io.BytesIO(arr_bytes))).transpose(Image.FLIP_LEFT_RIGHT) # PIL image

A C# sample for live view works at a much faster frame rate on the same PC using the same EDSDK.

aviimaging
  • 157
  • 10
  • it sounds like you are spawning multiple threads, one for each frame. if that's the case it's not surprising it's slow. you should have one thread that downloads frames in a loop. – Johannes Bildstein Feb 14 '20 at 12:53
  • @JohannesBildstein Thanks for your comment. Let's think through what you suggest. If i have just one thread download all frames sequentially then with the delay on the EDSDK C++ call EdsDownloadEvfImage time: 2.587 secs for each frame, it makes my frame rate only worse since they will be spaced out at least by that amount of time. I have tried a single thread before moving to multi-threaded approach so I know that this is true. Also this question is primarily about the time the C++ EDSDK call takes - the lower frame rate I believe is a by product of that. – aviimaging Feb 14 '20 at 16:53
  • ..and of course something else that I am doing wrong obviously. – aviimaging Feb 14 '20 at 17:00
  • that logic would be correct but the problem is that only one thread can ever call EdsDownloadEvfImage at the same time. So while one thread is downloading a frame, all other threads are waiting for that one to finish. In any case, the slowness may also be caused by hardware. did you try to use a different USB cable any/or port? – Johannes Bildstein Feb 14 '20 at 19:44
  • @JohannesBildstein I agree it makes sense that if there are multiple threads then may be there is a contention at some point between these threads with the camera resource !? But I am not sure then why I do see the same lag and low frame rate with a single thread version and how to resolve it. Will check one more time anyways. Yes, have tried different USB cables and ports and get similar timing issue. And used same setup with C-Sharp version which works with about 0.5 sec lag and very descent frame rate. Thanks for getting back. – aviimaging Feb 14 '20 at 21:44
  • I'm afraid I'm out of ideas then. I don't know much about Python so there may well be some magic behind the scenes that slows things down but it sounds strange. Are other calls slow too? e.g. when downloading a photo. – Johannes Bildstein Feb 18 '20 at 08:54
  • @JohannesBildstein your C Sharp tutorial and related library has been very helpful. - https://www.codeproject.com/Articles/688276/Canon-EDSDK-Tutorial-in-Csharp . Thank you for that. It looks like your C Sharp library/samples and pyedsdk are the only options out there to get Canon edsdk to work satisfying its STA requirements. I haven't yet got the python route working though. – aviimaging Feb 23 '20 at 04:04
  • @aviimaging Did you manage to solve this? – tpag26 Aug 15 '21 at 07:12
  • Hi @tpag26, I haven't been able to solve the python route yet. I moved over to C Sharp and haven't looked back at the python issues since. – aviimaging Aug 31 '21 at 14:19

0 Answers0