This article is intended for readers suffering from the narrow field-of-view of iPhones starting with the iPhone 4 and for programmers offering any kind of video recording in their apps.
As you may know already, recent iDevices use image stabilization during video recording. Unfortunately, not even the latest-and-greatest iPhone 5 has optical stabilization, only electronic, unlike the Nokia Lumia 92x. This, unfortunately, means part of the sensor is used for the stabilization itself, further narrowing the already limited field-of-view (FOV). I recommend you watch engadget's iPhone 5 vs. Nokia Lumia 920 videos so you can see how immensely better optical stabilization is.
If you use Apple's built-in stock Camera app, it will always use image stabilization and can't be disabled, even if you don't need it when, for example, shooting video from a tripod. This means you will unnecessarily reserve the outer 10 percent of pixels of the sensor for image stabilization in both dimensions. Let me show you two direct video framegrabs showing the difference:
(IS enabled. As with most images in this article, click for the original version.)
(IS disabled. Note that in both dimensions, its showing 10 percent larger area.)
Both framegrabs are taken from video footage recorded by my own open-source video recorder client (see below) from exactly the same camera position. Consequently, they show the difference between the two modes (which, generally, differ in one parameter only) reliably.
1.1 What could be done to widen the FOV?
1.1.1 Full sensor oversampling on JB'n devices
If you're an old reader of mine, you may remember I've written full sensor oversamplers (the latest one is HERE) for all the three iPhone models suffering from narrow field of view. However, they all require jailbreaking, which has become quite complicated (and, in many cases, downright impossible) with the 4S and the 5. In addition, sensor oversampling just can't deliver as high a framerate as non-oversampling method. Unfortunately, even the latest iPhone 5 has a quite slow oversample sensor (this isn't a Nokia PureView 808 with its almost on order of magnitude faster sensor & associated circuitry, not in the least), which means the maximal framerate you can have by oversampling is around 20 frame-per-second (fps).
This approach is usable on even iOS 4 devices. After all, my first FOV-enlargening jailbreak tweak targeted the iPhone 4 back in late 2010, that is, still in the iOS 4 times.
1.1.2 Using low-resolution 4:3 video modes
If you can't jailbreak or can't put up with the relatively low framerate, using a lower resolution mode in a third-party app can give you significantly wider FOV's. For example, on the iPhone 5, the 192x144, 480x 360, and the 640x 480 modes, all 4:3 ones, all use the entire sensor surface, delivering as wide FOV as possible. Nevertheless, no even low-resolution modes deliver such wide FOV - 352x 288 is, for example, one of the narrowest: only the 720p60 mode in iOS7 is narrower. In addition, all 16:9 modes (960x 540, 1280x 720, 1920x1080) use a narrower FOV compared to the width of the sensor, even without using IS.
Let me show you the FOV achievable when recording into 480x 360 footage on the iPhone 5 (where this resolution is used by the pre-defined AVCaptureSession preset “AVCaptureSessionPresetMedium”):
As you can see, it has more pixels on the sides than even the non-IS Full HD framegrab let alone the IS one, not only vertically (which is evident given its aspect ratio of 4:3, while Full HD videos have the relatively shorter 16:9 ratio), but also horizontally. That is, don't expect the non-IS Full HD / 720p to use all the available horizontal pixels. Nevertheless, the non-IS mode is still a great step forward, towards a significantly wider FOV.
By the way, 480x 360 uses the entire sensor surface, as can also be easily proven by simply comparing it to a still shot, like the following:
As you can see, the two shots (a framegrab from the 480x 360 video footage and a true still shot) are fully identical, FOV-wise.
This approach is, as with my full sensor oversampler tweak, usable on iOS4 devices and up.
1.1.3 iOS 6+: disable image stabilization
Another solution that only became available in iOS 6 is using a third-party video recorder not using IS. Then, you won't suffer from the low framerate (my full sensor oversampler tweak) or the low (maximum 640x480) resolution. Unfortunately, as has already mentioned, you cannot disable IS in the stock Camera app, not even in iOS7; hence the need for a third-party app.
As the first two solutions (1.1.1, 1.1.2) have already been very widely discussed in my previous, dedicated articles, I only explain the last one: disabling IS. I scrutinize doing this with both third-party AppStore apps and, by presenting you a fully-functional camera video recorder, your own program. Let's start with the former.
2. Third-party camcorder apps
As of June 23rd, one app, FiLMiC Pro ($4.99) allows you to dynamically enable and disable IS. Should you want to do this frequently while staying in the same app, you really want to look into this app. If you don't need IS at all, you should check out Section 2.2 below, which lists several cheaper alternatives. Note that I've also listed some other popular App Store camera apps.
2.1 Apps where you can switch image stabilization ON and OFF
FiLMiC Pro (note: it records in 1080p24 and IS is disabled by default)
Dis/enabling IS is done in Settings (annotated by me):
2.2 IS is disabled (it's OFF all the time)
Camera Awesome (free) by SmugMug 1.1.4
King Camera (free)
BetterCam (free)
2.3 IS can't be disabled (it's ON all the time)
Camcorder Pro 3 ($0.99) by Game Lingo (Note: it also has SD (VGA) and LP (480*360) modes)
Camera Plus (free) (Note: by default, it uses its filtered, low-res recording mode. Full HD recording is only available after switching to the “Default” camera in Settings > Videos)
2.4 No video recording at all
Camera+ ($1.99)
2.5 Records at 720p only (no Full HD recording available)
SloPro (free)
Now, let's turn our attention to actually writing apps that don't use IS and, consequently, provide users a significantly wider FOV. (But, again, not as wide as my JB-only tools!)
3. Disabling Image Stabilization In your Own Code
If you're a developer, by comparison, you can easily implement a camcorder with IS disabled. Actually, when creating any kind of an AVFoundation-based camera recorder, by default, IS is disabled.
Also, if you already have a camcorder app in the App Store, consider adding this switch to it to cater for customers requiring any of the both modes. It's programmatically very easy to do and remember: iOS does the actual image stabilization, you don't need to do anything to stabilize the video. Unfortunately, so far, very few developers have done this – as can clearly be seen in the above list, only FiLMiC Pro supports switching.
All 16:9 recording modes (but not a single 4:3 one!) support electronic image stabilization.
En/disabling IS is very simple:
videoConnection.enablesVideoStabilizationWhenAvailable= <BOOL>;
where
- <BOOL> is YES when enabling and NO when disabling.
- AVCaptureConnection *videoConnection is initialized by [fo connectionWithMediaType:AVMediaTypeVideo];, where
- fo is a capture output; for example, [[AVCaptureMovieFileOutput alloc] init], where
- the target filepath is set and the recording started with [self.fo startRecordingToOutputFileURL:fileURL recordingDelegate:self];.
Note:
1. should you want to know beforehand whether a given video mode supports IS or not, currently, [AVCaptureConnection isVideoStabilizationEnabled] always returns YES for non-IS-capable modes (4:3 ones). Enabling IS on non-IS-enabled AVCaptureDeviceFormat (iOS7+) / AVCaptureConnection (all iOS versions) doesn't cause any problems, though. Better use AVCaptureDevice.activeFormat.isVideoStabilizationSupported instead if you want to dynamically and easily inquire whether a given video mode supports IS.
2. changing the IS mode via AVCaptureConnection.enablesVideoStabilizationWhenAvailable= <BOOL>; results in the current video recording being stopped.
3. enabling IS can be done any time; that is, even before setting AVCaptureDevice.activeFormat (in iOS7+) or AVCaptureSession.sessionPreset (in all iOS versions).
3.1 An Example App with Full Source Code
I've created an Xcode project that demonstrates all this. It's available for download HERE and runs on all iOS 6/7 iDevices. (But no earlier ones as it was with iOS 6 that iOS received changeable IS.)
It has no GUI (I wanted the source code to be as terse as possible), which means I use pre-defined starting (right at program starting) and stopping (set by DisableISVideoRecViewController.REC_TIME) times. You'll, of course, want to wire record starting and stopping to GUI components. I've already separated the code in charge of doing starting / stopping in two separate methods, DisableISVideoRecViewController.startVideoRecording and stopRec, respectively. You'll want to wire these methods to your GUI callbacks.
Otherwise, the code is very straightforward. In DisableISVideoRecViewController.viewDidLoad, I create an AVCaptureSession and immediately populate it with a video camera input (if it exists), AVCaptureDevice *videoDevice. Then, I create a display preview (AVCaptureVideoPreviewLayer) and add it to the current view as a subview. In Step 4, I create a AVCaptureMovieFileOutput target. Here, I don't start recording yet as I dynamically check for the existence of previous filenames and continue with the filename postfix index not used before.
You can do the latter using in the already-mentioned “startVideoRecording” method. Before finding the first non-existing, indexed filename, I also invoke the “enableIS” custom method, which enables IS. (Again, when using AVFoundation for video recording from third-party apps, IS isn't enabled by default.) Currently, it's commented out. You'll want to comment it back so that you can see the difference in FOV between the two (IS-enabled and disabled) modes.
At the end of startVideoRecording, I set up a timer to stop recording after REC_TIME seconds. Again, you'll want to connect the “stopRec” method to a GUI component.