문제

I am building an augmented reality app that takes frames from the camera, filters them using a few image processing techniques, and displays them to the user in place of the camera preview.

When I first started I was simply calling:

holder = getHolder();
holder.addCallback(this);
... 
camera.addCallbackBuffer(buffer);
camera.setPreviewDisplay(holder);
camera.setPreviewCallbackWithBuffer(callback);
camera.startPreview();

Inside the callback I do the following:

SurfaceHolder holder;
Canvas c = holder.lockCanvas();
if (c != null) {
    try {
        // Draw to canvas
    } finally {
        holder.unlockCanvasAndPost(c);
    }
}

This worked fairly well, and was giving decent performance on the Motorola Photon.

I also own a Motorola Droid as well as an LG Optimus; on these two devices onPreviewFrame would never get called, and as a result the holder would never get drawn in the callback. And the user would be stuck with a black screen.

After searching around I found that the following line needed to be added

holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

With this line I finally get the callback. But the problem is if I try to call holder.lockCanvas() I get an error since this isn't allowed with SURFACE_TYPE_PUSH_BUFFERS.

Now I've been able to work around this by placing an ImageView on top of the SurfaceView and drawing the frames to the ImageView instead. But the performance of this is terrible in comparison to using SURFACE_TYPE_NORMAL.

My questions are:

  • Is SURFACE_TYPE_NORMAL a valid usable type, or can I only trust SURFACE_TYPE_PUSH_BUFFERS?
  • If so, is it possible to determine if a device supports SURFACE_TYPE_NORMAL so I can squeeze that extra bit of performance out of devices that do? Are there certain Android versions, or manufacturers that support it?

As a side note, I understand that for Honeycomb (3.0) these values are no longer supported. But they are requred for 2.3 and lower. Also for ICS (4.0), the new SurfaceTexture pipeline is blazing fast. But I would still like to support at least 2.2 and 2.3.

도움이 되었습니까?

해결책

While I have not received an official answer, and probably will not since on newer Android versions this is deprecated, I have found that SURFACE_TYPE_NORMAL is not valid for use with a camera preview on many devices.

This answer comes from testing on various devices. On some devices no video will ever be received; it has nothing to do with the various parameters used.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top