/// <summary> /// Add a frame to the output file /// </summary> /// <param name="hBitmap">Frame to add</param> public void AppendNewFrame(Bitmap hBitmap) { int hr = 0; INSSBuffer pSample = null; Rectangle r = new Rectangle(0, 0, hBitmap.Width, hBitmap.Height); BitmapData bmd; if (!m_Init) { // Only call this for the first frame Initialize(hBitmap); } // Lock the bitmap, which gets us a pointer to the raw bitmap data bmd = hBitmap.LockBits(r, ImageLockMode.ReadOnly, hBitmap.PixelFormat); try { // Compute size of bitmap in bytes. Strides may be negative. int iSize = Math.Abs(bmd.Stride * bmd.Height); IntPtr ip; // Get a sample interface hr = m_pWMWriter.AllocateSample(iSize, out pSample); Marshal.ThrowExceptionForHR(hr); // Get the buffer from the sample interface. This is // where we copy the bitmap data to hr = pSample.GetBuffer(out ip); Marshal.ThrowExceptionForHR(hr); // Copy the bitmap data into the sample buffer LoadSample(bmd, ip, iSize); // 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 { hr = m_pWMWriter.WriteSample(m_dwVideoInput, 10000 * m_msVideoTime, WriteFlags.CleanPoint, pSample); } while (hr == NSResults.E_InvalidData && iRetry++ < 3); Marshal.ThrowExceptionForHR(hr); // update the time based on the framerate m_msVideoTime = (++m_dwCurrentVideoSample * 1000) / m_iFrameRate; } finally { // Release the locals if (pSample != null) { Marshal.ReleaseComObject(pSample); pSample = null; } hBitmap.UnlockBits(bmd); } }
private void TestBuffer() { IntPtr ip, ip2; int l; m_pSample.GetBuffer(out ip); Debug.Assert(ip != IntPtr.Zero); m_pSample.GetBufferAndLength(out ip2, out l); Debug.Assert(ip == ip2); Debug.Assert(l == 12); }
public int Read(AudioBuffer buff, int maxLength) { buff.Prepare(this, maxLength); int buff_offset = 0; int buff_size = buff.ByteLength; while (m_pSampleSize < buff_size) { if (m_pSampleSize > 0) { IntPtr pdwBuffer; m_pSample.GetBuffer(out pdwBuffer); Marshal.Copy((IntPtr)(pdwBuffer.ToInt64() + m_pSampleOffset), buff.Bytes, buff_offset, m_pSampleSize); buff_size -= m_pSampleSize; buff_offset += m_pSampleSize; m_sampleOffset += m_pSampleSize; m_pSampleSize = 0; Marshal.ReleaseComObject(m_pSample); m_pSample = null; } long cnsSampleTime; long cnsDuration; SampleFlag flags; int dwOutputNum; short wStreamNum; try { m_syncReader.GetNextSample(m_wStreamNum, out m_pSample, out cnsSampleTime, out cnsDuration, out flags, out dwOutputNum, out wStreamNum); } catch (COMException ex) { // EOF if (ex.ErrorCode == NSResults.E_NO_MORE_SAMPLES) { if ((m_sampleOffset % PCM.BlockAlign) != 0) { throw new Exception("(m_sampleOffset % PCM.BlockAlign) != 0"); } m_sampleCount = m_sampleOffset / PCM.BlockAlign; if ((buff_offset % PCM.BlockAlign) != 0) { throw new Exception("(buff_offset % PCM.BlockAlign) != 0"); } return(buff.Length = buff_offset / PCM.BlockAlign); } throw ex; } //if (dwOutputNum != m_dwAudioOutputNum || wStreamNum != m_wStreamNum) //{ //} m_pSampleOffset = 0; m_pSample.GetLength(out m_pSampleSize); } if (buff_size > 0) { IntPtr pdwBuffer; m_pSample.GetBuffer(out pdwBuffer); Marshal.Copy((IntPtr)(pdwBuffer.ToInt64() + m_pSampleOffset), buff.Bytes, buff_offset, buff_size); m_pSampleOffset += buff_size; m_pSampleSize -= buff_size; m_sampleOffset += buff_size; buff_offset += buff_size; buff_size = 0; } if ((buff_offset % PCM.BlockAlign) != 0) { throw new Exception("(buff_offset % PCM.BlockAlign) != 0"); } return(buff.Length = buff_offset / PCM.BlockAlign); }
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; } } }