/// <summary>
        /// Dispose.
        /// </summary>
        /// <param name="disposing">
        /// Disposing parameter.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // Free other state (managed objects).
                }

                // Free your own state (unmanaged objects).
                // Set large fields to null.

                if (_searchLiveData != null)
                {
                    _searchLiveData.Dispose();
                    _searchLiveData = null;
                }

                if (_searchLiveOverlapData != null)
                {
                    _searchLiveOverlapData.Dispose();
                    _searchLiveOverlapData = null;
                }

                disposed = true;
            }
        }
        private void VideoCapture1_OnVideoFrameBuffer(object sender, SampleGrabberBufferCBEventArgs e)
        {
            try
            {
                if (_stopFlag)
                {
                    return;
                }

                Dispatcher.BeginInvoke(new NewFrameDelegate(NewFrameDelegateMethod), e);

                if (_tempBuffer == IntPtr.Zero)
                {
                    _tempBuffer = Marshal.AllocCoTaskMem(ImageHelper.GetStrideRGB24(e.Width) * e.Height);
                }

                // live
                if (_searchLiveData == null)
                {
                    _searchLiveData = new FingerprintLiveData(TimeSpan.FromMilliseconds(_fragmentDuration), DateTime.Now);
                    _fragmentCount++;
                }

                long timestamp = (long)(e.SampleTime * 1000);
                if (timestamp < _fragmentDuration * _fragmentCount)
                {
                    ImageHelper.CopyMemory(_tempBuffer, e.Buffer, e.BufferLen);

                    // process frame to remove ignored areas
                    if (_ignoredAreas.Count > 0)
                    {
                        foreach (var area in _ignoredAreas)
                        {
                            if (area.Right > e.Width || area.Bottom > e.Height)
                            {
                                continue;
                            }

                            MFP.FillColor(_tempBuffer, e.Width, e.Height, area, 0);
                        }
                    }

                    VFPSearch.Process(_tempBuffer, e.Width, e.Height, ImageHelper.GetStrideRGB24(e.Width), TimeSpan.FromMilliseconds(timestamp), ref _searchLiveData.Data);
                }
                else
                {
                    _fingerprintQueue.Enqueue(_searchLiveData);

                    _searchLiveData = null;

                    Dispatcher.BeginInvoke(new ProcessVideoDelegate(ProcessVideoDelegateMethod));
                }

                // overlap
                if (timestamp < _fragmentDuration / 2)
                {
                    return;
                }

                if (_searchLiveOverlapData == null)
                {
                    _searchLiveOverlapData = new FingerprintLiveData(TimeSpan.FromSeconds(_fragmentDuration), DateTime.Now);
                    _overlapFragmentCount++;
                }

                if (timestamp < _fragmentDuration * _overlapFragmentCount + _fragmentDuration / 2)
                {
                    ImageHelper.CopyMemory(_tempBuffer, e.Buffer, e.BufferLen);
                    VFPSearch.Process(_tempBuffer, e.Width, e.Height, ImageHelper.GetStrideRGB24(e.Width), TimeSpan.FromMilliseconds(timestamp), ref _searchLiveOverlapData.Data);
                }
                else
                {
                    _fingerprintQueue.Enqueue(_searchLiveOverlapData);

                    _searchLiveOverlapData = null;

                    Dispatcher.BeginInvoke(new ProcessVideoDelegate(ProcessVideoDelegateMethod));
                }
            }
            catch
            {
            }
        }
        private void ProcessVideoDelegateMethod()
        {
            lock (_processingLock)
            {
                //if (VideoCapture1.Status == VFVideoCaptureStatus.Free)
                //{
                //    return;
                //}

                //// done. searching for fingerprints.
                //VideoCapture1.Stop();

                long n;
                FingerprintLiveData fingerprint = null;

                if (_fingerprintQueue.TryDequeue(out fingerprint))
                {
                    IntPtr p = VFPSearch.Build(out n, ref fingerprint.Data);

                    VFPFingerPrint fvp = new VFPFingerPrint()
                    {
                        Data             = new byte[n],
                        OriginalFilename = string.Empty
                    };

                    Marshal.Copy(p, fvp.Data, 0, (int)n);

                    foreach (var ad in _adVFPList)
                    {
                        var positions = VFPAnalyzer.Search(ad, fvp, ad.Duration, (int)slDifference.Value, true);

                        if (positions.Count > 0)
                        {
                            foreach (var pos in positions)
                            {
                                DateTime tm = fingerprint.StartTime.AddMilliseconds(pos.TotalMilliseconds);

                                bool duplicate = false;
                                foreach (var detectedAd in _results)
                                {
                                    long time = 0;

                                    if (detectedAd.Timestamp > tm)
                                    {
                                        time = (long)(detectedAd.Timestamp - tm).TotalMilliseconds;
                                    }
                                    else
                                    {
                                        time = (long)(tm - detectedAd.Timestamp).TotalMilliseconds;
                                    }

                                    if (time < 1000)
                                    {
                                        // duplicate
                                        duplicate = true;
                                        break;
                                    }
                                }

                                if (duplicate)
                                {
                                    break;
                                }

                                _results.Add(new DetectedAd(tm));
                                resultsView.Add(
                                    new ResultsViewModel()
                                {
                                    Sample      = ad.OriginalFilename,
                                    TimeStamp   = tm.ToString("HH:mm:ss.fff"),
                                    TimeStampMS = tm - new DateTime(1970, 1, 1)
                                });
                            }
                        }
                    }

                    fingerprint.Data.Free();
                    fingerprint.Dispose();
                }
            }
        }