I am trying to implement in MonoTouch the ability to record video with high frame rates (available since iOS 7). Following Apple documentation, we are enumerating the available video formats like this:
AV.AVCaptureDeviceFormat highSpeedFormat = null;
m_captureSession.BeginConfiguration();
double requestedFrameRate = 120;
for (int i = 0; i < avVideoCaptureDevice.Formats.Length; i++)
{
AV.AVCaptureDeviceFormat format = avVideoCaptureDevice.Formats[i];
CM.CMFormatDescription fd = format.FormatDescription;
Media.Logger.Log(string.Format("format = {0}", format));
Media.Logger.Log(string.Format("dim = {0}x{1}", fd.VideoDimensions.Width, fd.VideoDimensions.Height));
for (int j = 0; j < format.VideoSupportedFrameRateRanges.Length; j++)
{
AV.AVFrameRateRange range = format.VideoSupportedFrameRateRanges[j];
Media.Logger.Log(string.Format(" range: {0}", range));
if (System.Math.Abs(requestedFrameRate - range.MaxFrameRate) <= 1.0 && fd.VideoDimensions.Width == 1280)
{
Media.Logger.Log(">>>> found a matching format");
highSpeedFormat = format;
}
}
}
Once we have found the desired high frame rate format, we set it to the video capture device like this:
if (highSpeedFormat != null)
{
NS.NSError error;
avVideoCaptureDevice.LockForConfiguration(out error);
avVideoCaptureDevice.ActiveFormat = highSpeedFormat;
CM.CMTime frameDuration = new CM.CMTime(1,requestedFrameRate);
avVideoCaptureDevice.ActiveVideoMaxFrameDuration = frameDuration;
avVideoCaptureDevice.UnlockForConfiguration();
}
This code works fine on iPhone 5 and we can record 60fps video on this device. However, on iPhone 5S, it crashes most of the time at the following line:
avVideoCaptureDevice.ActiveFormat = highSpeedFormat;
Stack trace:
0 libsystem_kernel.dylib 0x39ea41fc __pthread_kill + 8
1 libsystem_pthread.dylib 0x39f0ba4f pthread_kill + 55
2 libsystem_c.dylib 0x39e55029 abort + 73
3 EasyCaptureMonoTouch 0x0161ff8d 0x27000 + 23039885
4 EasyCaptureMonoTouch 0x0162a9fd 0x27000 + 23083517
5 libsystem_platform.dylib 0x39f06721 _sigtramp + 41
6 CoreFoundation 0x2f4c4b9b CFEqual + 231
7 CoreMedia 0x2fae1a07 CMFormatDescriptionEqual + 23
8 AVFoundation 0x2e4d7b6d -[AVCaptureDeviceFormat isEqual:] + 105
9 CoreFoundation 0x2f4cf9ef -[NSArray containsObject:] + 163
10 AVFoundation 0x2e48d69f -[AVCaptureFigVideoDevice setActiveFormat:] + 143
Sometimes, the crash occurs later with a similar stack trace (during recording, setActiveFormat
is in also called) :
0 libsystem_kernel.dylib 0x39a641fc __pthread_kill + 8
1 libsystem_pthread.dylib 0x39acba4f pthread_kill + 55
2 libsystem_c.dylib 0x39a15029 abort + 73
3 EasyCaptureMonoTouch 0x017a5685 0xec000 + 23828101
4 EasyCaptureMonoTouch 0x017b00f5 0xec000 + 23871733
5 libsystem_platform.dylib 0x39ac6721 _sigtramp + 41
6 libobjc.A.dylib 0x394b59d7 realizeClass(objc_class*) + 219
7 libobjc.A.dylib 0x394b59d7 realizeClass(objc_class*) + 219
8 libobjc.A.dylib 0x394b7793 lookUpImpOrForward + 71
9 libobjc.A.dylib 0x394b0027 _class_lookupMethodAndLoadCache3 + 31
10 libobjc.A.dylib 0x394afdf7 _objc_msgSend_uncached + 23
11 CoreFoundation 0x2f084b9b CFEqual + 231
12 CoreMedia 0x2f6a1a07 CMFormatDescriptionEqual + 23
13 AVFoundation 0x2e097b6d -[AVCaptureDeviceFormat isEqual:] + 105
14 CoreFoundation 0x2f08f9ef -[NSArray containsObject:] + 163
15 AVFoundation 0x2e04d69f -[AVCaptureFigVideoDevice setActiveFormat:] + 143
16 Foundation 0x2faa5149 _NSSetObjectValueAndNotify + 93
17 AVFoundation 0x2e04d2ef -[AVCaptureFigVideoDevice _setActiveFormatAndFrameRatesForResolvedOptions:sendingFrameRatesToFig:] + 91
18 AVFoundation 0x2e06245d -[AVCaptureSession _buildAndRunGraph] + 365
19 AVFoundation 0x2e05c23b -[AVCaptureSession addInput:] + 899
We are suspecting a implementation mistake in the MonoTouch bindings or maybe a misconfiguration / 64 bits issues? Someone has an idea ?