Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nexus 10, Front facing camera Preview is black (no preview)

So I'm working on a Camera related project, and I've been testing it on many devices and all of them passed the tests except for the Nexus 10.

I can't really figure out what is going on, and there is no one talking about the issue online.

I was able to replicate the issue on two different Nexus 10 (wifi) devices.

Here is my activity's code:

public class MainActivity extends Activity {
    private static Camera mCamera;
    private static boolean mCameraOpen;
    private static ImageView mPreviewImageView;
    private SurfaceView mPreviewSurfaceView;
    private static boolean mPreviewRunning;
    private static Handler mHandler;
    private static int TESTS_COUNT = 0;
    private Camera.Parameters mCameraParameters;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHandler = new Handler();
        mPreviewSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        mPreviewImageView = (ImageView) findViewById(R.id.imageview);
        mPreviewSurfaceView.getHolder().addCallback(mCallback);

        TextView view = (TextView) findViewById(R.id.textview);
        view.setText("Format: " + String.valueOf(TESTS_COUNT));

    }

    @Override
    public void onResume(){
        super.onResume();
        if (mCamera == null){
            for (int i = 0; i < Camera.getNumberOfCameras(); i++){
                Camera.CameraInfo info = new Camera.CameraInfo();
                Camera.getCameraInfo(i, info);

                if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
                    mCamera = Camera.open(i);
                    Camera.Parameters params = mCamera.getParameters();
                    params.set("camera-id", 2);
                    List<Integer> formats = params.getSupportedPreviewFormats();
                    if (formats.size() > TESTS_COUNT) {
                        Log.e("Camera", "testing preview format at index: " + TESTS_COUNT);
                        params.setPreviewFormat(formats.get(TESTS_COUNT));
                        mCamera.setParameters(params);
                        mCameraOpen = true;
                        SurfaceHolder holder = mPreviewSurfaceView.getHolder();
                        if (holder != null && holder.getSurface() != null && holder.getSurface().isValid()) {
                            mCallback.surfaceCreated(holder);
                        }
                        mCameraParameters = params;
                        break;
                    } else {
                        finish();
                    }
                }

            }
        }
    }

    @Override
    public void onPause(){
        super.onPause();
        if (mPreviewRunning){
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mPreviewRunning = false;
        }

        if (mCameraOpen){
            mCamera.release();
            mCamera = null;
            mCameraOpen = false;
        }
    }

    @Override
    public void onDestroy(){
        super.onDestroy();

    }

    private final SurfaceHolder.Callback mCallback =  new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
                if (mCameraOpen && mCamera != null){
                    try {
                        mCamera.setPreviewDisplay(surfaceHolder);
                        mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                            private int count;
                            private int total;
                            @Override
                            public void onPreviewFrame(byte[] bytes, Camera camera) {
                                if (count == 15){
                                    Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
                                    // pWidth and pHeight define the size of the preview Frame
                                    ByteArrayOutputStream out = new ByteArrayOutputStream();

                                    // Alter the second parameter of this to the actual format you are receiving
                                    YuvImage yuv = new YuvImage(bytes, ImageFormat.NV21, previewSize.width, previewSize.height, null);

                                    // bWidth and bHeight define the size of the bitmap you wish the fill with the preview image
                                    yuv.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 50, out);
                                    byte[] bitmapBytes = out.toByteArray();
                                    final Bitmap bitmap= BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
                                    mHandler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            mPreviewImageView.setImageBitmap(bitmap);
                                        }
                                    });
                                    count = 0;
                                    total++;
                                    if (total > 5){
                                        TESTS_COUNT++;
                                        if (TESTS_COUNT == mCameraParameters.getSupportedPreviewSizes().size()) {
                                            finish();
                                            return;
                                        }
                                        Intent intent = new Intent( MainActivity.this, MainActivity.class);
                                        startActivity(intent);

                                    }

                                } else {
                                    count++;
                                }

                            }
                        });

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder,  int format, int width, int height) {
            for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()){
                if (size.width == width && size.height == height){
                    if (mCameraOpen && mCamera != null && mPreviewRunning == false) {
                        mCameraParameters.setPreviewSize(width, height);
                        mCamera.setParameters(mCameraParameters);

                        mCamera.startPreview();

                        mPreviewRunning = true;
                        break;
                    }
                }
            }
            if (mPreviewRunning == false){
                Log.e("CameraPreview", "size not supported");
            }

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

        }
    };

}

My layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity"
    android:orientation="vertical"
    android:weightSum="2">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity"
    android:orientation="horizontal"
    android:layout_weight="1"
    android:weightSum="2">
        <SurfaceView
            android:layout_width="640px"
            android:layout_height="480px"
            android:id="@+id/surfaceview"/>
        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:id="@+id/imageview"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textview"
            android:textSize="40sp"/>
</LinearLayout>
</LinearLayout>

and manifest :

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

There is no error messages and the screen is just black

Screenshot

like image 325
Mr.Me Avatar asked Sep 10 '15 18:09

Mr.Me


2 Answers

The underlying question is, "How to debug this?" The answer, as always, is to think of as many hypotheses as possible that could explain these results, then test those hypotheses.

Here are some hypotheses (do think of more):

  • It's not finding any cameras.
  • It's not finding any front-facing cameras.
  • It's misinterpreting the camera parameters.
  • It's setting up mCallback too late, that is, after needed.
  • It's not finding a valid surface.
  • It's not successfully registering for camera frames.
  • It's registering but not receiving any camera frames.
  • It's receiving camera frames but failing to display them, e.g. the images aren't in the expected format, or the setImageBitmap(bitmap) Runnable isn't running.
  • TESTS_COUNT isn't doing what you want it to do.

You can test hypotheses via logging, but for much of this it'd be quicker and more informative to single-step through it in the debugger and examine data values such as params.

If you're not familiar with the debugger, now's the time!

like image 117
Jerry101 Avatar answered Sep 29 '22 08:09

Jerry101


Please verify your device by using an app called CtsVerifier, this app is included in the Android Open Source Project and is part of the Compatibility test suite for android devices(CTS). CTS Verifier have a series of tests that check the camera.check this link

You can be sure that if the front camera does not work within this app. Then your device is probably damaged, or some corruption has occurred on the hal layer. If that is the case you may attempt to downgrade/upgrade your android os. If not it probably is hardware damage.

like image 39
Jorch914 Avatar answered Sep 29 '22 08:09

Jorch914