Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃悰 Front camera recording is inverted when going from Back to Front camera during recording on Android #2854

Open
3 of 5 tasks
likecarson opened this issue May 7, 2024 · 4 comments
Labels
馃悰 bug Something isn't working

Comments

@likecarson
Copy link

likecarson commented May 7, 2024

What's happening?

On an Android device, while taking a video recording with the Back camera started, if user switches to Front camera during the same recording the Front video recording becomes inverted -- it looks okay during the recording session but the saved video recording of the Front camera is inverted (upside-down).

Interestingly, if I start the recording using the Front camera then switch to Back camera the recording of the Front video is fine.

Reproduceable Code

const [cameraPosition, setCameraPosition] = useState<'front' | 'back'>('back');
  const cameraDevice = useCameraDevice(cameraPosition);

<Camera
            ref={cameraRef}
            device={cameraDevice}
            torchEnabled={torchEnabled}
            onRotate={useCallback(() => {
              setCameraPosition((p) => (p === 'back' ? 'front' : 'back'));
            }, [])}
            onTorchToggle={() => setTorchEnabled((prev) => !prev)}
          />

Relevant log output

Back Camera:
{"formats": [{"autoFocusSystem": "none", "fieldOfView": 115.98923300825525, "maxFps": 30, "maxISO": 1600, "minFps": 2, "minISO": 25, "photoHeight": 144, "photoWidth": 176, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "none", "fieldOfView": 115.98923300825525, "maxFps": 30, "maxISO": 1600, "minFps": 2, "minISO": 25, "photoHeight": 240, "photoWidth": 320, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "none", "fieldOfView": 115.98923300825525, "maxFps": 30, "maxISO": 1600, "minFps": 2, "minISO": 25, "photoHeight": 288, "photoWidth": 352, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "none", "fieldOfView": 115.98923300825525, "maxFps": 30, "maxISO": 1600, "minFps": 2, "minISO": 25, "photoHeight": 480, "photoWidth": 640, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "none", "fieldOfView": 115.98923300825525, "maxFps": 30, "maxISO": 1600, "minFps": 2, "minISO": 25, "photoHeight": 720, "photoWidth": 1280, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "none", "fieldOfView": 115.98923300825525, "maxFps": 30, "maxISO": 1600, "minFps": 2, "minISO": 25, "photoHeight": 960, "photoWidth": 1280, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}], "hardwareLevel": "limited", "hasFlash": false, "hasTorch": false, "id": "10", "isMultiCam": false, "maxExposure": 6, "maxZoom": 1, "minExposure": -6, "minFocusDistance": 999.999985098839, "minZoom": 1, "name": "10 (BACK) androidx.camera.camera2", "neutralZoom": 1, "physicalDevices": ["ultra-wide-angle-camera"], "position": "back", "sensorOrientation": "landscape-left", "supportsFocus": false, "supportsLowLightBoost": false, "supportsRawCapture": false}

Front Camera:
{"formats": [{"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 1440, "photoWidth": 1920, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 1080, "photoWidth": 1920, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 960, "photoWidth": 1920, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 1200, "photoWidth": 1600, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 1080, "photoWidth": 1440, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 960, "photoWidth": 1280, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 720, "photoWidth": 1280, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 768, "photoWidth": 1024, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 600, "photoWidth": 800, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 480, "photoWidth": 720, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 480, "photoWidth": 640, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 360, "photoWidth": 640, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 288, "photoWidth": 352, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}, {"autoFocusSystem": "contrast-detection", "fieldOfView": 77.70146040253039, "maxFps": 30, "maxISO": 1000, "minFps": 7, "minISO": 100, "photoHeight": 240, "photoWidth": 320, "supportsDepthCapture": false, "supportsPhotoHdr": false, "supportsVideoHdr": false, "videoHeight": 720, "videoStabilizationModes": [Array], "videoWidth": 1280}], "hardwareLevel": "full", "hasFlash": true, "hasTorch": true, "id": "1", "isMultiCam": true, "maxExposure": 24, "maxZoom": 12.931958198547363, "minExposure": -24, "minFocusDistance": 9.800000093460085, "minZoom": 1, "name": "1 (FRONT) androidx.camera.camera2", "neutralZoom": 1, "physicalDevices": ["wide-angle-camera", "wide-angle-camera", "telephoto-camera"], "position": "front", "sensorOrientation": "landscape-right", "supportsFocus": true, "supportsLowLightBoost": false, "supportsRawCapture": false}

Camera Device

Back Camera
{
  "formats": [],
  "sensorOrientation": "landscape-left",
  "hardwareLevel": "limited",
  "maxZoom": 1,
  "minZoom": 1,
  "maxExposure": 6,
  "supportsLowLightBoost": false,
  "neutralZoom": 1,
  "physicalDevices": [
    "ultra-wide-angle-camera"
  ],
  "supportsFocus": false,
  "supportsRawCapture": false,
  "isMultiCam": false,
  "minFocusDistance": 999.999985098839,
  "minExposure": -6,
  "name": "10 (BACK) androidx.camera.camera2",
  "hasFlash": false,
  "hasTorch": false,
  "position": "back",
  "id": "10"
}

Front Camera
{
  "formats": [],
  "sensorOrientation": "landscape-right",
  "hardwareLevel": "full",
  "maxZoom": 12.931958198547363,
  "minZoom": 1,
  "maxExposure": 24,
  "supportsLowLightBoost": false,
  "neutralZoom": 1,
  "physicalDevices": [
    "wide-angle-camera",
    "wide-angle-camera",
    "telephoto-camera"
  ],
  "supportsFocus": true,
  "supportsRawCapture": false,
  "isMultiCam": true,
  "minFocusDistance": 9.800000093460085,
  "minExposure": -24,
  "name": "1 (FRONT) androidx.camera.camera2",
  "hasFlash": true,
  "hasTorch": true,
  "position": "front",
  "id": "1"
}

Device

Android Pixel 6 Pro API 34 (emulator), Pixel 5 API 34 (physical device)

VisionCamera Version

4.0.3

Can you reproduce this issue in the VisionCamera Example app?

I didn't try (鈿狅笍 your issue might get ignored & closed if you don't try this)

Additional information

@likecarson likecarson added the 馃悰 bug Something isn't working label May 7, 2024
@mrousavy
Copy link
Owner

mrousavy commented May 8, 2024

What does inverted mean? Please attach a sample video.

@mrousavy mrousavy changed the title 馃悰 [V4] Front camera recording is inverted when going from Back to Front camera during recording on Android 馃悰 Front camera recording is inverted when going from Back to Front camera during recording on Android May 8, 2024
@likecarson
Copy link
Author

likecarson commented May 8, 2024

Here is a screen recording using the Android Pixel 6 Pro API 34 emulator. The same happens on physical device:

@mrousavy
Copy link
Owner

mrousavy commented May 8, 2024

Okay, this is a CameraX bug then, nothing I am doing explicitly - could you create a bug report in the Google CameraX issue tracker about this?
Thanks!

@likecarson
Copy link
Author

@mrousavy I think I figured out the issue -- at least doing this change fixes it for me:

In this file:
node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt

I commented out line 308:
val video = VideoCapture.Builder(recorder).also { video ->
// Configure Video Output
// video.setMirrorMode(MirrorMode.MIRROR_MODE_ON_FRONT_ONLY)

And the issue was resolved. I think this is because in my use case, the recording starts using the back camera and the CameraX must set a certain orientation, and when I switch to Front camera during the same recording the orientation is not updated to relative to Front camera, so mirrorMode causes the inversion.

I'm not sure if there is a way to adjust the code to check if the orientation is correct before applying the setMirrorMode or maybe this is the desired behavior just an issue with CameraX as you say.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
馃悰 bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants