I've found something quite odd about QTCaptureSession. My app is a
Java app using native methods (JNI) to access QuickTime. On Leopard
the current JVM (1.5) is normally run as a 32-bit process (although
it can be run as 64-bit). The "new" JVM (1.6) is 64-bit only, but
is not yet the default JVM, although Apple is expected to make it
the default relatively soon. As a result, I need to build my native
library to run in both 32-bit and 64-bit processes. I wrote an
Objective-C class to manage the process, it has instance variables
for the QTCaptureSession, QTCaptureInput,
QTCaptureVideoPreviewOutput, and a buffer where I blit frame data
to in my
captureOutput:didOutputVideoFrame:withSampleBuffer:fromConnection
delegate method.
I have found that QTCaptureSession stopRunning has some odd
behaviour when run in 32-bit mode only. Specifically, I have found
that when:
- the QTCaptureDevice is a UVC camera, and
- the code is run in a 32-bit process, and
- the device is the input of a running QTCaptureSession, and
- my code calls stopRunning before removing the session input, and
- I later restart the session (after adding an input back in)
frame data being fed to my output delegate method arrives very
slowly -- it is like the frames are still being captured at 30 FPS,
but I'm getting them initially at about 3-5 FPS, but quickly
dropping off to less than 1 FPS. After about 15-30 seconds of this
the rate recovers, but it remains behind by the time spent in this
odd mode. I found that even if I removed everything from the
session, closed the input device and released all the QTKit
objects, and created a new session, input and output, it still
exhibited the same odd behaviour. The FireWire iSight does not
exhibit this behaviour, only UVC cameras (and all 4 UVC cameras I
tried behaved the same). I found that unplugging the UVC camera and
plugging it back in caused a QTCaptureSession that had been
exhibiting this behaviour to behave as if the QTCaptureSession had
never been opened, but after stopping the QTCaptureSession and
restarting it (i.e. stopRunning, removeInput, wait, addInput,
startRunning) the dropped back to a crawl again.
Changing my code to remove the input before stopping the session
rectified the issue, i.e.:
[session stopSession];
[session removeInput:input];
[[input device] close];
[input release];
input = nil;
exhibits the problem, but:
[session removeInput:input];
[[input device] close];
[input release];
input = nil;
[session stopSession];
does not exhibit the problem. Is this order dependence expected?
And why do 32-bit and 64-bit processes differ in this regard?