bool SetupCaptureSession()
        {
            var availableResolutions = new List <CameraResolution> ();

            var consideredResolutions = new Dictionary <NSString, CameraResolution> {
                { AVCaptureSession.Preset352x288, new CameraResolution   {
                      Width = 352, Height = 288
                  } },
                { AVCaptureSession.PresetMedium, new CameraResolution    {
                      Width = 480, Height = 360
                  } },                                                                                      //480x360
                { AVCaptureSession.Preset640x480, new CameraResolution   {
                      Width = 640, Height = 480
                  } },
                { AVCaptureSession.Preset1280x720, new CameraResolution  {
                      Width = 1280, Height = 720
                  } },
                { AVCaptureSession.Preset1920x1080, new CameraResolution {
                      Width = 1920, Height = 1080
                  } }
            };

            // configure the capture session for low resolution, change this if your code
            // can cope with more data or volume
            session = new AVCaptureSession()
            {
                SessionPreset = AVCaptureSession.Preset640x480
            };

            // create a device input and attach it to the session
//			var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video);
            AVCaptureDevice captureDevice = null;
            var             devices       = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);

            foreach (var device in devices)
            {
                captureDevice = device;
                if (options.UseFrontCameraIfAvailable.HasValue &&
                    options.UseFrontCameraIfAvailable.Value &&
                    device.Position == AVCaptureDevicePosition.Front)
                {
                    break;                     //Front camera successfully set
                }
                else if (device.Position == AVCaptureDevicePosition.Back && (!options.UseFrontCameraIfAvailable.HasValue || !options.UseFrontCameraIfAvailable.Value))
                {
                    break;                     //Back camera succesfully set
                }
            }
            if (captureDevice == null)
            {
                Console.WriteLine("No captureDevice - this won't work on the simulator, try a physical device");
                if (overlayView != null)
                {
                    this.AddSubview(overlayView);
                    this.BringSubviewToFront(overlayView);
                }
                return(false);
            }

            CameraResolution resolution = null;

            // Find resolution
            // Go through the resolutions we can even consider
            foreach (var cr in consideredResolutions)
            {
                // Now check to make sure our selected device supports the resolution
                // so we can add it to the list to pick from
                if (captureDevice.SupportsAVCaptureSessionPreset(cr.Key))
                {
                    availableResolutions.Add(cr.Value);
                }
            }

            resolution = options.GetResolution(availableResolutions);

            // See if the user selected a resolution
            if (resolution != null)
            {
                // Now get the preset string from the resolution chosen
                var preset = (from c in consideredResolutions
                              where c.Value.Width == resolution.Width &&
                              c.Value.Height == resolution.Height
                              select c.Key).FirstOrDefault();

                // If we found a matching preset, let's set it on the session
                if (!string.IsNullOrEmpty(preset))
                {
                    session.SessionPreset = preset;
                }
            }

            var input = AVCaptureDeviceInput.FromDevice(captureDevice);

            if (input == null)
            {
                Console.WriteLine("No input - this won't work on the simulator, try a physical device");
                if (overlayView != null)
                {
                    this.AddSubview(overlayView);
                    this.BringSubviewToFront(overlayView);
                }
                return(false);
            }
            else
            {
                session.AddInput(input);
            }


            foundResult = false;
            //Detect barcodes with built in avcapture stuff
            AVCaptureMetadataOutput metadataOutput = new AVCaptureMetadataOutput();

            captureDelegate = new CaptureDelegate(metaDataObjects =>
            {
                if (!analyzing)
                {
                    return;
                }

                //Console.WriteLine("Found MetaData Objects");

                var msSinceLastPreview = (DateTime.UtcNow - lastAnalysis).TotalMilliseconds;

                if (msSinceLastPreview < options.DelayBetweenAnalyzingFrames ||
                    (wasScanned && msSinceLastPreview < options.DelayBetweenContinuousScans) ||
                    working)
                //|| CancelTokenSource.IsCancellationRequested)
                {
                    return;
                }

                working      = true;
                wasScanned   = false;
                lastAnalysis = DateTime.UtcNow;

                var mdo = metaDataObjects.FirstOrDefault();

                if (mdo == null)
                {
                    return;
                }

                var readableObj = mdo as AVMetadataMachineReadableCodeObject;

                if (readableObj == null)
                {
                    return;
                }

                wasScanned = true;

                var zxingFormat = ZXingBarcodeFormatFromAVCaptureBarcodeFormat(readableObj.Type.ToString());

                var rs = new ZXing.Result(readableObj.StringValue, null, null, zxingFormat);

                resultCallback(rs);

                working = false;
            });

            metadataOutput.SetDelegate(captureDelegate, DispatchQueue.MainQueue);
            session.AddOutput(metadataOutput);

            //Setup barcode formats
            if (ScanningOptions.PossibleFormats != null && ScanningOptions.PossibleFormats.Count > 0)
            {
                #if __UNIFIED__
                var formats = AVMetadataObjectType.None;

                foreach (var f in ScanningOptions.PossibleFormats)
                {
                    formats |= AVCaptureBarcodeFormatFromZXingBarcodeFormat(f);
                }

                formats &= ~AVMetadataObjectType.None;

                metadataOutput.MetadataObjectTypes = formats;
                #else
                var formats = new List <string> ();

                foreach (var f in ScanningOptions.PossibleFormats)
                {
                    formats.AddRange(AVCaptureBarcodeFormatFromZXingBarcodeFormat(f));
                }

                metadataOutput.MetadataObjectTypes = (from f in formats.Distinct() select new NSString(f)).ToArray();
                #endif
            }
            else
            {
                metadataOutput.MetadataObjectTypes = metadataOutput.AvailableMetadataObjectTypes;
            }



            previewLayer = new AVCaptureVideoPreviewLayer(session);

            //Framerate set here (15 fps)
            if (previewLayer.RespondsToSelector(new Selector("connection")))
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0))
                {
                    var perf1 = PerformanceCounter.Start();

                    NSError lockForConfigErr = null;

                    captureDevice.LockForConfiguration(out lockForConfigErr);
                    if (lockForConfigErr == null)
                    {
                        captureDevice.ActiveVideoMinFrameDuration = new CMTime(1, 10);
                        captureDevice.UnlockForConfiguration();
                    }

                    PerformanceCounter.Stop(perf1, "PERF: ActiveVideoMinFrameDuration Took {0} ms");
                }
                else
                {
                    previewLayer.Connection.VideoMinFrameDuration = new CMTime(1, 10);
                }
            }

                        #if __UNIFIED__
            previewLayer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;
                        #else
            previewLayer.LayerVideoGravity = AVLayerVideoGravity.ResizeAspectFill;
                        #endif
            previewLayer.Frame    = new CGRect(0, 0, this.Frame.Width, this.Frame.Height);
            previewLayer.Position = new CGPoint(this.Layer.Bounds.Width / 2, (this.Layer.Bounds.Height / 2));

            layerView = new UIView(new CGRect(0, 0, this.Frame.Width, this.Frame.Height));
            layerView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
            layerView.Layer.AddSublayer(previewLayer);

            this.AddSubview(layerView);

            ResizePreview(UIApplication.SharedApplication.StatusBarOrientation);

            if (overlayView != null)
            {
                this.AddSubview(overlayView);
                this.BringSubviewToFront(overlayView);

                //overlayView.LayoutSubviews ();
            }

            session.StartRunning();

            Console.WriteLine("RUNNING!!!");



            //output.AlwaysDiscardsLateVideoFrames = true;


            Console.WriteLine("SetupCamera Finished");

            //session.AddOutput (output);
            //session.StartRunning ();


            if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus))
            {
                NSError err = null;
                if (captureDevice.LockForConfiguration(out err))
                {
                    if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus))
                    {
                        captureDevice.FocusMode = AVCaptureFocusMode.ContinuousAutoFocus;
                    }
                    else if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.AutoFocus))
                    {
                        captureDevice.FocusMode = AVCaptureFocusMode.AutoFocus;
                    }

                    if (captureDevice.IsExposureModeSupported(AVCaptureExposureMode.ContinuousAutoExposure))
                    {
                        captureDevice.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure;
                    }
                    else if (captureDevice.IsExposureModeSupported(AVCaptureExposureMode.AutoExpose))
                    {
                        captureDevice.ExposureMode = AVCaptureExposureMode.AutoExpose;
                    }

                    if (captureDevice.IsWhiteBalanceModeSupported(AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance))
                    {
                        captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance;
                    }
                    else if (captureDevice.IsWhiteBalanceModeSupported(AVCaptureWhiteBalanceMode.AutoWhiteBalance))
                    {
                        captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.AutoWhiteBalance;
                    }

                    if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
                    {
                        captureDevice.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near;
                    }

                    if (captureDevice.FocusPointOfInterestSupported)
                    {
                        captureDevice.FocusPointOfInterest = new CGPoint(0.5f, 0.5f);
                    }

                    if (captureDevice.ExposurePointOfInterestSupported)
                    {
                        captureDevice.ExposurePointOfInterest = new CGPoint(0.5f, 0.5f);
                    }

                    captureDevice.UnlockForConfiguration();
                }
                else
                {
                    Console.WriteLine("Failed to Lock for Config: " + err.Description);
                }
            }

            return(true);
        }
        bool SetupCaptureSession()
        {
            // configure the capture session for low resolution, change this if your code
            // can cope with more data or volume
            session = new AVCaptureSession()
            {
                SessionPreset = AVCaptureSession.Preset640x480
            };

            // create a device input and attach it to the session
//			var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video);
            AVCaptureDevice captureDevice = null;
            var             devices       = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);

            foreach (var device in devices)
            {
                captureDevice = device;
                if (options.UseFrontCameraIfAvailable.HasValue &&
                    options.UseFrontCameraIfAvailable.Value &&
                    device.Position == AVCaptureDevicePosition.Front)
                {
                    break;                     //Front camera successfully set
                }
                else if (device.Position == AVCaptureDevicePosition.Back && (!options.UseFrontCameraIfAvailable.HasValue || !options.UseFrontCameraIfAvailable.Value))
                {
                    break;                     //Back camera succesfully set
                }
            }
            if (captureDevice == null)
            {
                Console.WriteLine("No captureDevice - this won't work on the simulator, try a physical device");
                if (overlayView != null)
                {
                    this.AddSubview(overlayView);
                    this.BringSubviewToFront(overlayView);
                }
                return(false);
            }

            var input = AVCaptureDeviceInput.FromDevice(captureDevice);

            if (input == null)
            {
                Console.WriteLine("No input - this won't work on the simulator, try a physical device");
                if (overlayView != null)
                {
                    this.AddSubview(overlayView);
                    this.BringSubviewToFront(overlayView);
                }
                return(false);
            }
            else
            {
                session.AddInput(input);
            }


            foundResult = false;
            //Detect barcodes with built in avcapture stuff
            AVCaptureMetadataOutput metadataOutput = new AVCaptureMetadataOutput();

            var dg = new CaptureDelegate(metaDataObjects =>
            {
                if (foundResult)
                {
                    return;
                }

                //Console.WriteLine("Found MetaData Objects");

                var mdo = metaDataObjects.FirstOrDefault();

                if (mdo == null)
                {
                    return;
                }

                var readableObj = mdo as AVMetadataMachineReadableCodeObject;

                if (readableObj == null)
                {
                    return;
                }

                foundResult = true;

                //Console.WriteLine("Barcode: " + readableObj.StringValue);

                var zxingFormat = ZXingBarcodeFormatFromAVCaptureBarcodeFormat(readableObj.Type.ToString());

                var rs = new ZXing.Result(readableObj.StringValue, null, null, zxingFormat);

                resultCallback(rs);
            });

            metadataOutput.SetDelegate(dg, MonoTouch.CoreFoundation.DispatchQueue.MainQueue);
            session.AddOutput(metadataOutput);

            //Setup barcode formats
            if (ScanningOptions.PossibleFormats != null && ScanningOptions.PossibleFormats.Count > 0)
            {
                var formats = new List <string> ();

                foreach (var f in ScanningOptions.PossibleFormats)
                {
                    formats.AddRange(AVCaptureBarcodeFormatFromZXingBarcodeFormat(f));
                }

                metadataOutput.MetadataObjectTypes = (from f in formats.Distinct() select new NSString(f)).ToArray();
            }
            else
            {
                metadataOutput.MetadataObjectTypes = metadataOutput.AvailableMetadataObjectTypes;
            }



            previewLayer = new AVCaptureVideoPreviewLayer(session);

            //Framerate set here (15 fps)
            if (previewLayer.RespondsToSelector(new Selector("connection")))
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0))
                {
                    var perf1 = PerformanceCounter.Start();

                    NSError lockForConfigErr = null;

                    captureDevice.LockForConfiguration(out lockForConfigErr);
                    if (lockForConfigErr == null)
                    {
                        captureDevice.ActiveVideoMinFrameDuration = new CMTime(1, 10);
                        captureDevice.UnlockForConfiguration();
                    }

                    PerformanceCounter.Stop(perf1, "PERF: ActiveVideoMinFrameDuration Took {0} ms");
                }
                else
                {
                    previewLayer.Connection.VideoMinFrameDuration = new CMTime(1, 10);
                }
            }

            previewLayer.LayerVideoGravity = AVLayerVideoGravity.ResizeAspectFill;
            previewLayer.Frame             = new RectangleF(0, 0, this.Frame.Width, this.Frame.Height);
            previewLayer.Position          = new PointF(this.Layer.Bounds.Width / 2, (this.Layer.Bounds.Height / 2));

            layerView = new UIView(new RectangleF(0, 0, this.Frame.Width, this.Frame.Height));
            layerView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
            layerView.Layer.AddSublayer(previewLayer);

            this.AddSubview(layerView);

            ResizePreview(UIApplication.SharedApplication.StatusBarOrientation);

            if (overlayView != null)
            {
                this.AddSubview(overlayView);
                this.BringSubviewToFront(overlayView);

                //overlayView.LayoutSubviews ();
            }

            session.StartRunning();

            Console.WriteLine("RUNNING!!!");



            //output.AlwaysDiscardsLateVideoFrames = true;


            Console.WriteLine("SetupCamera Finished");

            //session.AddOutput (output);
            //session.StartRunning ();


            if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ModeContinuousAutoFocus))
            {
                NSError err = null;
                if (captureDevice.LockForConfiguration(out err))
                {
                    if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ModeContinuousAutoFocus))
                    {
                        captureDevice.FocusMode = AVCaptureFocusMode.ModeContinuousAutoFocus;
                    }
                    else if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ModeAutoFocus))
                    {
                        captureDevice.FocusMode = AVCaptureFocusMode.ModeAutoFocus;
                    }

                    if (captureDevice.IsExposureModeSupported(AVCaptureExposureMode.ContinuousAutoExposure))
                    {
                        captureDevice.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure;
                    }
                    else if (captureDevice.IsExposureModeSupported(AVCaptureExposureMode.AutoExpose))
                    {
                        captureDevice.ExposureMode = AVCaptureExposureMode.AutoExpose;
                    }

                    if (captureDevice.IsWhiteBalanceModeSupported(AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance))
                    {
                        captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance;
                    }
                    else if (captureDevice.IsWhiteBalanceModeSupported(AVCaptureWhiteBalanceMode.AutoWhiteBalance))
                    {
                        captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.AutoWhiteBalance;
                    }

                    if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
                    {
                        captureDevice.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near;
                    }

                    if (captureDevice.FocusPointOfInterestSupported)
                    {
                        captureDevice.FocusPointOfInterest = new PointF(0.5f, 0.5f);
                    }

                    if (captureDevice.ExposurePointOfInterestSupported)
                    {
                        captureDevice.ExposurePointOfInterest = new PointF(0.5f, 0.5f);
                    }

                    captureDevice.UnlockForConfiguration();
                }
                else
                {
                    Console.WriteLine("Failed to Lock for Config: " + err.Description);
                }
            }

            return(true);
        }