Example #1
0
        void queueFrameCallbackMethod(IntPtr userPtr, uint userData, QCamM_Err errcode, uint flags)
        {
            int state = Interlocked.CompareExchange(ref queueFrameReentranceState,
                                                    QFRS_IN_CALLBACK, QFRS_NONE);

            if (state != QFRS_NONE)
            {
                string msg = callback_thread_msg + CheckCurrentThread() + " @start";
                if (CrashIfCallbackReEntranceDetected)
                {
                    throw new Exception(msg);
                }
                else
                {
                    Trace.TraceError(msg);
                }
            }
            else
            {
                CheckCurrentThread();
            }

            if (disposeSignal.Wait(0))
            {
                return;
            }

            queueFrameCallbackErr = unchecked ((int)errcode);
            int         bufferIdx = checked ((int)userData);
            QCamM_Frame qCamFrame = qCamFrameBuffers[bufferIdx];


            bool ok = RingBufferForOutput.TryCopyIn <QCamM_Frame, VideoFrame>(copierDelegate, qCamFrame);

            if (!ok)
            {
                Trace.Write("!");
            }

            // re-insert buffer into the driver's queue
            QueueFrame(bufferIdx, qCamFrame.bufferSize);

            state = Interlocked.CompareExchange(ref queueFrameReentranceState,
                                                QFRS_NONE, QFRS_IN_CALLBACK);

            if (state != QFRS_IN_CALLBACK)
            {
                string msg = callback_thread_msg + CheckCurrentThread() + " @end";
                if (CrashIfCallbackReEntranceDetected)
                {
                    throw new Exception("QCam callback is re-entrant (end");
                }
                else
                {
                    Trace.TraceError(msg);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Copies data from QCam frame data structure to standardized VideoFrame structure
        /// which can be serialized over the wire
        /// </summary>
        void CopyDataForOutput(QCamM_Frame qFrame, VideoFrame outFrame)
        {
            outFrame.ErrorCode    = qFrame.errorCode;
            outFrame.BitsPerPixel = qFrame.bits;
            outFrame.Width        = qFrame.width;
            outFrame.Height       = qFrame.height;
            lock (odometerLock)
            {
                uint newOdo      = CounterUtils.UnwrapRolledCounter(QCam_counter_bits, odometer, qFrame.frameNumber);
                long nFrameDrops = newOdo - (long)odometer - 1;
                if (nFrameDrops > 0)
                {
                    Trace.TraceWarning("QCam driver dropped {0} frames!", nFrameDrops);
                }
                odometer             = newOdo;
                outFrame.FrameNumber = newOdo;
            }
            outFrame.TimeStamp = qFrame.timeStamp;

            IntPtr pSrc = qFrame.pBuffer;

            if (pSrc == IntPtr.Zero)
            {
                throw new ArgumentException("Got QCam frame buffer with null data pointer");
            }

            uint nBytes = qFrame.size;

            outFrame.DataSizeBytes = nBytes;

            // if there is data available, there's a buffer of the correct size, and copy it
            if (nBytes > 0)
            {
                byte[] buffer = outFrame.Data;
                if ((buffer == null) || (buffer.Length != nBytes))
                {
                    buffer = new byte[nBytes];
                }

                Lab.Utilities.CopyPointerToBuffer(pSrc, buffer, 0, nBytes);

                outFrame.Data = buffer;
            }
            else
            {
                outFrame.Data = new byte[0];
                Trace.TraceWarning("Sending empty frame!");
            }
        }
Example #3
0
        /// <summary>
        /// Preps a frame buffer and inserts it into the QCam streaming queue
        /// </summary>
        void QueueFrame(int frameNum, uint dataSize)
        {
            if ((frameNum < 0) || (dataSize < 1))
            {
                throw new ArgumentOutOfRangeException();
            }

            if (disposeSignal.Wait(0))
            {
                return;
            }

            QCamM_Frame frame = qCamFrameBuffers[frameNum];

            // check that buffer exists and is sized correctly
            if (frame == null)
            {
                frame = new QCamM_Frame();
                qCamFrameBuffers[frameNum] = frame;
            }
            if (frame.bufferSize != dataSize)
            {
                // release existing buffer, if present
                if (frame.pBuffer != IntPtr.Zero)
                {
                    xq.QCamM_Free(frame.pBuffer);
                }

                // update buffer size
                frame.bufferSize = (uint)dataSize;
                frame.pBuffer    = xq.QCamM_Malloc((uint)dataSize);
                if (frame.pBuffer == IntPtr.Zero)
                {
                    Trace.TraceError("QCam_malloc returned a null pointer!");
                    return;
                }
            }
            var err = xq.QCamM_QueueFrame(camera, frame,
                                          queueFrameCallbackDelegate, (uint)QCamM_qcCallbackFlags.qcCallbackDone,
                                          IntPtr.Zero, (uint)frameNum);

            if (err != QCamM_Err.qerrSuccess)
            {
                Trace.TraceWarning("QCamM_QueueFrame returned " + err.ToString());
            }
        }