jamesathey / fastandroidcamera Goto Github PK
View Code? Open in Web Editor NEWCamera preview callbacks with less overhead on Xamarin.Android.
License: Apache License 2.0
Camera preview callbacks with less overhead on Xamarin.Android.
License: Apache License 2.0
Hey,
when using FastAndroidCamera and returning to the view multiple times ill receive an out of memory error. As soon as i stop returning bytes to the buffers in the callback the issue is fixed. It seems the handle is not properly released? And clue where this comes from?
I am testing with the example app from my own library https://github.com/rebuy-de/rb-forms-barcode
[mono] Unhandled Exception:
[mono] Java.Lang.OutOfMemoryError: Exception of type 'Java.Lang.OutOfMemoryError' was thrown.
[mono] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0
[mono] at Android.Runtime.JNIEnv.CallStaticObjectMethod (IntPtr jclass, IntPtr jmethod) [0x00063] in /Users/builder/data/lanes/1353/ac29b2c6/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:1144
[mono] at Android.OS.Looper.get_MainLooper () [0x0002d] in /Users/builder/data/lanes/1353/ac29b2c6/source/monodroid/src/Mono.Android/platforms/android-21/src/generated/Android.OS.Looper.cs:35
[mono] at Android.Runtime.AndroidEnvironment.GetDefaultSyncContext () [0x00000] in /Users/builder/data/lanes/1353/ac29b2c6/source/monodroid/src/Mono.Android/src/Runtime/AndroidEnvironment.cs:181
[mono] at System.AndroidPlatform.GetDefaultSyncContext () [0x00000] in <filename unknown>:0
[mono] at System.Threading.SynchronizationContext.get_Current () [0x00000] in <filename unknown>:0
[mono] at System.Threading.Tasks.AwaiterActionContinuation.Execute () [0x00000] in <filename unknown>:0
[mono] at System.Threading.Tasks.Task.ProcessCompleteDelegates () [0x00000] in <filename unknown>:0
[mono] at System.Threading.Tasks.Task.Finish () [0x00000] in <filename unknown>:0
[mono] at System.Threading.Tasks.Task.ThreadStart () [0x00000] in <filename unknown>:0
[mono] at System.Threading.Tasks.Task.Execute () [0x00000] in <filename unknown>:0
[mono] at System.Threading.Tasks.TpScheduler.TaskExecuterCallback (System.Object obj) [0x00000] in <filename unknown>:0
[mono] --- End of managed exception stack trace ---
[mono] java.lang.OutOfMemoryError
[mono] at dalvik.system.NativeStart.run(Native Method)
in the class JniEnvEx
getting a null returned with the following call:
var envP = typeof(JNIEnv).GetProperty ("Env", BindingFlags.NonPublic | BindingFlags.Static);
here's the method:
static void GetDelegate<TDelegate> (string name, ref TDelegate value)
where TDelegate : class
{
if (value != null)
return;
//////this line returns null....
var envP = typeof(JNIEnv).GetProperty ("Env", BindingFlags.NonPublic | BindingFlags.Static);
/////
var env = envP.GetValue (null);
var JniEnvP = env.GetType ().GetField ("JniEnv", BindingFlags.NonPublic | BindingFlags.Instance);
var JniEnv = JniEnvP.GetValue (env);
var d = JniEnv.GetType ().GetField (name);
value = (TDelegate) (object) Marshal.GetDelegateForFunctionPointer ((IntPtr) d.GetValue (JniEnv), typeof (TDelegate));
}
does this have something to do with Xamarin changes? I may try and roll back to an earlier version.
I am trying to get a simple sample project running using the FastAndroidCamera, but after ~990 frames (@ 30fps) my app crashes with:
[libc] Fatal signal 6 (SIGABRT) at 0x0000179c (code=-6)
I've tried to follow your sample code closely. Here's my callback code:
public void OnPreviewFrame(IntPtr data, Android.Hardware.Camera camera)
{
totalFrames++;
FastJavaByteArray buffer = new FastJavaByteArray(data);
Console.WriteLine ("frame " + totalFrames );
camera.AddCallbackBuffer(buffer);
}
not sure what to change?
Using xamarin forms, I've implemented a custom renderer to show a camera preview in a tabbed page (snapchat like). When moving away from the page and back (a few times) I get a out of memory exception.
When the page is appearing the following gets called:
try
{
Console.WriteLine("OPENING");
var watch = System.Diagnostics.Stopwatch.StartNew();
camera = Camera.Open(0);
camera.SetDisplayOrientation(90);
var parameters = camera.GetParameters();
var bitsPerPixel = Android.Graphics.ImageFormat.GetBitsPerPixel(parameters.PreviewFormat);
int bufferSize = (parameters.PreviewSize.Width * parameters.PreviewSize.Height * bitsPerPixel) / 8;
for (uint i = 0; i < 4; ++i)
{
using (FastJavaByteArray buffer = new FastJavaByteArray(bufferSize))
{
// allocate new Java byte arrays for Android to use for preview frames
camera.AddCallbackBuffer(new FastJavaByteArray(bufferSize));
}
// The using block automatically calls Dispose() on the buffer, which is safe
// because it does not automaticaly destroy the Java byte array. It only releases
// our JNI reference to that array; the Android Camera (in Java land) still
// has its own reference to the array.
}
watch.Stop();
System.Diagnostics.Debug.WriteLine("Opening camera: {0}ms", watch.ElapsedMilliseconds);
}
When the page dissappears:
if(camera != null) {
camera.SetPreviewDisplay(null);
camera.StopPreview();
camera.SetNonMarshalingPreviewCallback(null);
camera.Release();
camera.Dispose();
camera = null;
}
The previewCallback:
public void OnPreviewFrame(IntPtr data, Camera camera)
{
using(FastJavaByteArray buff = new FastJavaByteArray(data))
{
camera.AddCallbackBuffer(buff);
}
}
Logs:
[art] Starting a blocking GC Alloc
[art] Starting a blocking GC Alloc
[art] Alloc sticky concurrent mark sweep GC freed 245(67KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 536us total 5.632ms
[art] Starting a blocking GC Alloc
[art] Clamp target GC heap from 103MB to 96MB
[art] Alloc partial concurrent mark sweep GC freed 211(12KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 553us total 12.668ms
[art] Starting a blocking GC Alloc
[art] Clamp target GC heap from 103MB to 96MB
[art] Alloc concurrent mark sweep GC freed 80(17KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 583us total 18.989ms
[art] Forcing collection of SoftReferences for 1012KB allocation
[art] Starting a blocking GC Alloc
[art] Clamp target GC heap from 103MB to 96MB
[art] Alloc concurrent mark sweep GC freed 11(344B) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 606us total 17.917ms
[art] Throwing OutOfMemoryError "Failed to allocate a 1036812 byte allocation with 573032 free bytes and 559KB until OOM"
[art] Starting a blocking GC Alloc
[art] Starting a blocking GC Alloc
[art] Starting a blocking GC Alloc
[art] Clamp target GC heap from 103MB to 96MB
[art] Alloc partial concurrent mark sweep GC freed 6(192B) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 605us total 12.669ms
[art] Starting a blocking GC Alloc
[art] Clamp target GC heap from 103MB to 96MB
[art] Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 565us total 20.010ms
[art] Forcing collection of SoftReferences for 1012KB allocation
[art] Starting a blocking GC Alloc
[art] Clamp target GC heap from 103MB to 96MB
[art] Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 596us total 18.817ms
[art] Starting a blocking GC HomogeneousSpaceCompact
[art] Clamp target GC heap from 103MB to 96MB
[art] HomogeneousSpaceCompact marksweep + semispace GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 35.955ms total 35.955ms
[art] Throwing OutOfMemoryError "Failed to allocate a 1036812 byte allocation with 565112 free bytes and 547KB until OOM"
Thread finished: <Thread Pool> #14
Thread started: <Thread Pool> #15
[art] art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception java.lang.OutOfMemoryError: Failed to allocate a 1036812 byte allocation with 565112 free bytes and 547KB until OOM
[art] art/runtime/java_vm_ext.cc:410] at void md5270abb39e60627f0f200893b490a1ade.FragmentContainer.n_setUserVisibleHint(boolean) (FragmentContainer.java:-2)
[art] art/runtime/java_vm_ext.cc:410] at void md5270abb39e60627f0f200893b490a1ade.FragmentContainer.setUserVisibleHint(boolean) (FragmentContainer.java:43)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(android.view.ViewGroup, int, java.lang.Object) (FragmentPagerAdapter.java:134)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.v4.view.ViewPager.populate(int) (ViewPager.java:1266)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.v4.view.ViewPager.setCurrentItemInternal(int, boolean, boolean, int) (ViewPager.java:668)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.v4.view.ViewPager.setCurrentItemInternal(int, boolean, boolean) (ViewPager.java:630)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.v4.view.ViewPager.setCurrentItem(int, boolean) (ViewPager.java:622)
[art] art/runtime/java_vm_ext.cc:410] at void md5270abb39e60627f0f200893b490a1ade.TabbedPageRenderer.n_onTabSelected(android.support.design.widget.TabLayout$Tab) (TabbedPageRenderer.java:-2)
[art] art/runtime/java_vm_ext.cc:410] at void md5270abb39e60627f0f200893b490a1ade.TabbedPageRenderer.onTabSelected(android.support.design.widget.TabLayout$Tab) (TabbedPageRenderer.java:87)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.design.widget.TabLayout.dispatchTabSelected(android.support.design.widget.TabLayout$Tab) (TabLayout.java:1164)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.design.widget.TabLayout.selectTab(android.support.design.widget.TabLayout$Tab, boolean) (TabLayout.java:1157)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.design.widget.TabLayout.selectTab(android.support.design.widget.TabLayout$Tab) (TabLayout.java:1127)
[art] art/runtime/java_vm_ext.cc:410] at void android.support.design.widget.TabLayout$Tab.select() (TabLayout.java:1426)
[art] art/runtime/java_vm_ext.cc:410] at boolean android.support.design.widget.TabLayout$TabView.performClick() (TabLayout.java:1536)
[art] art/runtime/java_vm_ext.cc:410] at void android.view.View$PerformClick.run() (View.java:21168)
[art] art/runtime/java_vm_ext.cc:410] at void android.os.Handler.handleCallback(android.os.Message) (Handler.java:746)
[art] art/runtime/java_vm_ext.cc:410] at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:95)
[art] art/runtime/java_vm_ext.cc:410] at void android.os.Looper.loop() (Looper.java:148)
[art] art/runtime/java_vm_ext.cc:410] at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:5443)
[art] art/runtime/java_vm_ext.cc:410] at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
[art] art/runtime/java_vm_ext.cc:410] at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:728)
[art] art/runtime/java_vm_ext.cc:410] at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:618)
Am I missing something ?
Xamarin.Forms: 2.3.4
Hello, I am trying to access the frames of the preview on Android using this Library, and then passing the FastJavaByteArray to Zxing's Decode() method to scan for a barcode in a specific area of the preview. The preview is working fine, and when I use the normal Preview.SetPreviewCallback(this); it works fine and the OnPreviewFrame(byte[], Camera) gets called. It's just when I use Preview.SetNonMarshalingPreviewCallback(this) that the method isn't being called. I'm not to sure why this is happening and I wanted to use this so I could scan for a barcode frame by frame using Zxing. I've attached my code below.
`public void Open() {
if (!closed) return;
try {
Preview = Camera.Open();
}
catch (Exception e) {
Console.WriteLine(e);
}
var parameters = Preview.GetParameters();
int numBytes = (parameters.PreviewSize.Width * parameters.PreviewSize.Height * Android.Graphics.ImageFormat.GetBitsPerPixel(parameters.PreviewFormat)) / 8;
using (FastJavaByteArray buffer = new FastJavaByteArray(numBytes))
Preview.AddCallbackBuffer(new FastJavaByteArray(numBytes));
var options = new ZXing.Mobile.MobileBarcodeScanningOptions();
options.PossibleFormats.Add(BarcodeFormat.QR_CODE);
barcodeReader = options.BuildBarcodeReader();
Preview.SetNonMarshalingPreviewCallback(this);
//Preview.SetPreviewCallback(this);
Handler handler = new Handler();
Action loop = null;
loop = () =>
{
if (!closed)
{
AutoFocusLoop();
handler.PostDelayed(loop, (long)(1000 * AF_DELAY));
}
};
handler.Post(loop);
closed = false;
}
public void OnPreviewFrame(IntPtr data, Camera camera)
{
//Generate FastJavaByteArray and use Zxing Decode()
}
`
Hey,
does the xamarin android 5.1 change regarding JNIEnv have any effects on the library?
Is there a need to make changes to the library to utilize the new GC feature?
The readme file says:
...
using (FastJavaByteArray buffer = new FastJavaByteArray(numBytes))
{
// allocate new Java byte arrays for Android to use for preview frames
camera.AddCallbackBuffer(new FastJavaByteArray(numBytes));
}
...
Unless I'm missing something, the variable buffer is simply instantiated and disposed without ever actually being used. Isn't this enclosing using{} statement redundant?
Hello,
if i instanciate the class:
this.previewNonMarshallingCallback = new mPreviewNonMarshallingCallback();
The following exception is thrown:
Unhandled Exception:
System.TypeLoadException: Could not load type 'FastAndroidCamera.INonMarshalingPreviewCallbackInvoker' from assembly 'FastAndroidCamera, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Hi,
Do you have any plan to update camera API to camera2?
Thanks,
Jesse
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.