getSupportedPictureSize() returns a value which is not actually supported by Nexus4
Asked Answered
E

3

7

I have extended a SurfaceView for displaying the camera feed for a very simple camera application. To find the optimal preview size for each device, I used this sample code which is used in almost all the open source camera apps I have seen:

    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
    double minDiff = Double.MAX_VALUE;
    for (Camera.Size size : sizes) {
        if (Math.abs(size.width - width) < minDiff) {
        screenWidth = size.width;
        screenHeight = size.height;
        minDiff = Math.abs(size.width - width);
        }
    }

Everything works perfectly up to this point.

Now, due to the nature of the application, I have to keep two bitmaps in the memory during the course of a session and for the sake of simplicity(avoiding memory issues during testing) I used the same code for the PICTURE SIZE(replaced the getSupportedPreviewSizes() with getSupportedPictureSizes()). Everything works great on most of the devices though I have to decide some other way to choose the optimum picture size for each device.

Recently, while testing on an Nexus 4 device, this above loop failed in choosing the optimum picture size. Upon investigation, I found out that the getSupportedPictureSizes() functions returns a value i.e 1280*960 which is not actually supported by the Nexus 4 camera. So, how does one solve this issue? I mean, isn't this function supposed to ONLY return those values which the CAMERA of the device supports? I am sure there will be other devices with the same issue which I won't be able to test on. Any clues as to how this issue should be resolved?

UPDATE: Whats happening is that it accepts the wrong parameter without any error and the image that it returns is distorted, I will try to get a picture here as well. Also, there are no runtime exceptions.

Evanevander answered 20/5, 2013 at 15:17 Comment(6)
loop failed in choosing the optimum picture size - what do you mean by that? It loop cannot find screenWidth and screenHeight? Or the chosen values cannot be used in setPictureSize()?Housebreaker
The getSupportedPictureSizes() functions returns a value i.e 1280*960 which is not actually supported by the Nexus 4 camera. As in, this size cannot be used in setPictureSize()Evanevander
"So, how does one solve this issue?" -- tactically, use Build to determine that you're on a Nexus 4 and throw out this value. I and my Nexus 4 are not in the same place right now and so I cannot attempt to verify your reported behavior. BTW, what exactly does "not actually supported by the Nexus 4 camera" mean? Do you crash with an exception? Do you crash with a core dump? Do you just get invalid output? Does the phone catch fire? :-)Agar
Fortunately, the phone hasn't caught fire yet :-) Whats happening is that it accepts the wrong parameter without any error and the image that it returns is distorted, I will try to get you one so that you can comment on it and also, there are no runtime exceptions.Evanevander
@FarazHassan I'm having this trouble with an LG Lucid. It claims to support these sizes and aspect ratios, but takePicture returns a corrupted image at any of the 1.7… aspect ratios. 2560x1920 (1.3333333333333333) 3072x1728 (1.7777777777777777) 2048x1536 (1.3333333333333333) 2304x1296 (1.7777777777777777) 1536x864 (1.7777777777777777) 1280x960 (1.3333333333333333) 640x480 (1.3333333333333333) Is your situation similar?Ajani
Yup, I am facing the exact same problemEvanevander
A
6

I have the same problem on an LG Lucid (model number VS840 4G). Basically, getSupportedPictureSizes() returns these sizes:

Size        Aspect Ratio
2560x1920   (1.3333333333333333)
3072x1728   (1.7777777777777777)
2048x1536   (1.3333333333333333)
2304x1296   (1.7777777777777777)
1536x864    (1.7777777777777777)
1280x960    (1.3333333333333333)
640x480     (1.3333333333333333)

If we call setPictureSize() with any of the sizes with a 1.7 aspect ratio, the camera hardware throws no errors, but it returns an image that is distorted:

sample of distorted result from LG Lucid, showing what appears to be a pixel buffer interpreted with the wrong stride

I tried a number of techniques to get the camera driver to admit this size was not really supported, including checking the result of getPictureSize() and getSupportedPictureFormats() after calling setParameters(). I couldn't find anything that gave away this behavior.

To work around this, we now mimic the behavior of the stock Camera app: we attempt to find a "preferred" size from the getSupportedPictureSizes() list before falling back to selecting the largest (as computed by width * height). Since the preferred sizes all have an aspect ratio of 1.333 (4:3), this works around the issue on this device.

See the Camera app source where it sets the value (line 111) and the hardcoded sizes it prefers (line 63) for the exact implementation.

Ajani answered 6/6, 2013 at 16:18 Comment(5)
FWIW, I'm able to reproduce this problem using JBcamera by selecting one of the "bad" sizes. It happens in both portrait and landscape modes.Ajani
The image you published (i.sstatic.net/uxdW7.jpg) is a 900x1600 JPEG. If this is an untouched produce of your device, then definitely something is deeply wrong; this resolution is not listed, to the best of my knowledge, as supported picture size by any Nexus 4 (see androidfragmentation.com/database/l/deviceModel/Nexus%204).Housebreaker
PS: same for VS840 4GHousebreaker
@AlexCohn Yes, it's an untouched image. I think the camera driver is broken and the developers never noticed because they were testing using the stock camera app, which ignores the buggy sizes for photo mode.Ajani
So at least there is an easy way to programmatically find out that the things went very wrong: onPictureTaken() brings an image size not equal to camera.getParameters().getPictureSize().Housebreaker
H
1

I believe 1280x960 picture is supported by the secondary, face camera on Nexus 4. I don't know why the device reports "mixed" sizes, usually each camera answers for itself.

I can confirm that there are some devices that lie about their camera capabilities, though I have more experience with preview sizes than picture sizes.

When you choose a wrong size, different things may happen. Sometimes, you will get a RuntimeException on camera.setParameters() if you choose an unsupported size. Sometimes, the device will silently accept the parameters, but if you ask getParameters() after that, you will find the picture size did not change, or is not what you asked. Some devices lie even further: they pretend to set the required size, but the actual output is different. E.g. Galaxy Nexus pretends to support 320x240 video, but the buffers you get in the preview callback are of size 640x480.

Another "nice" feature of Nexus 4 is that it is, apparently, sensitive to android.camera.front feature (see Frontal Camera Image Distortion)

I have reproduced your logic with a Nexus 4 v.4.2.2 (JDQ39); there is no problem with picture size 1280x960 either camera. Note that the picture orientation is not exactly what one could expect, but your question does not mention fiddling with camera orientation.

Housebreaker answered 20/5, 2013 at 19:25 Comment(11)
Whats happening is that it accepts the wrong parameter without any error and the image that it returns is distorted, I will try to get you one so that you can comment on it and also, there are no runtime exceptions.Evanevander
Is it distorted similar to the referenced article?Housebreaker
Yup, its the same as this one.Evanevander
Then, people say uses-feature in Manifest may helpHousebreaker
uses-feature is already there, but has no effect on the problemEvanevander
I have reproduced your logic with a Nexus 4 v.4.2.2 (JDQ39); there is no problem with picture size 1280x960 either camera. Note that the picture orientation is not exactly what one could expect, but your question does not mention fiddling with camera orientation. I could try your APK if you put the full code somewhere.Housebreaker
Its locked to landscape orientation only, I dont think that'd have any effect?Evanevander
Generally speaking, orientation may have a major effect. But the problems usually concentrate around Portrait mode. The linked article, for example, demonstrates troubles in Portrait mode only. Anyway, I could not reproduce your problems even when I allowed Portrait. I could try to run your code on my device - maybe your sample is defective, this also happens.Housebreaker
Yeah, I meant, generally there aren't problems with the landscape orientation, let me get you the code I am using.Evanevander
been busy with something else, sorry I havent been able to get you the code yet, trying this one out on my phone, will let you know how it goesEvanevander
any update here? sitting on the same problem, actually, the resolution 1280x960 == 1.33 and DOES NOT WORK! :( for me, Nexus 4, Android 4.3 / 4.4 - same on bothWellfound
W
1

what's actually up there, BUT, summed up: thanks Google!

  • some devices support 1.33
  • some devices support 1.77

in my test scenario, a Nexus 4 with 4.3 and another one with 4.4 both are NOT supporting 1.33, BUT 1.77 ...

i cannot say how many devices are out there, or which is actually the unsupported type (above it's mentioned different way) .. so basically only option. let the user decide. if there are problems -> offer an option to change aspect ratio.

i did it this way now.

hope this helps someone -> good luck :)

Wellfound answered 10/4, 2014 at 21:59 Comment(2)
just a speculation: could this get broken when the new fully immersive view was introduced?Housebreaker
sorry, have absolutely no idea why this is so broken. its a mess. complete camera.Wellfound

© 2022 - 2024 — McMap. All rights reserved.