public static unsafe byte[] convertToGrayscale(SoftwareBitmap bitmap, out int width, out int height)
        {
            width  = 0;
            height = 0;
            byte[] returnArray = null;

            //if (pauseDecoder) return returnArray; //this is done in proxy.js

            Debug.WriteLine("Active Threads now: " + aThreads);
            law_n_order.WaitOne();
            if ((aThreads + convertedQueue.Count) < maxThreads) //old: if (aThreads < nThreads && convertedQueue.Count == 0)
            {
                //aThreads = nThreads; //just test one frame

                aThreads++;

                //spawn a new thread
                BackgroundWorker bWorker = new BackgroundWorker();
                bWorker.WorkerReportsProgress      = false;
                bWorker.WorkerSupportsCancellation = false;
                bWorker.DoWork             += new DoWorkEventHandler(bWorker_DoWork);
                bWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bWorker_RunWorkerCompleted);
                bWorker.RunWorkerAsync(bitmap);
            }
            else
            {
                //skip this frame
            }

            if (convertedQueue.Count > 0)
            {
                conversionResult cResult = convertedQueue.Dequeue();
                width       = cResult.width;
                height      = cResult.height;
                returnArray = cResult.returnArray;
            }
            law_n_order.ReleaseMutex();

            //special case handling because js doesn't see it as null
            if (returnArray == null)
            {
                returnArray = new byte[1] {
                    0
                };
            }

            return(returnArray);
        }
        public static MWResult decodeFrame([ReadOnlyArray()] byte[] returnArray, int width, int height)//, out MWResult mwResult)
        {
            MWResult mwResult = null;

            if (returnArray == null)
            {
                return(mwResult);
            }
            //Debug.WriteLine("In DecodeFrame: " + ("\n\taThreads: ") + aThreads + "\tconv_count: " + convertedQueue.Count); //tconv_count always 0, thats why
            law_n_order.WaitOne();
            if (aThreads < maxThreads) //rm && convertedQueue.Count > 0 thaaank you
            {
                aThreads++;

                conversionResult cData = new conversionResult();
                cData.width       = width;
                cData.height      = height;
                cData.returnArray = returnArray;

                //spawn a new thread
                BackgroundWorker bWorkerX = new BackgroundWorker();
                bWorkerX.WorkerReportsProgress      = false;
                bWorkerX.WorkerSupportsCancellation = false;
                bWorkerX.DoWork             += new DoWorkEventHandler(bWorkerX_DoWork);
                bWorkerX.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bWorkerX_RunWorkerCompleted);
                bWorkerX.RunWorkerAsync(cData);
            }

            if (decodedQueue.Count > 0)
            {
                mwResult = decodedQueue.Dequeue();

                //reset/clear up
                iniClear();
                //Debug.WriteLine("found it!");
            }
            law_n_order.ReleaseMutex();

            return(mwResult);
        }
        private static unsafe void bWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            byte *data     = null;
            uint  capacity = 0;

            SoftwareBitmap bitmap = e.Argument as SoftwareBitmap; //could check for null
            int            width  = 0;
            int            height = 0;

            byte[] returnArray = null;

            // Effect is hard-coded to operate on BGRA8 format only
            if (bitmap.BitmapPixelFormat == BitmapPixelFormat.Bgra8 || bitmap.BitmapPixelFormat == BitmapPixelFormat.Nv12 ||
                bitmap.BitmapPixelFormat == BitmapPixelFormat.Yuy2 || bitmap.BitmapPixelFormat == BitmapPixelFormat.Gray8)
            {
                // In BGRA8 format, each pixel is defined by 4 bytes
                int BYTES_PER_PIXEL = 4;

                using (var buffer = bitmap.LockBuffer(BitmapBufferAccessMode.ReadWrite))
                    using (IMemoryBufferReference reference = buffer.CreateReference())
                    {
                        if (reference is IMemoryBufferByteAccess)
                        {
                            // Get a pointer to the pixel buffer
                            ((IMemoryBufferByteAccess)reference).GetBuffer(out data, out capacity);
                            var desc = buffer.GetPlaneDescription(0);
                            width       = desc.Width;
                            height      = desc.Height;
                            returnArray = new byte[desc.Width * desc.Height];
                            if (bitmap.BitmapPixelFormat == BitmapPixelFormat.Yuy2)
                            {
                                int length = desc.Width * desc.Height;
                                for (int i = 0; i < length; i++)
                                {
                                    returnArray[i] = data[i << 1];
                                }
                            }
                            else
                            if (bitmap.BitmapPixelFormat == BitmapPixelFormat.Nv12 || bitmap.BitmapPixelFormat == BitmapPixelFormat.Gray8)
                            {
                                Marshal.Copy((IntPtr)data, returnArray, 0, desc.Width * desc.Height);
                            }
                            else

                            if (bitmap.BitmapPixelFormat == BitmapPixelFormat.Bgra8)
                            {
                                BYTES_PER_PIXEL = 4;

                                // Get information about the BitmapBuffer

                                // Iterate over all pixels
                                width  = desc.Width;
                                height = desc.Height;
                                for (uint row = 0; row < desc.Height; row++)
                                {
                                    for (uint col = 0; col < desc.Width; col++)
                                    {
                                        // Index of the current pixel in the buffer (defined by the next 4 bytes, BGRA8)
                                        var currPixel = desc.StartIndex + desc.Stride * row + BYTES_PER_PIXEL * col;

                                        // Read the current pixel information into b,g,r channels (leave out alpha channel)
                                        var b = data[currPixel + 0]; // Blue
                                        var g = data[currPixel + 1]; // Green
                                        var r = data[currPixel + 2]; // Red

                                        int y = (r * 77) + (g * 151) + (b * 28) >> 8;

                                        /*
                                         *                              data[currPixel + 0] = (byte)y;
                                         *                              data[currPixel + 1] = (byte)y;
                                         *                              data[currPixel + 2] = (byte)y;
                                         */
                                        returnArray[row * desc.Width + col] = (byte)y;
                                    }
                                }
                            }
                        }
                    }
            }

            conversionResult cResult = new conversionResult();

            cResult.width       = width;
            cResult.height      = height;
            cResult.returnArray = returnArray;

            law_n_order.WaitOne();
            convertedQueue.Enqueue(cResult);
            law_n_order.ReleaseMutex();
            //throw new NotImplementedException();
        }