9

I am trying to encode a 30 frames per second video using MediaCodec through the Camera's PreviewCall back(onPreviewFrame). The video that I encoded always plays very fast(this is not desired). So, I tried to check the number of frames that is coming into my camera's preview by setting up a int frameCount variable to remember its count. What I am expecting is 30 frames per second because I setup my camera's preview to have 30 fps preview(as shown below). The result that I get back is not the same. I called the onPreviewFrame callback for 10 second, the number of frameCount I get back is only about 100 frames. This is bad because I am expecting 300 frames. Is my camera parameters setup correctly? Is this a limitation of Android's Camera preview call back? And if this is a limitation on the Android Camera's preview call back, then is there any other camera callback that can return the camera's image data(nv21,yuv, yv12) in 30 frames per second?

thanks for reading and taking your time to helpout. i would appreciate any comments and opinions.

Here is an example an encoded video using Camera's onPreviewFrame:

http://www.youtube.com/watch?v=I1Eg2bvrHLM&feature=youtu.be

                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setPreviewFormat(ImageFormat.NV21);
                parameters.setPictureSize(previewWidth,previewHeight);
                parameters.setPreviewSize(previewWidth, previewHeight);
//              parameters.setPreviewFpsRange(30000,30000);

                parameters.setPreviewFrameRate(30);
                mCamera.setParameters(parameters);

                mCamera.setPreviewCallback(previewCallback);
                mCamera.setPreviewDisplay(holder);
xiaowoo
  • 2,248
  • 7
  • 34
  • 45
  • 1
    Different devices have different capabilities. Is 30fps in the range returned by http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getPreviewFpsRange(int[]) ? – fadden Nov 12 '13 at 15:51
  • My device returned a range of 5000-30000, I guess my question now is how to fix the rate so it doesn't varies all the time? – xiaowoo Nov 12 '13 at 22:44
  • are there other ways to get the camera frame data other than camera onPreviewFrame callback? – xiaowoo Nov 12 '13 at 23:40
  • You can use native camera intrface, as OpenCV does, instead of onPreviewFrame(), but it is not more reliable, not faster, and not officially supported. It will not overcome the variable range problem. I'd only recommend this way for video recording, if you can use hardware encoder, which can read camera buffers in kernel address space. – Alex Cohn Nov 13 '13 at 04:41

1 Answers1

17

No, Android camera does not guarantee stable frame rate, especially at 30 FPS. For example, it may choose longer exposure at low lighting conditions.

But there are some ways we, app developers, can make things worse.

First, by using setPreviewCallback() instead of setPreviewCallbackWithBuffer(). This may cause unnecessary pressure on the garbage collector.

Second, if onPreviewFrame() arrives on the main (UI) thread, you cause any UI action directly delay the camera frames arrival. To keep onPreviewFrame() on a separate thread, you should open() the camera on a secondary Looper thread. Here I explained in detail how this can be achieved: Best use of HandlerThread over other similar classes.

Third, check that processing time is less than 20ms.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • thanks alex, your suggestion improved the frame rate call back significantly. never the less, it still cannot fix the call back rate. i need the call back rate to be exactly lets say 25fps or 30fps... no more or less – xiaowoo Nov 12 '13 at 22:46
  • 1
    It might be worth examining the app with systrace to see where the pain points are. – fadden Nov 12 '13 at 23:57