2

My goal is to get as high FPS as possible. I will be happy with BW small frames, but FPS should be maximum. getSupportedPreviewFpsRange on HTC WildFire S returns (9, 30). But when I try to draw preview image with most simple processing it visually get at about 12-15 FPS max. After setting Parameters and startPreview() method call I do this:

camera.setPreviewCallback(new Camera.PreviewCallback() {
          @Override
          public void onPreviewFrame(byte[] bytes, Camera camera) {
            Bitmap bitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
            int[] colors = new int[size.width * size.height];
            for (int i=0; i < colors.length; i++){
              colors[i] = getBWColor(bytes[i]);
            }
            bitmap.setPixels(colors, 0, size.width, 0, 0, size.width, size.height);
            secondView.setImageBitmap(bitmap);
          }
        });
      }

private static int getBWColor(byte b){
    int res = 255;
    for(int i=0;i<3;i++){
      res = (res << 8) + b;
    }
    return res;
  }

Is there way to get it as fast as possible? =(

Aleksandr Motsjonov
  • 1,230
  • 3
  • 14
  • 25
  • Someone recommended "You could supply socket to media recorder, and it will write live data into it - so you can capture data before it saved. ( this will be already compressed though ) " But I don't really understand how to do it. – Aleksandr Motsjonov Dec 27 '11 at 22:19

3 Answers3

5

First, use setPreviewCallbackWithBuffer(), it reuses one buffer and does not have to allocate new buffer on every frame. Check my older answer, there is an example how to use it.

Than, do not do any expensive opeartion in onPreviewFrame(), the time of the data is limited, it is rewritten on each new frame. You should do the processing in another thread.

And of course do not create new bitmap a the colors array on each frame, do it just once.

Community
  • 1
  • 1
Jaa-c
  • 5,017
  • 4
  • 34
  • 64
  • I saw example of using different threads and other stuff people suggested here. I accumulate all suggestions, and than write what did I do. Thank you and other commentators! – Aleksandr Motsjonov Dec 29 '11 at 13:52
3

I don't really understand what you're doing, but I'd guess you're killing yourself in processing.

1) Do not create a new bitmap every time. Reuse 1 bitmap. 2) Manipulate your bitmaps in C/C++ with the NDK. Look at the "plasma" example. Its MUCH faster than Java. Not because its C++ really, but because the Java version of the API tends to transform the whole thing whenever you push in a data array for pixels. In the C++ version, you can directly manipulate the pixel values.

Kevin Galligan
  • 16,159
  • 5
  • 42
  • 62
1

Im not exactly sure what your goal is for this app but the way I added in camera functionality was created a custom surfaceView class and set up my camera inside there. After i chose the front facing (if available) or the back facing, I set up the parameters and then called setPreviewDisplay and passed in the SurfaceHolder I created(code below). After that simply call startpreview() and everything worked beautifully. I had good framerate for it and it all looked fine. If you want me to elaborate more or post some code let me know.

SufaceHolder mHolder;
mHolder = getHolder();
mHolder.addCallback(this); // this is the SurfaceView class
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.setKeepScreenOn(true);