ochornenko / Camera2GLPreview

Android camera preview application using Camera2 API and OpenGL ES/Vulkan
174 stars 53 forks source link

Your Sample is better than sample google ndk master (camera/basic) ? #3

Closed simonprovost closed 5 years ago

simonprovost commented 5 years ago

Hello,

I am new in this domain, but after using a lot hours camera/basic ndk master sample google, I have observed that the sample was not too good, because if you grow the resolution it will make a lot of latency's on your app.

I just downloaded your sample one hour ago and I was feeling wonderful when I have seen that your project works well, but I don't find where can I grow the resolution to test if it works much better than the camera/basic ndk, do you know where can I make it?

I think you know the camera/basic project, do you make this sample because the camera/basic was made a lot of latency?

Thank you for sharing your sample, it is very helpful !! Have a good day !!

EDIT 1:

I think I found, how to change the resolution.

            mImageReader = ImageReader.newInstance(1280, 720, ImageFormat.YUV_420_888, 2);
ochornenko commented 5 years ago

Hi,

Yes that's the right place to change the resolution, just need to make sure your camera supports it. In some filter GLSL shaders it also hard coded to use VGA (640, 480) resolution, just in case you need to use that filters.

Qamar4P commented 4 years ago

Hi @ochornenko

I agree it's better. I have little different question but it's relevant to this thread.

Have you done any performance comparison?

What if we write VideoRenderer.java with all methods in JAVA?

There are some comparison references available here

Just to give you an idea what is our problem. Currently we have following renderer. There are some colors, transitions and scaling applied using shader script. If user is constantly previewing the screen. FYI we don't record. We just preview. This causes device to heat-up. Some device get too hot. 48+ Degree Celsius

public class MyRenderer extends Thread implements OnFrameAvailableListener {

 private void initGL() {
        this.mEglCore = new EglCore((EGLContext)null, 3);
        this.mWindowSurface = new WindowSurface(this.mEglCore, this.mSurfaceTexture);
        this.mWindowSurface.makeCurrent();
        this.initGLComponents();
    }

    private void initGLComponents() {
        this.setupVertexBuffer();
        this.setupTextures();
        this.setupCameraTexture();
        this.setupShaders();
        this.mUpdateUniforms = true;
        this.mOnRendererReadyListener.onRendererReady();
    }
...
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        synchronized(this) {
            this.mPreviewTexture.updateTexImage();
            this.draw();
            this.mWindowSurface.makeCurrent();
            boolean swapResult = this.mWindowSurface.swapBuffers();
            if (!swapResult) {
                Looper.myLooper().quit();
            }

        }
    }

private void draw() {
        if (this.mUpdateUniforms) {
            GLES20.glViewport(0, 0, this.mViewportWidth, this.mViewportHeight);
            GLES20.glUseProgram(this.mShaderPgm);
            this.updateUniformAndAttribs();
            this.mUpdateUniforms = false;
        }

        GLES20.glEnableVertexAttribArray(this.positionHandle);
        GLES20.glEnableVertexAttribArray(this.textureCoordinateHandle);
        GLES20.glDrawElements(5, drawOrder.length, 5123, this.drawListBuffer);
        GLES20.glDisableVertexAttribArray(this.positionHandle);
        GLES20.glDisableVertexAttribArray(this.textureCoordinateHandle);
        this.checkGlError("after draw");
    }
}

You can see grafika/TextureViewGLActivity.java example for reference.

I want to know how much performance and power consumption will be improved. If write all rendering in C++ as you did. If you can explain little bit that will be helpful. Thanks

ochornenko commented 4 years ago

Hi @Qamar4P

I did not do performance comparison. In general it should be more or less the same because it renders eventually on GPU, there can be some differences in implementation of GL in Java that can affect performance, like allocation of buffers for textures, passing data to GPU memory etc.

What are you doing in your run() method? I see in grafika implementation they are rendering on separate thread in run() method but you render it when onFrameAvailable is called. Maybe there are some issues in your renderer thread implementation.

Qamar4P commented 4 years ago

@ochornenko Rendering is fine. Here is the run method code. Using Looper.

public void run() {
        Looper.prepare();
        this.mHandler = new Handler();
        this.initGL();
        Looper.loop();
        this.deinitGL();
        this.mOnRendererReadyListener.onRendererFinished();
        if (this.mShutdownSemaphore != null) {
            this.mShutdownSemaphore.release();
        }

    }