So ... after two days and nights of intense hacking, the situation is as follows:
1. Memory consumption is probably at the root of the problem. I have already noticed that C7-00 and E7-00 have bigger problems than N701, and really: the former models do have 32 MB of dedicated graphical memory, while N701 has 128 MB. We'll definitely try to reduce consumption of graphical memory by our application (it is a hog, as it frequently paints huge SVGs).
2. This seems to be confirmed by further experiments: accessing the front camera, used for video-chats mainly, isn't problematic. This front camera has much lower resolution than the main camera, and thus probably lower memory footprint. I can already use the front camera on all devices I have at my disposal.
3. If the Reserve() failure occurs, for example, when accessing the main camera on C7-00, it does not occur immediately. Instead, the appropriate failure event is only thrown after some 10 seconds, which is a bit strange, and uncomfortable from the user's point of view.
4. Once you experience the Reserve() failure on C7-00, you may (but by no means will - the exact logic of appearance of this problem isn't clear to me) experience further problems regarding access to the CCamera API, up to entire bricking of the phone, when it becomes unresponsive until you take the battery out. I haven't dared reproducing this on E7-00, where the battery cover isn't removable...!
Consider this simple piece of code, which just accesses all cameras on the device, asks them for their camera info, and possibly stores the info for future use:
Code:
DestroyCameraObject();
TInt i, cameraCount = CCamera::CamerasAvailable();
for (i=0; i< cameraCount; i++)
{
TBool camCreated = AllocateCameraObjectL(i);
if (camCreated)
{
TCameraInfo info;
// Access the camera info.
iCamera->CameraInfo(info);
// Store the information for future use.
iCameraInfo.Append(info);
// Get rid of the camera object again.
DestroyCameraObject();
}
}
where the AllocateCameraObjectL method looks like this:
Code:
TBool CCamera2EntropySource::AllocateCameraObjectL(TInt aIndex)
{
TRAPD(err, iCamera = CCamera::New2L(*this, index, KDefaultCameraPriority));
if (err != KErrNone)
{
return EFalse;
}
return (iCamera != NULL);
}
and the DestroyCameraObject() looks like that:
Code:
void CCameraSymbianEntropySource::DestroyCameraObject()
{
if (iCamera)
{
delete iCamera;
iCamera = NULL;
}
}
Now, if something messes up in the camera API on C7-00, your application, and probably the entire phone, will sometimes hang on the line
Code:
iCamera = CCamera::New2L(*this, index, KDefaultCameraPriority);
regardless of presence of the TRAP, and you'll have to take the battery out to revive it again. This can be proven by introducing a text log file and flushing line after line, so that nothing stays in the disk cache.
I have a suspicion that something triggers an infinite loop in the system code, as this is how infinite loops usually demonstrate themselves (a plain mutex-based deadlock won't prevent other threads from execution).
The constant KDefaultCameraPriority is currently defined to 30, but I have experimented with values from 0 to 100, and they do not seem to influence the behavior at all.