internal void AddFrame(WriteableBitmap bitmap)
        {
            INSSBuffer sampleBuffer = null;

            if (BitmapBounds.Width != bitmap.Width)
            {
                Guid  mediaSubType;
                short bitCount;

                BitmapBounds = new Rectangle(0, 0, (int)bitmap.Width, (int)bitmap.Height);
                GetMediaType(bitmap.Format, out mediaSubType, out bitCount);
                ConfigureMediaWriter(BitmapBounds.Width, BitmapBounds.Height, mediaSubType, bitCount);
                MediaWriterConfigured = true;

                if (!MediaWriterIsWriting)
                {
                    MediaWriter.BeginWriting();
                    MediaWriterIsWriting = true;
                }
            }

            try
            {
                // Compute size of bitmap in bytes.  Strides may be negative.
                int bitmapSize = Math.Abs(bitmap.BackBufferStride * (int)bitmap.Height);

                IntPtr framePointer;

                // Get a sample interface
                MediaWriter.AllocateSample(bitmapSize, out sampleBuffer);

                // Get the buffer from the sample interface.  This is
                // where we copy the bitmap data to
                sampleBuffer.GetBuffer(out framePointer);

                // Copy the bitmap data into the sample buffer
                CopyFrame(bitmap.BackBuffer, framePointer, bitmapSize);

                // Write the sample to the output - Sometimes, for reasons I can't explain,
                // writing a sample fails.  However, writing the same sample again
                // works.  Go figure.
                int iRetry = 0;
                do
                {
                    try
                    {
                        MediaWriter.WriteSample(VideoChannelIndex, 10000 * CurrentSampleTimeStamp, SampleFlag.CleanPoint, sampleBuffer);
                        break;
                    }
                    catch (COMException e)
                    {
                        if ((iRetry++ < 3) && (e.ErrorCode != NSResults.E_INVALID_DATA))
                        {
                            continue;
                        }
                        else
                        {
                            throw;
                        }
                    }
                } while (true);

                // update the time based on the framerate
                CurrentSampleTimeStamp = (++CurrentSampleIndex * 1000) / Constants.VideoFrameRate;
            }
            finally
            {
                // Release the locals
                if (sampleBuffer != null)
                {
                    Marshal.ReleaseComObject(sampleBuffer);
                    sampleBuffer = null;
                }
            }
        }