3

I have an Android app (targetSdkVersion 28) that combines 2 TextureViews each showing a camera view into 1 bitmap then uses drawbitmap to a mediarecorder surface for recording. This is being called from the onSurfaceTextureUpdated. This seems to bottle neck it down to around 8 to 10 frames per second in the final video.

Does anyone know if OpenGL can achieve this in a more frame rate efficient way or if the below code can be made more performant?

I have tried moving creating the Bitmap and Canvas outside of the function and while it is slightly better, the combined bitmap has flicker.

class thScreenShot extends AsyncTask{

    @Override
    protected Object doInBackground(Object... params) {

        try {

            List<TextureView> tilingViews = getAllTextureViews(rootLayout);
            if (tilingViews.size() > 0) {
                final Bitmap bitmap = Bitmap.createBitmap(DISPLAY_WIDTH, DISPLAY_HEIGHT, Bitmap.Config.RGB_565);
                final Canvas canvas = new Canvas(bitmap);
                for (TextureView tilingTextureView : tilingViews) {
                    Bitmap bitmap1 = tilingTextureView.getBitmap(tilingTextureView.getWidth(), tilingTextureView.getHeight());
                    int[] location = new int[2];
                    tilingTextureView.getLocationInWindow(location);
                    Rect dest = new Rect(location[0], location[1], bitmap.getWidth(), bitmap.getHeight());
                    canvas.drawBitmap(bitmap1, dest, dest, null);
                }
                if (isRecording) {
                     if (surfaceS == null)
                     {
                          surfaceS = mMediaRecorder.getSurface();
                     }
                     synchronized (surfaceS) {
                          canvasS = surfaceS.lockHardwareCanvas();
                          canvasS.drawBitmap(bitmap, 0, 0, null);
                          surfaceS.unlockCanvasAndPost(canvasS);
                          FPSCount++;
                     }
                }
            }
            return null;
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}

public List<TextureView> getAllTextureViews(View view)
{
    List<TextureView> tilingViews = new ArrayList<TextureView>();
    if (view instanceof TextureView) {
        tilingViews.add((TextureView)view);
    }
    else if(view instanceof ViewGroup)
    {
        ViewGroup viewGroup = (ViewGroup)view;
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            tilingViews.addAll(getAllTextureViews(viewGroup.getChildAt(i)));
        }
    }
    return tilingViews;
}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
user3882856
  • 71
  • 1
  • 6

1 Answers1

0

I'm not sure if you need UI rendering to texture or normal render to texture, probably one of them. You can check for example Is it possible to render an Android View to an OpenGL FBO or texture? and https://gamedev.stackexchange.com/questions/41887/how-to-render-small-texture-on-another-texture

Also remember to always check https://www.khronos.org/opengl/wiki/Common_Mistakes

user1039663
  • 1,230
  • 1
  • 9
  • 15