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; } } }