1
votes

I'm using Camera2 to record videos. To get a list of available resolutions, we have 2 options:

List<android.util.Size> resolutions = Arrays.asList(map.getOutputSizes(MediaRecorder.class));

And:

// CAMCORDER_PROFILES is an int array listing all the profiles ids
for(int profileId : CAMCORDER_PROFILES) {

    if(CamcorderProfile.hasProfile(profileId)) {

        CamcorderProfile profile = CamcorderProfile.get(profileId);
        // Here we can get a resolution with profile.videoFrameWidth & profile.videoFrameHeight
    }
}

At first I was using option 2 only. It was working fine until I try on a Samsung Galaxy A3 2016. On this device, if I try to use the 1920*1080 resolution, it fails with this error:

E/CameraDevice-0-LE: Surface with size (w=1920, h=1080) and format 0x1 is not valid, size not in valid set: [960x720, 880x720, 720x720, 720x480, 640x480, 352x288, 320x240, 176x144]

To workaround it, I now get a profile whose resolution is in the result of map.getOutputSizes(MediaRecorder.class). I works, but the best profile I can use is 640x480, which is not enough for my needs.

Is there a way to use the 1920*1080 resolution with Camera2 on the A3? Or is that resolution usable only with the Samsung SDK???

EDIT: Here's what I do when I start the video recording:

private void startRecordingVideo() {

    if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewResolution) {
        return;
    }

    try {

        closeCaptureSession();
        setUpMediaRecorder();

        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;

        texture.setDefaultBufferSize( (int) mPreviewResolution.getWidth(), (int) mPreviewResolution.getHeight());

        List<Surface> surfaces = new ArrayList<>();

        // Set up Surface for the camera preview
        Surface previewSurface = new Surface(texture);
        surfaces.add(previewSurface);
        mPreviewRequestBuilder.addTarget(previewSurface);

        // Set up Surface for the MediaRecorder
        Surface recorderSurface = mMediaRecorder.getSurface();
        surfaces.add(recorderSurface);
        mPreviewRequestBuilder.addTarget(recorderSurface);

        // Start a capture session:
        mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {

            @Override
            public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {

                mCaptureSession = cameraCaptureSession;
                updatePreview();

                // Start recording
                mMediaRecorder.start();
            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                Log.e(this, "Unable to start recording video");
            }

        }, mBackgroundHandler);
    }
    catch (CameraAccessException | IOException e) {
        e.printStackTrace();
    }
}
1

1 Answers

3
votes

A3 has a Legacy camera. This means that the camera2 API is a wrapper around the old Camera API. Quite often, this wrapper introduces more hassle than whatever it resolves. I recommend to work with this and other legacy devices directly through the old Camera API.