Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Samsung Galaxy S5 Camera Flash Problems

I am working on an app with custom Camera functionality. The Camera is working fine on the Galaxy S3, S4, HTC, Nexus, but on the S5, all of the photos that require flash come out dark. The photo looks fine in the preview, the flash fires, but what is captured by the sensor is always too dark, as if the flash never fired off, or the firing of the flash and the capturing of the image happened at different times. The flash can be either set to auto or to always on, with the same effect. I've tried FOCUS_MODE_CONTINUOUS_PICTURE and FOCUS_MODE_AUTO, with the same result.

Does anyone have any suggestions what else to try?

Thank You, Gary

like image 847
Gary Kipnis Avatar asked Oct 11 '14 19:10

Gary Kipnis


People also ask

Why is the flash not working on my Samsung phone?

Check Flashlight Settings in the Camera App If the flashlight not working issue is limited to the camera app only, you can double-check the flashlight settings to ensure that it isn't disabled or set to auto-mode. Open the Camera app on your Samsung Galaxy phone and tap on the flash icon in the top left corner.

Why is my phone camera flash not working?

Restart the phoneIf a particular app or process is conflicting with the flashlight, then a simple reboot should fix it. Just hold the power button and select “Power off” from the menu. Now wait 10-15 seconds and turn it back on. This should fix the problem in most cases.

How do I turn the flash on my Samsung camera?

To activate the flash when you are capturing photos, press the Flash release button on the left side of the camera. When you press the button, the flash will pop up and, depending on the shooting mode you have selected, the flash option will be activated in the camera settings.


1 Answers

It seems like there are 2 unrelated bugs here, one on the Nexus 4, the other on the Samsung S5. They both seem to manifest as the same issue, pictures taken in low light conditions with the flash on appear extremely dark, but have very different root causes.

Nexus 4

The Nexus 4 breaks when using continuous focus in conjunction with the flash. This seems like a relatively well known issue and the only solution seems to be to use FOCUS_MODE_AUTO instead of FOCUS_MODE_CONTINUOUS_PICTURE. The root cause seems to be related to taking the picture too early, before the flash gets a chance to fire.

As far as I know, the Nexus 4 is the only device that needs this kind of special casing (i.e. it reports supporting FOCUS_MODE_CONTINUOUS_PICTURE but breaks horribly with it).

// dummy method, replace with wherever you setup camera params
public void onCameraOpened(Camera camera) {
    Camera.Parameters params = camera.getParameters();

    setFocusModeParameter(
        params,
        Build.MODEL.equals("Nexus 4")
            ? new String[] {
                Camera.Parameters.FOCUS_MODE_AUTO
            }
            : new String[] {
                Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
                Camera.Parameters.FOCUS_MODE_AUTO,
            }
    );

    camera.setParameters(params);
}

public static void setFocusModeParameter(Camera.Parameters params, String... preferences) {
    List<String> supported_focus_modes = params.getSupportedFocusModes();
    if (supported_focus_modes == null) {
        return;
    }

    for (String pref : preferences) {
        if (supported_focus_modes.contains(pref)) {
            params.setFocusMode(pref);
            return;
        }
    }
}

Samsung S5

Unlike the Nexus 4, the Samsung S5 seems to lag behind the flash which causes a dark picture. As far as I can tell, turning on the hidden zero shutter lag parameter (in the safe manner described in the robust section) seems to have no ill effects on the following devices: Nexus 4, Nexus 5, Samsung S3, Samsung S4, Samsung Galaxy Tab S (SM-T700).

Turn on Zero Shutter Lag

Try setting the following hidden camera parameter, which seems to solve the problem on my S5.

Camera.Parameters params = camera.getParameters();
params.set("zsl", "on");
camera.setParameters(params);

More Robust Solution

If the solution above works, I'm using a slightly more robust way to detect when the zsl parameter is available:

// dummy method, replace with whatever sets up camera parameters
public void onCameraOpened(Camera camera) {
    Camera.Parameters params = camera.getParameters();
    setHiddenParameter(params, "zsl-values", "zsl", "on");
    camera.setParameters(params);
}

public static void setHiddenParameter(Camera.Parameters params, String values_key, String key, String value) {
    if (params.get(key) == null) {
        return;
    }

    String possible_values_str = params.get(values_key);
    if (possible_values_str == null) {
        return;
    }

    String[] possible_values = possible_values_str.split(",");
    for (String possible : possible_values) {
        if (possible.equals(value)) {
            params.set(key, value);
            return;
        }
    }
}

Explanations

This part is only here to document the rabbit hole to find this parameter, hopefully someone that knows more than me can expand on this.

Symptoms:

  • On the Samsung S5, taking pictures in extremely dark conditions with the flash set to FLASH_MODE_ON or FLASH_MODE_AUTO leads to dark or completely black photos.
  • This does not seem to happen on any other device I have tested (Nexus 4, Nexus 5, Samsung S3, Samsung S4)
  • If I take pictures standing close to the objects (~3 ft) in a completely dark room, I get a extremely dark picture with only a few things visible.
  • If I take pictures in front of an open space (>5 ft) in a completely dark room, I get a completely black picture.

The first thing I tried was messing with focus related settings, reasoning that the open space would cause the focus to take longer, thus messing with the timing of taking the picture with the flash. Neither FOCUS_MODE_AUTO nor FOCUS_MODE_CONTINUOUS_PICTURE seemed to help the situation.

I also tried locking the auto-exposure and auto-whitebalance adjustments before calling camera.takePicture(...) to make sure those process weren't throwing the flash timing off, but that did not seem to help either.

It still felt like a timing issue though, so I started comparing the difference in parameters between the parameters my app was using vs. the native camera app.

Native Camera

12-10 15:49:08.659: W/QCameraParameters(265): [FW_DBG] setFirmwareMode: none
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] Requested preview size 1920 x 1080
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] dualrecording-hint : 0 m_FaceAE=1 Camera ID=0
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] Requested video size 1920 x 1080
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] Requested picture size 2048 x 1152
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] Requested FOV 62.000000
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] requested jpeg thumbnail size 512 x 288
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] set optimal jpeg thumbnail size 512 x 288
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] rotation val = 90
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] m_bNoDisplayMode = 0
12-10 15:49:08.659: W/QCameraParameters(265): setZslMode : m_nDualMode=0, mHdrMode=0, mTakeLowlight=0, m_bRecordingHint=0, mAutoLLS=0, m_nDualRecordingHint=0
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] ZSL = ON
12-10 15:49:08.659: I/QCameraParameters(265): [PARM_DBG] Requested FpsRange Values:(15000, 30000)
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] flash mode = on
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] AEC lock = false
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] AWB lock = false
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] mHdrMode 0 mTakeLowlight 0
12-10 15:49:08.659: E/QCameraParameters(265): SAMSUNG APPS HDR MODE
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] live snapshot size 2048 x 1152
12-10 15:49:08.659: E/QCameraParameters(265): [syscamera][setRthdrModes::2831][str::off][prev_str::off]
12-10 15:49:08.659: E/QCameraParameters(265): [syscamera][setPafModes::2863][str::on][prev_str::on]
12-10 15:49:08.659: E/QCameraParameters(265): [syscamera][setDrcModes::2891][str::on][prev_str::on]
12-10 15:49:08.659: W/QCameraParameters(265): updateParameters : X - mCameraId=0, final_rc=0, line=4465
12-10 15:49:08.659: W/QCameraParameters(265): [PARM_DBG] setNumOfSnapshot : nBurstNum = 1, nExpnum = 1

My App

12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] Requested preview size 1920 x 1080
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] dualrecording-hint : 0 m_FaceAE=1 Camera ID=0
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] Requested video size 1920 x 1080
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] Requested picture size 2048 x 1152
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] Requested FOV 62.000000
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] requested jpeg thumbnail size 512 x 288
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] set optimal jpeg thumbnail size 512 x 288
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] m_bNoDisplayMode = 0
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] ZSL = off
12-10 15:48:33.109: I/QCameraParameters(265): [PARM_DBG] Requested FpsRange Values:(10000, 30000)
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] flash mode = on
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] AEC lock = false
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] AWB lock = false
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] mHdrMode 0 mTakeLowlight 0
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] live snapshot size 2048 x 1152
12-10 15:48:33.109: E/QCameraParameters(265): [syscamera][setPafModes::2863][str::off][prev_str::off]
12-10 15:48:33.109: E/QCameraParameters(265): [syscamera][setDrcModes::2891][str::off][prev_str::off]
12-10 15:48:33.109: W/QCameraParameters(265): updateParameters : X - mCameraId=0, final_rc=0, line=4465
12-10 15:48:33.109: W/QCameraParameters(265): [PARM_DBG] setNumOfSnapshot : nBurstNum = 1, nExpnum = 1

Native vs. My App

The AEC (auto exposure) and AWB (white balance) lines are the same, so that's consistent with what I've tried before. The one difference is the ZSL parameter, which I've never heard of before.

Googling for ZSL finds this SO answer:

To achieve zero shutter lag, the camera driver must maintain a small circular buffer pool containing full resolution frames. Images are captured at sensor rate and are sent to preview and to the circular buffer pool (either as raw Bayer or as processed/semi-processed YUV). When the use presses the shutter, the newest buffer in the circular pool is extracted, processed and compressed as JPEG. On older mobile phone cameras, the sensor is not able to capture full resolution frames at a high enough frame rate, and therefore ZSL cannot be implemented.

So it seems like the shutter lag causes a timing mismatch between when the flash fires and when the picture is captured. Turning on ZSL seems to eliminate the issue entirely. It should probably be on by default given that flash behaviour is broken without it, but I'm not going to hold my breath on that one.

like image 175
rraval Avatar answered Sep 22 '22 19:09

rraval