nicolas2k / google-glass-api

Automatically exported from code.google.com/p/google-glass-api
1 stars 0 forks source link

Cannot take picture using raw Camera API #351

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Here's my code. 

        Camera camera = null;
        try {
            camera = Camera.open();
            camera.lock();
            SurfaceView dummy = new SurfaceView(this);
            camera.setPreviewDisplay(dummy.getHolder());
            camera.startPreview();
            camera.takePicture(null, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    // do stuff...
                    camera.release();
                }
            });
        } catch (Exception e) {
            Toast.makeText(this, "Failed to take a picture", Toast.LENGTH_SHORT).show();
            if (camera != null) {
                camera.release();
            }
        }

My onPictureTaken callback never gets called. Instead, I see this in the log:

01-09 10:48:22.268     109-8460/? D/DOMX﹕ 
hardware/ti/domx/domx/omx_proxy_common/src/omx_proxy_common.c:1688  __PROXY_SetCo
nfig()
01-09 10:48:22.268     109-8460/? D/DOMX﹕ ERROR: failed check:(eError == 
OMX_ErrorNone) || (eError == OMX_ErrorNoMore) - returning error: 0x80001010 - 
Error returned from OMX API in ducati
01-09 10:48:22.268     109-8460/? E/CameraHal﹕ (123c998)   
hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXCapture.cpp:2307 
setCapturingFlag - Error setting capturing flag!
01-09 10:48:22.268     109-8460/? I/CameraHal﹕ (123c998)   
hardware/ti/omap4xxx/camera/CameraHalCommon.cpp:114 PPM - PPM: 
startImageCapture image buffers queued and capture enabled:  :1280.395 ms :  
1389293302277 ms
01-09 10:48:27.268     109-8460/? E/CameraHal﹕ (123c998)   
hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXCapture.cpp:1591 
startImageCapture - Timeout expired on shutter callback
01-09 10:48:27.268     109-8460/? E/CameraHal﹕ (123c998)   
hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXCapture.cpp:1604 
startImageCapture - Exiting function startImageCapture because of ret -1 
eError=0
01-09 10:48:27.268     109-8460/? E/ion﹕ ioctl -1073460991 failed with code 
-1: Bad file number

Original issue reported on code.google.com by eug...@wearableintelligence.com on 9 Jan 2014 at 6:54

GoogleCodeExporter commented 8 years ago
Am using XE12

Original comment by eug...@wearableintelligence.com on 9 Jan 2014 at 7:19

GoogleCodeExporter commented 8 years ago
Actually, this also appears to be related to 
https://code.google.com/p/google-glass-api/issues/detail?id=228 (in that both 
crash at the native level)

Original comment by eug...@wearableintelligence.com on 10 Jan 2014 at 2:30

GoogleCodeExporter commented 8 years ago
Hello,

Thanks for the report! Unfortunately, I have not been able to reproduce this 
issue.
Please find attached a small sample app that I used to try to use 
Camera.takePicture: you can start the demo with "Ok Glass, show me a demo" and 
take a picture by tapping on the touchpad.

Best,
Alain

Original comment by ala...@google.com on 13 Jan 2014 at 11:25

Attachments:

GoogleCodeExporter commented 8 years ago
Alain,

The sample you provided works only it requires me to have camera control all 
the time. At all other times, I want it to be accessible to other processes.

Also, your sample throws an error after a few seconds (that is if I don't take 
the picture first):
01-13 17:39:01.963    9264-9287/com.google.android.glass.sample.camera 
E/Camera﹕ Received CAMERA_MSG_RELEASE
01-13 17:39:02.173    9264-9264/com.google.android.glass.sample.camera 
E/Camera﹕ Unknown message type 8192
01-13 17:39:28.423    9264-9264/com.google.android.glass.sample.camera 
E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to resume activity {com.google.android.glass.sample.camera/com.google.android.glass.sample.camera.MainActivity}: java.lang.RuntimeException: Method called after release()
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2444)
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2472)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1173)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4424)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.RuntimeException: Method called after release()
            at android.hardware.Camera.setPreviewDisplay(Native Method)
            at android.hardware.Camera.setPreviewDisplay(Camera.java:491)
            at com.google.android.glass.sample.camera.CameraPreview.updatePreview(CameraPreview.java:82)
            at com.google.android.glass.sample.camera.CameraPreview.setCamera(CameraPreview.java:56)
            at com.google.android.glass.sample.camera.MainActivity.onResume(MainActivity.java:66)
            at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1154)
            at android.app.Activity.performResume(Activity.java:4544)
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2434)
            at 
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2472)
            at 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1173)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at 
android.app.ActivityThread.main(ActivityThread.java:4424)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
            at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
            at dalvik.system.NativeStart.main(Native Method)

Original comment by eug...@wearableintelligence.com on 14 Jan 2014 at 1:46

GoogleCodeExporter commented 8 years ago
I just ran another experiment (my original code but using your CameraPreview) 
and I still go the same error in CPP layer (so it has nothing to do with 
CameraPreview). Comparing the two versions (yours and mine), the only relevant 
difference that I see is that you spread out the use of camera throughout 
activity's lifecycle whereas I do it in one go. 

The way I do it is technically correct. If camera expects me to give it some 
time to boot up, your API should either block or provide an asynchronous 
callback. You should not expect me to wing it.

Original comment by eug...@wearableintelligence.com on 14 Jan 2014 at 1:51

GoogleCodeExporter commented 8 years ago
Well, you need to at least wait for the preview to start which you can check 
with a SurfaceHolder.Callback.

Attached is a stripped down version of the previous app which takes a picture 
when started and releases the camera when the picture is available: the call to 
Camera.takePicture is done only when the SurfaceHolder is created and the 
preview is started.

Original comment by ala...@google.com on 14 Jan 2014 at 5:32

Attachments:

GoogleCodeExporter commented 8 years ago
Are you saying that startPreview causes surfaceCreated to be called? I suppose 
the answer is no.

What if the surface is already created? How do I know when startPreview goes 
through?

Original comment by eug...@wearableintelligence.com on 14 Jan 2014 at 6:56

GoogleCodeExporter commented 8 years ago
 In your latest example, I don't have control over when to take the picture. It gets taken as soon as the view is created.

I could, of course, move everything into a separate activity, whose sole 
purpose is to take the picture and finish. Is that the approach you want all 
developers to take? 

Original comment by eug...@wearableintelligence.com on 14 Jan 2014 at 6:59

GoogleCodeExporter commented 8 years ago
Regarding your question in #7, the camera should be passed a proper 
SurfaceHolder which you only get when onSurfaceCreated is called: once this is 
called, you can start the preview and take the picture whenever you want.

For #8, this is only a proof of concept showing that takePicture works: it is 
up to you to move the pieces around to support your use-case. You could simply 
keep flags to know when the Camera is ready (i.e the SurfaceHolder has been 
created and you can safely start a preview) and only start the preview and take 
the picture on user input.

I'm going to close this bug as "WorkingAsIntended".

Original comment by ala...@google.com on 14 Jan 2014 at 7:17

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
So, let me be clear. Anyone who wants to take a picture without a preview will 
have to create several files, a dozen functions and callbacks only to satisfy 
the requirement that camera does not work without a preview? 

That's like saying that your digital camera won't take pictures if the preview 
screen is broken.

Bravo, Google!

Original comment by eug...@wearableintelligence.com on 14 Jan 2014 at 7:27

GoogleCodeExporter commented 8 years ago
I should also add that startPreview call takes about a second, which makes for 
a bad user experience when trying to take an instant picture.

Original comment by eug...@wearableintelligence.com on 15 Jan 2014 at 3:59

GoogleCodeExporter commented 8 years ago
The camera demo app Alan created now breaks on XE16 (KK), although it worked 
fine on XE12
From my own code, it seems to be an issue with grabbing the camera. From the 
demo app:

04-19 15:38:41.906  15718-15718/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.google.android.glass.sample.camera, PID: 15718
    java.lang.NullPointerException
            at com.google.android.glass.sample.camera.MainActivity.onGesture(MainActivity.java:84)
            at com.google.android.glass.touchpad.CombinedListener.onGesture(CombinedListener.java:101)
            at com.google.android.glass.touchpad.OneFingerState.onEvent(OneFingerState.java:49)
            at com.google.android.glass.touchpad.StateMachine.onEvent(StateMachine.java:79)
            at com.google.android.glass.touchpad.GestureDetector.onMotionEvent(GestureDetector.java:244)
            at com.google.android.glass.sample.camera.MainActivity.onGenericMotionEvent(MainActivity.java:78)
            at android.app.Activity.dispatchGenericMotionEvent(Activity.java:2502)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchGenericMotionEvent(PhoneWindow.java:2153)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processGenericMotionEvent(ViewRootImpl.java:3998)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3862)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3424)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3474)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3443)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3550)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3451)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3607)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3424)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3474)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3443)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3451)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3424)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3474)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3443)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3583)
            at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3743)
            at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2010)
            at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1704)
            at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1695)
            at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:1987)
            at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
            at android.os.MessageQueue.nativePollOnce(Native Method)
            at android.os.MessageQueue.next(MessageQueue.java:138)
            at android.os.Looper.loop(Looper.java:131)
            at android.app.ActivityThread.main(ActivityThread.java:5061)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)
            at dalvik.system.NativeStart.main(Native Method)

Original comment by Han...@gmail.com on 19 Apr 2014 at 7:44

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
In relation to comments #7 and #9, how do I have surfaceCreated run multiple 
times (every time I want to take a photo)?

try { mCamera = Camera.open(); }
catch (Exception e) { e.printStackTrace(); }

mSurfaceView = (SurfaceView) findViewById(R.id.preview);
mSurfaceView.getHolder().addCallback(mSurfaceHolderCallback);

try { mCamera.setPreviewDisplay(mSurfaceView.getHolder()); }
catch (IOException e) { e.printStackTrace(); }

mCamera.startPreview();

--

mCamera.stopPreview();
mCamera.release();
mCamera = null;
mSurfaceView.setVisibility(View.GONE);

The first part of the code manages to reach surfaceCreated and onPictureTaken 
once (the first time it's run), but not a second time, after the second part of 
the code is run.

I've added my question in stackoverflow, in case someone wants to answer it 
there:

http://stackoverflow.com/questions/31996128/taking-a-picture-with-androids-camer
a-api-19-onpicturetaken-is-not-called

Original comment by augusto...@gmail.com on 14 Aug 2015 at 7:51