Max
Max

Reputation: 16719

Setting camera preview buffer size

I'm testing my app using HTC Wildfire with Android 2.2.1. The default camera preview size is 768x432. I see it from device log:

12-19 18:41:34.088: D/QualcommCameraHardware(72): initPreview E: preview size=768x432
12-19 18:41:34.088: D/QualcommCameraHardware(72): initPreview E: preview size=768x432 videosize = 768 x 432
12-19 18:41:34.088: D/QualcommCameraHardware(72): mBufferSize=497664, mAlignedBufferSize=524288

OK, it works. But if I try to change preview size to some different value like 320x240 or 800x480 there is nothing but a mess of pixels on the screen. The most interesting thing here is that if I use preview with the buffer size smaller then the default one (497664) I get this error in the log:

12-19 18:52:49.288: E/Camera-JNI(5776): Manually set buffer was too small! Expected 497664 bytes, but got 144000!

So it is obvious that the actual buffer size is not changed. Is there any way to solve this?

I should also notice that there is no such problem on Asus Eee Pad Transformer with Android 3.2.1

Upvotes: 2

Views: 5609

Answers (3)

Vlad
Vlad

Reputation: 4525

My solution for 2.2 version:

Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
mCamera.addCallbackBuffer(data);
mCamera.startPreview();

http://developer.android.com/reference/android/hardware/Camera.html#addCallbackBuffer%28byte[]%29
        }
                };

Upvotes: 0

Max
Max

Reputation: 16719

I've figured out what was the problem. It appears that on Android 2.2.1 you do have to set camera parameters BEFORE you call

camera.startPreview()

However on later systems like Android 3.2.1 this is no longer an issue (however it could be vendor specific).

Upvotes: 4

Konstantin Pribluda
Konstantin Pribluda

Reputation: 12367

Camera on android is kind of voodoo. I would recommend to look which preview sizes are actually supported (well, at least advertized) :

        Camera.Parameters cameraParameters = camera.getParameters();
        // print out parameters
        Log.d(LOG_TAG, "flash modes:" + cameraParameters.getSupportedFlashModes());
        Log.d(LOG_TAG, "autofocus:" + cameraParameters.getSupportedFocusModes());
        Log.d(LOG_TAG, "preview formats:" + cameraParameters.getSupportedPreviewFormats());
        Log.d(LOG_TAG, "scene modes:" + cameraParameters.getSupportedSceneModes());
        Log.d(LOG_TAG, "white balance modes:" + cameraParameters.getSupportedWhiteBalance());

Unfortunately, not all preview sizes are quaranted to work, even if they are in this list. At least not on motorola defy or htc hero. So I do following:

            // as we know,  that big preview size can produce RE on HTC Hero,
        // we just iterate through allowed preview sizes until we find something proper
        //  go for maximal allowed preview size

        previewSize = cameraParameters.getPreviewSize();

        if (previewSize.width <= MIN_PREVIEW_WIDTH) {
            Log.d(LOG_TAG, "preview size is too small:" + previewSize.width + "x" + previewSize.height);
            final List<Camera.Size> sizes = cameraParameters.getSupportedPreviewSizes();
            Collections.sort(sizes, new Comparator<Camera.Size>() {
                public int compare(Camera.Size o1, Camera.Size o2) {
                    return new Integer(o2.width).compareTo(o1.width);
                }
            });

            for (Camera.Size size : sizes) {
                cameraParameters.setPreviewSize(size.width, size.height);
                camera.setParameters(cameraParameters);
                Log.d(LOG_TAG, "attempt preview size:" + size.width + "x" + size.height);
                try {
                    camera.startPreview();
                    Log.d(LOG_TAG, "...accepted - go along");
                    //  ok, camera accepted out settings.  since we know,
                    // that some implementations may choose different preview format,
                    // we retrieve parameters again. just to be sure
                    cameraParameters = camera.getParameters();
                    break;
                } catch (RuntimeException rx) {
                    // ups, camera did not like this size
                    Log.d(LOG_TAG, "...barfed, try next");
                }

            }
        } else {
            Log.d(LOG_TAG, " accepted default preview size on the spot:" + previewSize.width + "x" + previewSize.height);
            camera.startPreview();
        }

Upvotes: 0

Related Questions