Basics
Trying to capture video from Logitech Brio camera (can support up to 60fps at 1080p -- tested in VLC), but I cannot seem to be able to get higher than 30 fps by using OpenCV VideoCapture.
My System & Settings
Info about what I have and work with:
- Camera: Logitech Brio
 - Language: python
 - opencv version: 4.0
 - Windows 10 with powershell (this is needed because my main program interacts with other windows-based applications)
 
Codec-related settings:
- Fourcc = MJPEG (as other ones don't support the resolutions I need for my camera for some reason)
 - the following code is used to open the camera: 
cv2.VideoCapture(cv2.CAP_DSHOW + 1) 
Some background and Code
I have used a threading approach, as suggested here: OpenCV VideoCapture lag due to the capture buffer
Basically my current code has 2 threads: 1 for the grab() function, and 1 for the retrieve() function and saving the retrieved image as an avi.
the thread that runs the grab() function looks something like this:
def __frame_grab_worker(self, cap, cameraNumber):
    try:
        while(cap.isOpened()):
            # sync with retrieve
            acquired = self._retrievingLock[cameraNumber].acquire()
            try:
                cap.grab()
            finally:
                self._retrievingLock[cameraNumber].release()
            if(self.interrupt == True):
                break
    finally:
        self._cleanupLock.release()
the thread that retrieves the image and saves it looks something like this:
def __record(self, filename, vidWidth, vidHeight, fps, cap, cameraNumber):
    if(self.numberOfCams > 0):
        fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
        out = cv2.VideoWriter(filename, fourcc , fps, (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))
        while(cap.isOpened()):
            self._retrievingLock[cameraNumber].acquire()
            ret, frame = cap.retrieve()
            self._retrievingLock[cameraNumber].release()
            if ret ==True:
                if(self.recordingFlag==True):
                    out.write(frame)
                cv2.imshow(str(cameraNumber), frame)
                # stop if interrupt flag presented
                if cv2.waitKey(1) & self.interrupt == True:
                    break
        cap.release()
        out.release()
        cv2.destroyAllWindows()
Things I've tried
I profiled my code. In general, between each loop of the while look in __record there is about 0.03 sec delay, which is equal to 30 fps. This is equally split between cap.retrieve() and the write and imshow functions.
I noticed that if I comment out the parts of the code that do any processing on the retrieved image (i.e. out.write(frame) or cv2.imshow(...) ) the time taken for the cap.retrieve() function increases to 0.03 (from previously around 0.15). 
So I assume that the problem is to do with either DSHOW with MJPEG not allowing more than 30fps, or a problem with the underlying opencv codes.
I further looked over the opencv codebase (specifically videoio/src/cap_dshow.cpp & videoio/src/cap.cpp) and couldn't find anything useful... I might have missed something.
If anyone has a solution or know anything that could help I would appreciate it Thanks in advance :)