How to create multiple camera2 previews in most efficient way?

偶尔善良 提交于 2020-01-25 09:00:27

问题


I am trying to create 4 streams of my camera preview on my activity. I created a TextureView which is registered to the camera2 API for the feed and then I set up a listener on the SurfaceView in order to listen to changes for the feed and update the other 3 previews (ImageViews) accordingly. You can see in my code below:

    private final TextureView.SurfaceTextureListener mSurfaceTextureListener
            = new TextureView.SurfaceTextureListener() {

        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
            cameraHandler.openCamera(width, height);
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
            return true;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture texture) {
            for (ImageView mSecondaryPreview : mSecondaryPreviews) {
                Bitmap frame = Bitmap.createBitmap(mTextureView.getWidth(), mTextureView.getHeight(), Bitmap.Config.ARGB_8888);
                mTextureView.getBitmap(frame);
                mSecondaryPreview.setImageBitmap(frame);
            }
        }
    };

As you can see this has to read from the TextureView for every frame, extract the bitmap and then set the bitmap of the other 3 ImageView streams. I tried to do this on the UI thread initially which is very slow and then tried to submit it to the background handler which was better frame rate but caused a lot of issues with the app crashing due to the load.

Thanks

EDIT

So in order to crop the bottom 0.4375 of the preview, I changed ttmp to

    float[] ttmp = {
            0.0f, 1.0f,
            1.0f, 1.0f,
            0.0f, 0.4375f,

            0.0f, 0.4375f,
            1.0f, 1.0f,
            1.0f, 0.4375f,

            0.0f, 1.0f,
            1.0f, 1.0f,
            0.0f, 0.4375f,

            0.0f, 0.4375f,
            1.0f, 1.0f,
            1.0f, 0.4375f,

            0.0f, 1.0f,
            1.0f, 1.0f,
            0.0f, 0.4375f,

            0.0f, 0.4375f,
            1.0f, 1.0f,
            1.0f, 0.4375f,

            0.0f, 1.0f,
            1.0f, 1.0f,
            0.0f, 0.4375f,

            0.0f, 0.4375f,
            1.0f, 1.0f,
            1.0f, 0.4375f
    };

but this did not crop as expected


回答1:


So if you can get GLSurfaceView working with the camera preview as in this question then you can make 3 more copies simply by adding 6 more polygons. Let me explain how they are layed out. vtmp and ttmp describe the vector coordinates and texture coordinates, respectively, of two triangles, in a GL_TRIANGLE_STRIP form:

float[] vtmp = {
    1.0f, 1.0f,    //Top right of screen
    1.0f, -1.0f,    //Bottom right of screen
    -1.0f, 1.0f,    //Top left of screen
    -1.0f, -1.0f    //Bottom left of screen
};

float[] ttmp = {
    1.0f, 1.0f,     //Top right of camera surface
    0.0f, 1.0f,     //Top left of camera surface
    1.0f, 0.0f,     //Bottom right of camera surface
    0.0f, 0.0f      //Bottom left of camera surface
};

Step 1: Let's change the primitive type to a GL_TRIANGLES, because this is going to be difficult with a GL_TRIANGLE_STRIP:

//This also includes a fix for the left/right inversion:
float[] vtmp = {
    //Triangle 1:
    -1.0f, -1.0f,
    -1.0f, 1.0f,
    1.0f, 1.0f,

    //Triangle 2:
    1.0f, -1.0f,
    -1.0f, 1.0f,
    1.0f, 1.0f
};

float[] ttmp = {
    //Triangle 1:
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,

    //Triangle 2:
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f
};

pVertex = ByteBuffer.allocateDirect(12*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
pTexCoord = ByteBuffer.allocateDirect(12*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);    //Careful: Multiple changes on this line
(...)

If Step 1 went well, then let's add the extra triangles in Step 2:

float[] vtmp = {
    //Triangle 1:
    -1.0f, 0.0f,
    -1.0f, 1.0f,
    0.0f, 0.0f,

    //Triangle 2:
    0.0f, 0.0f,
    -1.0f, 1.0f,
    0.0f, 1.0f,

    //Triangle 3:
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 0.0f,

    //Triangle 4:
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    //Triangle 5:
    0.0f, -1.0f,
    0.0f, 0.0f,
    1.0f, -1.0f,

    //Triangle 6:
    1.0f, -1.0f,
    0.0f, 0.0f,
    1.0f, 0.0f,

    //Triangle 7:
    -1.0f, -1.0f,
    -1.0f, 0.0f,
    0.0f, -1.0f,

    //Triangle 8:
    0.0f, -1.0f,
    -1.0f, 0.0f,
    0.0f, 0.0f
};

float[] ttmp = {
    //This is the same as in Step 1, but duplicated 4 times over:
    //Triangle 1:
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,

    //Triangle 2:
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,

    //Triangle 3:
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,

    //Triangle 4:
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,

    //Triangle 5:
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,

    //Triangle 6:
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,

    //Triangle 7:
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,

    //Triangle 8:
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f
};

pVertex = ByteBuffer.allocateDirect(48*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
pTexCoord = ByteBuffer.allocateDirect(48*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 24);
(...)


来源:https://stackoverflow.com/questions/59524927/how-to-create-multiple-camera2-previews-in-most-efficient-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!