7

The example of CameraToMpegTest.java in bigflake.com, or "Show + capture camera" in Grafika, uses the camera.preview to get the frame data. Experiments show that (Nexus 4, Android 4.4.2) the frame rate is 10 fps. This is not as high as expected.

If we use the same device (Nexus 4, Android 4.4.2) to record a video using the camera, the frame rate is 30fps.

So I assume the lower frame rate using camera.preview lies in the method (preview method). I once read a post, saying that camera preview method has a lower frame rate.

So it seems the workaround is to use raw frame data from the camera hardware directly. How to do that? I have an impression iOS has video processing APIs to do that, directly getting frame raw data from camera. (But I do not know what their frame rate is).

user1914692
  • 3,033
  • 5
  • 36
  • 61

1 Answers1

14

The camera API has two different parameters for controlling the frame rate: setPreviewFrameRate, which takes a single frame rate value and is deprecated, and setPreviewFpsRange, which takes a range of FPS values, and is the currently-recommended control.

The reason the single-FPS setting control is not sufficient is that sometimes you want the camera to slow down its frame rate in dark conditions to keep the viewfinder bright (this is the case for a still camera viewfinder), and sometimes you want the camera to maintain a steady 30fps no matter what (in case of video recording). A single value can't capture which you prefer.

So, the ideal solution is to call getSupportedPreviewFpsRange to get a list of valid FPS ranges the camera supports, and pick the one that's best for your use case. If you're looking for steady 30fps operation, you'd want (30, 30) as the range.

Unfortunately, the set of supported FPS ranges isn't as well tested as it should be, and it's not guaranteed that (30, 30) is on the list. In that case, an alternative is to try the deprecated single-FPS control with a parameter of 30, and turn on the recording hint parameter. This parameter tells the camera device that you're doing recording-like operation, which may switch it to doing a steady frame rate at 30. Unfortunately that's not guaranteed, since it's just a hint.

So in short, to get steady 30fps operation:

  1. Query getSupportedPreviewFpsRange
  2. If (30,30) is listed, use setPreviewFpsRange(30, 30). This should be enough to guarantee steady frame rate.
  3. If not, query getSupportedPreviewFrameRates (30 should always be listed here, but best to double-check)
  4. Use setPreviewFrameRate(30) and setRecordingHint(true). This maximizes the likelihood of seeing 30fps operation. But some devices may still not do what you want, unfortunately.

Going forward, we'll hopefully add a requirement that (30, 30) is always listed as a supported range, to simplify this and guarantee steady-state operation.

Eddy Talvala
  • 17,243
  • 2
  • 42
  • 47
  • I added calls to `setRecordingHint(true)` to Grafika and I see significantly higher frame rates from the camera preview on Nexus 4. – fadden Mar 25 '14 at 20:18
  • Thank Eddy and fadden. If I only use setRecordingHint(true), it will go to 30 fps. Of course, for safety, I add getSupportedPreviewFpsRange. – user1914692 Mar 25 '14 at 23:22
  • @Eddy Talvala , I have trouble setting Nexus 5 preview at 30 fps and be bright at the same time, using Camera 1 API. If I set recording hint true and choose the (30, 30) preview fps range, then the preview in at 30 fps but the view is very dark in dim places. However, I noticed that Google's Camera app has 30 fps preview with bright preview. Is it because it's using Camera 2 API? – Petrakeas Dec 01 '15 at 09:35
  • It seems that setting recording hint to true is required for (30, 30) fps range, in order to get a well exposed image. – Petrakeas Dec 01 '15 at 13:27
  • The Google Camera app generally uses a wide FPS range for preview, such as (9,30). This is required to ensure a bright preview in darker conditions, and slower framerate is acceptable for a still mode viewfinder. For recording, the Google Camera App sticks to (30,30) generally. – Eddy Talvala Dec 02 '15 at 14:31