1

Downloaded Xamarin Camera2Basic project

Initially all works correctly as it's begin tested in Visual Studio 2017 emulator.

Commented out code inside "CameraCaptureStillPictureSessionCallback.cs" as shown below to allow the still image captured to be displayed on the emulator screen after clicking the "Take Picture" button:

public override void OnCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)
{
    //Owner.ShowToast("Saved: " + Owner.mFile);
    //Log.Debug(TAG, Owner.mFile.ToString());
    //Owner.UnlockFocus();
}

Clicking the "Take Picture" button hides itself, and shows another button labeled "Retake Picture" on the screen (which I added after the fact and the code is located in the Camera2BasicFragment.cs file, but the code is inconsequential to the issue).

Clicking the now visible "Retake Picture" button does the following:

  1. Hides itself
  2. Shows the "Take Picture" button
  3. Calls UnlockFocus()

UnlockFocus() allows the camera's stream to display continuously on the screen instead of the still image captured previously.

Now, when I click the "Take Picture" button again (to attempt to capture a new still image), the app crashes.

Visual studio does not provide any meaningful error messages. The closest useful bit of information are the error messages displayed int the Device Log:

07-26 23:29:03.201   10.1" Marshmallow (6.0.0) XHDPI Tablet Error   6987    BufferQueueProducer [ImageReader-640x480f100m2-6987-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count  
07-26 23:29:07.174   10.1" Marshmallow (6.0.0) XHDPI Tablet Error   6987    RequestThread-0 Hit timeout for jpeg callback!  
07-26 23:29:03.201   10.1" Marshmallow (6.0.0) XHDPI Tablet Error   6987    Legacy-CameraDevice-JNI LegacyCameraDevice_nativeProduceFrame: Error while producing frame Function not implemented (-38).

I'm not sure what to make of these errors, or which settings/code to change to allow the "Retake Picture" functionality to work without crashing the app.

Any suggestions?

EDIT 1: Per request, where is a link to the project as I currently have it.

https://drive.google.com/file/d/0B7OSuA_ybXcFb081T210UlQzZkE/view?usp=sharing

Here is some other seemingly pertinent information:

  1. This code was run using:

    a. Windows 10 Pro, Visual Studio 2017 Community, Android Emulator For Visual Studio, Hyper-v Virtual Manager, Android 6.0 (Marshamallow SDK 23), Tablet sized template

    b. 2013 Macbook Pro, Visual Studio For Mac (latest version), default emaulator, Android 6.0 (Marshmallow SDK 23), Tablet sized template.

  2. The failure to take snapshot after second "LockFocus" call is observed in both environments.

  3. The Mac made it easier to find some more meaninful errors:

    a. The error I saw happened on method "produceFrame" inside LegacyCameraDevice.java

fuzzlog
  • 131
  • 3
  • 18
  • Could you please share your basic project that could reproduce this problem? – York Shen Jul 28 '17 at 06:20
  • I've added a link to download the project as requested, plus added more info. thanks. – fuzzlog Jul 28 '17 at 15:49
  • Have you test it on a real device? – York Shen Jul 29 '17 at 13:59
  • I have not. Do not have a device available for me to use yet. Will not either until I can get past this issue occurring in the emulator. – fuzzlog Jul 29 '17 at 17:26
  • 1
    Maybe you could read this : https://stackoverflow.com/questions/28003186/capture-picture-without-preview-using-camera2-api – York Shen Jul 30 '17 at 03:28
  • I read it. Not sure how it can help me. Even if a use an ImageReader, my issue still remains since that question talks about saving it silently. I need to show the user a still image of their capture, so they can decide to keep it, or retake it. We're you able to successfully run the code for which I posted the link? – fuzzlog Jul 30 '17 at 08:32

2 Answers2

1

I've the problem with this demo also, The real problem behind this is about the IOnImageAvailableListener, it will not trigger the OnImageAvailable method to save the picture...

After read the code, i found out that the demo is broken, it missing some piece. In the Camera2BasicFragment.cs, in the OnCreateMethod, you will need to add this line

mCaptureCallback = new CameraCaptureListener() { Owner = this};

The entire method should look like this:

public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        mStateCallback = new CameraStateListener() { owner = this };
        mSurfaceTextureListener = new Camera2BasicSurfaceTextureListener(this);

        // fill ORIENTATIONS list
        ORIENTATIONS.Append((int)SurfaceOrientation.Rotation0, 90);
        ORIENTATIONS.Append((int)SurfaceOrientation.Rotation90, 0);
        ORIENTATIONS.Append((int)SurfaceOrientation.Rotation180, 270);
        ORIENTATIONS.Append((int)SurfaceOrientation.Rotation270, 180);
    }

The interesting thing is, if you run this on emulator, nothing will happened, because in the CameraCaptureListener.cs file, this will always return 0, not ControlAFState.FocusedLocked or ControlAFState.InActivate

Integer afState = (Integer)result.Get(CaptureResult.ControlAfState);

Event if i hack the If method to be able to run jump into next step, the method OnImageAvaiable of ImageAvailableListener.cs will never be triggered by emulator. But if i run on the real device, it ran fine ?!

So the fix is: 1. Add the code above like i explained on the onCreate function. 2. Don't use emulator to run Camera2, it's buggy.

Hope it help :)

Huy.Vu
  • 173
  • 10
  • I think you are looking at the java version. The one I'm working with is the Xamarin (c# version). The OnCreate method on this looks completely different than yours so I cannot follow your suggestions. – fuzzlog Aug 23 '17 at 03:53
  • sorry, i have edited my answer, i copied the wrong code section :). Actually it's Xamarin (C#) version. Just test on a real device, it will work. – Huy.Vu Aug 23 '17 at 07:15
  • Finally able to get a hold of a device. Indeed, the app does not crash and works as intended when used within a device. Thank you for your insight. I've marked your answer as accepted. – fuzzlog Aug 31 '17 at 02:11
0

If you are still interested; IOnImageAvailableListener not trigger OnImageAvailable method in Visual Studio Emulator For Android.

Code is correct but Visual Studio Emulator For Android have a bug. I hope they fix it as soon as possible. On the other hand you can try your code in Xamarin by using Android Studio Emulator without any bug. It is easy and you dont need to know anything about Java or Android Studio Just follow the below steps

  1. Install Android Studio with virtual device
  2. Close Hper-v on your pc (windows -> control panel -> programs -> programs and features -> Turn windows features on or off)
  3. Open android studio -> Tools -> Avd Manager -> Create Virtual Device

Visual studio detect the virtual device just use it on Visual Studio Xamarin

hope it help