/// <summary> /// Disposes the <see cref="MFResampler"/> object. /// </summary> public void Dispose() { if (this.resampler != null) { Marshal.ReleaseComObject(this.resampler); this.resampler = null; } if (this.inputBuffer != null) { Marshal.ReleaseComObject(this.inputBuffer); this.inputBuffer = null; } if (this.inputSample != null) { Marshal.ReleaseComObject(this.inputSample); this.inputSample = null; } if (this.outputBuffer != null) { Marshal.ReleaseComObject(this.outputBuffer); this.outputBuffer = null; } if (this.outputSample != null) { Marshal.ReleaseComObject(this.outputSample); this.outputSample = null; } }
// Token: 0x06000945 RID: 2373 RVA: 0x0001B0A0 File Offset: 0x000192A0 private long ConvertOneBuffer(IMFSinkWriter writer, int streamIndex, IWaveProvider inputProvider, long position, byte[] managedBuffer) { long num = 0L; IMFMediaBuffer imfmediaBuffer = MediaFoundationApi.CreateMemoryBuffer(managedBuffer.Length); int count; imfmediaBuffer.GetMaxLength(out count); IMFSample imfsample = MediaFoundationApi.CreateSample(); imfsample.AddBuffer(imfmediaBuffer); IntPtr destination; int num2; imfmediaBuffer.Lock(out destination, out count, out num2); int num3 = inputProvider.Read(managedBuffer, 0, count); if (num3 > 0) { num = MediaFoundationEncoder.BytesToNsPosition(num3, inputProvider.WaveFormat); Marshal.Copy(managedBuffer, 0, destination, num3); imfmediaBuffer.SetCurrentLength(num3); imfmediaBuffer.Unlock(); imfsample.SetSampleTime(position); imfsample.SetSampleDuration(num); writer.WriteSample(streamIndex, imfsample); } else { imfmediaBuffer.Unlock(); } Marshal.ReleaseComObject(imfsample); Marshal.ReleaseComObject(imfmediaBuffer); return(num); }
private bool ConsumeBuffer(IMFMediaBuffer buff, MediaItem item) { buff.Lock(out IntPtr ptr, out int maxLen, out int curLen); try { try { byte[] temp = new byte[curLen]; Marshal.Copy(ptr, temp, 0, temp.Length); int stride = item.Width * 3; int tmpheight = item.Height; BitmapSource src = BitmapSource.Create(item.Width, tmpheight, 600, 600, PixelFormats.Bgr24, null, temp, stride); image.Source = src; return(true); } catch (ObjectDisposedException) { return(false); } } finally { buff.Unlock(); } }
/// <summary> /// Use Source Reader to allocate a sample /// </summary> /// <param name="sourceReader">The Source Reader</param> /// <param name="dwStreamIndex">The stream to pull data from</param> /// <param name="dwControlFlags">A bitwise OR of zero or more flags from the MF_SOURCE_READER_CONTROL_FLAG enumeration</param> /// <param name="pdwActualStreamIndex">Receives the zero-based index of the stream</param> /// <param name="pdwStreamFlags">Receives a bitwise OR of zero or more flags from the MF_SOURCE_READER_FLAG enumeration</param> /// <param name="pllTimestamp">Receives the time stamp of the sample, or the time of the stream event indicated in pdwStreamFlags. The time is given in 100-nanosecond units</param> public void ReadSampleFrom( IMFSourceReader sourceReader, uint dwStreamIndex, uint dwControlFlags, out uint pdwActualStreamIndex, out uint pdwStreamFlags, out ulong pllTimestamp) { // Once a sample is read avoid reading more samples if (this.read) { throw new InvalidOperationException("Already holding a sample"); } sourceReader.ReadSample(dwStreamIndex, dwControlFlags, out pdwActualStreamIndex, out pdwStreamFlags, out pllTimestamp, out this.sample); if (this.sample != null) { // Get the size of the media sample in bytes IMFMediaBuffer buffer = null; this.sample.GetBufferByIndex(0, out buffer); buffer.GetCurrentLength(out this.bufferSize); // Add the memory pressure of unmanaged memory to improve the garbage collector performance GC.AddMemoryPressure(this.bufferSize); } this.read = true; }
// Token: 0x06000A59 RID: 2649 RVA: 0x0001E1A8 File Offset: 0x0001C3A8 private IMFSample ReadFromSource() { int num = this.sourceProvider.Read(this.sourceBuffer, 0, this.sourceBuffer.Length); if (num == 0) { return(null); } IMFMediaBuffer imfmediaBuffer = MediaFoundationApi.CreateMemoryBuffer(num); IntPtr destination; int num2; int num3; imfmediaBuffer.Lock(out destination, out num2, out num3); Marshal.Copy(this.sourceBuffer, 0, destination, num); imfmediaBuffer.Unlock(); imfmediaBuffer.SetCurrentLength(num); IMFSample imfsample = MediaFoundationApi.CreateSample(); imfsample.AddBuffer(imfmediaBuffer); imfsample.SetSampleTime(this.inputPosition); long num4 = MediaFoundationTransform.BytesToNsPosition(num, this.sourceProvider.WaveFormat); imfsample.SetSampleDuration(num4); this.inputPosition += num4; Marshal.ReleaseComObject(imfmediaBuffer); return(imfsample); }
public static byte[] GetDataFromMediaSample(IMFSample sample) { IMFMediaBuffer pMediaBuffer = null; IntPtr pBuffer; int maxLen = 0, curLen = 0; //HResult hr = sample.LockStore(); HResult hr = sample.ConvertToContiguousBuffer(out pMediaBuffer); MFError.ThrowExceptionForHR(hr); try { hr = pMediaBuffer.Lock(out pBuffer, out maxLen, out curLen); MFError.ThrowExceptionForHR(hr); try { byte[] data = new byte[curLen]; Marshal.Copy(pBuffer, data, 0, curLen); return(data); } finally { hr = pMediaBuffer.Unlock(); } } finally { //hr = sample.UnlockStore(); COMBase.SafeRelease(pMediaBuffer); } }
public static extern HResult MFCreateDXGISurfaceBuffer2( [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, IntPtr punkSurface, int uSubresourceIndex, [MarshalAs(UnmanagedType.Bool)] bool fBottomUpWhenLinear, out IMFMediaBuffer ppBuffer );
// Get the buffers and sizes to be modified, then pass them // to the transform routine. private void DoWork(IMFMediaBuffer pIn, IMFMediaBuffer pOut) { IntPtr pSrc = IntPtr.Zero; int lSrcStride = 0; IMF2DBuffer pIn2D = null; // Lock the input buffer. Use IMF2DBuffer if available. Lockit(pIn, out pIn2D, out lSrcStride, out pSrc); try { IntPtr pDest; int mlo; int cb; MFError throwonhr = pOut.Lock(out pDest, out mlo, out cb); try { // Invoke the image transform function. YUY2_TO_RGB32(pSrc, pDest, m_imageWidthInPixels, m_imageHeightInPixels, lSrcStride); } finally { pOut.Unlock(); } } finally { // Ignore error UnlockIt(pSrc, pIn2D, pIn); } }
// Get the buffers and sizes to be modified, then pass them // to the appropriate Update_* routine. private void DoWork(IMFMediaBuffer pIn) { IntPtr pSrc = IntPtr.Zero; // Source buffer. int lSrcStride; // Source stride. IMF2DBuffer pIn2D = null; try { // Lock the input buffer. Use IMF2DBuffer if available. Lockit(pIn, out pIn2D, out lSrcStride, out pSrc); // Invoke the image transform function. if (m_pTransformFn != null) { m_pTransformFn(pSrc, lSrcStride, m_imageWidthInPixels, m_imageHeightInPixels); } else { throw new COMException("Transform type not set", (int)HResult.E_UNEXPECTED); } // Set the data size on the output buffer. MFError throwonhr = pIn.SetCurrentLength(m_cbImageSize); } finally { UnlockIt(pSrc, pIn2D, pIn); } }
public void ProcessingThread() { while (true) { m_SampleReady.WaitOne(); IMFMediaBuffer pInput = null; try { // Get the data buffer from the input sample. If the sample has // multiple buffers, you might be able to get (slightly) better // performance processing each buffer in turn rather than forcing // a new, full-sized buffer to get created. m_hr = InputSample.ConvertToContiguousBuffer(out pInput); if (Succeeded(m_hr)) { m_hr = DoWork(pInput); } } catch (Exception e) { m_hr = (HResult)Marshal.GetHRForException(e); } finally { // If (somewhere) there is .Net code that is holding on to an instance of // the same buffer as pInput, this will yank the RCW out from underneath // it, probably causing it to crash. But if we don't release it, our memory // usage explodes. SafeRelease(pInput); m_SampleDone.Set(); } } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Write the text on the output buffer /// </summary> /// <param name="outputMediaBuffer">Output buffer</param> /// <history> /// 01 Nov 18 Cynic - Ported In /// </history> private void WriteTextOnBuffer(IMFMediaBuffer outputMediaBuffer) { IntPtr destRawDataPtr = IntPtr.Zero; // Destination buffer. int destStride = 0; // Destination stride. bool destIs2D = false; try { // Lock the output buffer. Use the IMF2DBuffer interface // (if available) as it is faster if ((outputMediaBuffer is IMF2DBuffer) == false) { // not an IMF2DBuffer - get the raw data from the IMFMediaBuffer int maxLen = 0; int currentLen = 0; TantaWMFUtils.LockIMFMediaBufferAndGetRawData(outputMediaBuffer, out destRawDataPtr, out maxLen, out currentLen); // the stride is always this. The Lock function does not return it destStride = m_lStrideIfContiguous; } else { // we are an IMF2DBuffer, we get the stride here as well TantaWMFUtils.LockIMF2DBufferAndGetRawData((outputMediaBuffer as IMF2DBuffer), out destRawDataPtr, out destStride); destIs2D = true; } // count this now. We only use this to write it on the screen m_FrameCount++; // We could eventually offer the ability to write on other formats depending on the // current media type. We have this hardcoded to ARGB for now WriteImageOfTypeARGB(destRawDataPtr, destStride, m_imageWidthInPixels, m_imageHeightInPixels); // Set the data size on the output buffer. It probably is already there // since the output buffer is the input buffer HResult hr = outputMediaBuffer.SetCurrentLength(m_cbImageSize); if (hr != HResult.S_OK) { throw new Exception("WriteTextOnBuffer call to outputMediaBuffer.SetCurrentLength failed. Err=" + hr.ToString()); } } finally { // we MUST unlock if (destIs2D == false) { TantaWMFUtils.UnLockIMFMediaBuffer(outputMediaBuffer); } else { TantaWMFUtils.UnLockIMF2DBuffer((outputMediaBuffer as IMF2DBuffer)); } } }
// Constructor public VideoBufferLock(IMFMediaBuffer pBuffer) { m_p2DBuffer = null; m_bLocked = false; m_pBuffer = pBuffer; // Query for the 2-D buffer interface. OK if this fails. m_p2DBuffer = pBuffer as IMF2DBuffer; }
/// <summary> /// Disposes the <see cref="WasapiCaptureClient"/> object. /// </summary> public void Dispose() { if (this.captureThread != null) { this.shutdownEvent.Set(); this.captureThread.Join(); this.captureThread = null; } if (this.shutdownEvent != null) { this.shutdownEvent.Close(); this.shutdownEvent = null; } if (this.audioClient != null) { Marshal.ReleaseComObject(this.audioClient); this.audioClient = null; } if (this.captureClient != null) { Marshal.ReleaseComObject(this.captureClient); this.captureClient = null; } if (this.resampler != null) { Marshal.ReleaseComObject(this.resampler); this.resampler = null; } if (this.inputBuffer != null) { Marshal.ReleaseComObject(this.inputBuffer); this.inputBuffer = null; } if (this.inputSample != null) { Marshal.ReleaseComObject(this.inputSample); this.inputSample = null; } if (this.outputBuffer != null) { Marshal.ReleaseComObject(this.outputBuffer); this.outputBuffer = null; } if (this.outputSample != null) { Marshal.ReleaseComObject(this.outputSample); this.outputSample = null; } }
// Get the buffers and sizes to be modified, then pass them // to the appropriate Update_* routine. private HResult DoWork(IMFMediaBuffer pIn) { MFError throwonhr; int cb; IntPtr pSrc; // Source buffer. int lSrcStride = 0; // Source stride. bool bLockedInputBuffer = false; IMF2DBuffer pIn2D; // While there are exceptions thrown here, they should never happen // in real life. // Lock the input buffer. Use IMF2DBuffer if available. pIn2D = pIn as IMF2DBuffer; if (pIn2D != null) { throwonhr = pIn2D.Lock2D(out pSrc, out lSrcStride); } else { int ml; throwonhr = pIn.Lock(out pSrc, out ml, out cb); lSrcStride = m_lStrideIfContiguous; } bLockedInputBuffer = true; // Invoke the image transform function. if (m_pTransformFn != null) { m_pTransformFn(pSrc, lSrcStride, m_imageWidthInPixels, m_imageHeightInPixels); } else { return(HResult.E_UNEXPECTED); } if (bLockedInputBuffer) { if (pIn2D != null) { throwonhr = pIn2D.Unlock2D(); } else { throwonhr = pIn.Unlock(); } } // Set the data size on the output buffer. throwonhr = pIn.SetCurrentLength(m_cbImageSize); return(HResult.S_OK); }
// Constructor public VideoBufferLock(IMFMediaBuffer pBuffer) { p2DBuffer = null; bLocked = false; this.pBuffer = pBuffer; // Query for the 2-D buffer interface. OK if this fails. // ReSharper disable once SuspiciousTypeConversion.Global p2DBuffer = pBuffer as IMF2DBuffer; }
public static IntPtr Lock(this IMFMediaBuffer input, out uint maxLength, out uint currentLength) { if (input == null) { throw new ArgumentNullException(nameof(input)); } input.Lock(out var ptr, out maxLength, out currentLength).ThrowOnError(); return(ptr); }
public void Dispose() { UnlockBuffer(); SafeRelease(pBuffer); SafeRelease(p2DBuffer); pBuffer = null; p2DBuffer = null; GC.SuppressFinalize(this); }
private void invokeDecodeCompleteEvent(IMFMediaBuffer buffer) { try { OnSampleDecodeComplete?.Invoke(this, buffer); } catch { //todo: throw event to notify the client. } }
// IMFSourceReaderCallback methods //------------------------------------------------------------------- // OnReadSample // // Called when the IMFMediaSource::ReadSample method completes. //------------------------------------------------------------------- public int OnReadSample(int hrStatus, int dwStreamIndex, MF_SOURCE_READER_FLAG dwStreamFlags, long llTimestamp, IMFSample pSample) { var hr = hrStatus; IMFMediaBuffer pBuffer = null; lock (LockSync) { try { if (pSample != null) { // Get the video frame buffer from the sample. if (Succeeded(hr)) { hr = pSample.GetBufferByIndex(0, out pBuffer); } if (Succeeded(hr)) { hr = OnFrame(pSample, pBuffer, llTimestamp, snapFormat); snapFormat = string.Empty; } } // Request the next frame. if (Succeeded(hr)) { // Read next sample. hr = PReader.ReadSample( (int)MF_SOURCE_READER.FirstVideoStream, 0, IntPtr.Zero, // actual IntPtr.Zero, // flags IntPtr.Zero, // time stamp IntPtr.Zero // sample ); } if (Failed(hr)) { NotifyError(hr); } } finally { SafeRelease(pBuffer); SafeRelease(pSample); } } return(hr); }
private long ConvertOneBuffer(IMFSinkWriter writer, int streamIndex, IWaveProvider inputProvider, long position, byte[] managedBuffer, int seconds, ref bool flag) { long durationConverted = 0; int maxLength; IMFMediaBuffer buffer = MediaFoundationApi.CreateMemoryBuffer(managedBuffer.Length); buffer.GetMaxLength(out maxLength); IMFSample sample = MediaFoundationApi.CreateSample(); sample.AddBuffer(buffer); IntPtr ptr; int currentLength; buffer.Lock(out ptr, out maxLength, out currentLength); int oneLength = inputProvider.WaveFormat.AverageBytesPerSecond; int read = 0; if (flag) { for (int i = 0; i < seconds; i++) { read = inputProvider.Read(managedBuffer, 0, oneLength); } flag = false; } else { read = inputProvider.Read(managedBuffer, 0, oneLength); } if (read > 0) { durationConverted = BytesToNsPosition(read, inputProvider.WaveFormat); Marshal.Copy(managedBuffer, 0, ptr, read); buffer.SetCurrentLength(read); buffer.Unlock(); sample.SetSampleTime(position); sample.SetSampleDuration(durationConverted); writer.WriteSample(streamIndex, sample); //writer.Flush(streamIndex); } else { buffer.Unlock(); } Marshal.ReleaseComObject(sample); Marshal.ReleaseComObject(buffer); return(durationConverted); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Get the buffers and sizes to be modified, then pass them /// to the appropriate Update_* routine. /// </summary> /// <param name="inputMediaBuffer">the mediaBuffer</param> /// <history> /// 01 Nov 18 Cynic - Ported over /// </history> private void DoWork(IMFMediaBuffer inputMediaBuffer) { IntPtr srcRawDataPtr = IntPtr.Zero; // Source buffer. int srcStride; // Source stride. bool srcIs2D = false; try { // Lock the input buffer. Use the IMF2DBuffer interface // (if available) as it is faster if ((inputMediaBuffer is IMF2DBuffer) == false) { // not an IMF2DBuffer - get the raw data from the IMFMediaBuffer int maxLen = 0; int currentLen = 0; TantaWMFUtils.LockIMFMediaBufferAndGetRawData(inputMediaBuffer, out srcRawDataPtr, out maxLen, out currentLen); // the stride is always this. The Lock function does not return it srcStride = m_lStrideIfContiguous; } else { // we are an IMF2DBuffer, we get the stride here as well TantaWMFUtils.LockIMF2DBufferAndGetRawData((inputMediaBuffer as IMF2DBuffer), out srcRawDataPtr, out srcStride); srcIs2D = true; } // Invoke the image transform function. if (TransformImageFunction != null) { TransformImageFunction(srcRawDataPtr, srcStride, m_imageWidthInPixels, m_imageHeightInPixels); } else { throw new COMException("Transform type not set", (int)HResult.E_UNEXPECTED); } // Set the data size on the output buffer. MFError throwonhr = inputMediaBuffer.SetCurrentLength(m_cbImageSize); } finally { if (srcIs2D == false) { TantaWMFUtils.UnLockIMFMediaBuffer(inputMediaBuffer); } else { TantaWMFUtils.UnLockIMF2DBuffer((inputMediaBuffer as IMF2DBuffer)); } } }
public static HResult ConverToMediaBuffer(IBufferPacket packet, out IMFMediaBuffer mediaBuffer) { mediaBuffer = null; var dataLength = packet.GetLength(); if (packet == null || dataLength == 0) { return(HResult.E_INVALIDARG); } IMFMediaBuffer spMediaBuffer; HResult hr = MFExtern.MFCreateMemoryBuffer(dataLength, out spMediaBuffer); if (MFError.Failed(hr)) { return(hr); } IntPtr pBuffer; int cbMaxLength; int cbCurrentLength; //todo: call lock2d on a 2d buffer because the lock2d is more efficient. /* * if (MFError.Succeeded(Marshal.intp spMediaBuffer.QueryInterface(IID_PPV_ARGS(&_sp2DBuffer)))) * { * LONG lPitch; * hr = _sp2DBuffer.Lock2D(&_pBuffer, &lPitch); * } * else * { * hr = pMediaBuffer->Lock(&_pBuffer, &cbMaxLength, &cbCurrentLength); * }*/ hr = spMediaBuffer.Lock(out pBuffer, out cbMaxLength, out cbCurrentLength); if (MFError.Failed(hr)) { return(hr); } var buffer = packet.TakeBuffer(dataLength); Marshal.Copy(buffer, 0, pBuffer, buffer.Length); spMediaBuffer.SetCurrentLength(buffer.Length); spMediaBuffer.Unlock(); mediaBuffer = spMediaBuffer; buffer = null; return(hr); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// This is the routine that performs the transform. Assumes InputSample is set. /// /// An override of the abstract version in TantaMFTBase_Sync. /// </summary> /// <param name="outputSampleDataStruct">The structure to populate with output data.</param> /// <returns>S_Ok unless error.</returns> /// <history> /// 01 Nov 18 Cynic - Ported In /// </history> protected override HResult OnProcessOutput(ref MFTOutputDataBuffer outputSampleDataStruct) { HResult hr = HResult.S_OK; IMFMediaBuffer outputMediaBuffer = null; // we are processing in place, the input sample is the output sample, the media buffer of the // input sample is the media buffer of the output sample. try { // Get the data buffer from the input sample. If the sample contains more than one buffer, // this method copies the data from the original buffers into a new buffer, and replaces // the original buffer list with the new buffer. The new buffer is returned in the inputMediaBuffer parameter. // If the sample contains a single buffer, this method returns a pointer to the original buffer. // In typical use, most samples do not contain multiple buffers. hr = InputSample.ConvertToContiguousBuffer(out outputMediaBuffer); if (hr != HResult.S_OK) { throw new Exception("OnProcessOutput call to InputSample.ConvertToContiguousBuffer failed. Err=" + hr.ToString()); } // now that we have an output buffer, do the work to implement the appropriate rotate mode. // Writing into outputMediaBuffer will write to the approprate location in the outputSample FlipImageInBuffer(outputMediaBuffer); // increment this for the client/transform communications demonstrator code m_FrameCount++; // Set status flags. outputSampleDataStruct.dwStatus = MFTOutputDataBufferFlags.None; // The output sample is the input sample. We get a new IUnknown for the Input // sample since we are going to release it below. The client will release this // new IUnknown outputSampleDataStruct.pSample = Marshal.GetIUnknownForObject(InputSample); } finally { // clean up SafeRelease(outputMediaBuffer); // Release the current input sample so we can get another one. // the act of setting it to null releases it because the property // is coded that way InputSample = null; } return(HResult.S_OK); }
private static void UnlockIt(IntPtr pSrc, IMF2DBuffer pIn2D, IMFMediaBuffer pIn) { if (pSrc != IntPtr.Zero) { MFError throwonhr; if (pIn2D != null) { throwonhr = pIn2D.Unlock2D(); } else { throwonhr = pIn.Unlock(); } } }
private void Lockit(IMFMediaBuffer pOut, out IMF2DBuffer pOut2D, out int lDestStride, out IntPtr pDest) { MFError throwonhr; pOut2D = pOut as IMF2DBuffer; if (pOut2D != null) { throwonhr = pOut2D.Lock2D(out pDest, out lDestStride); } else { int ml; int cb; throwonhr = pOut.Lock(out pDest, out ml, out cb); lDestStride = m_lStrideIfContiguous; } }
// IMFSourceReaderCallback methods //------------------------------------------------------------------- // OnReadSample // // Called when the IMFMediaSource::ReadSample method completes. //------------------------------------------------------------------- public HResult OnReadSample(HResult hrStatus, int dwStreamIndex, MF_SOURCE_READER_FLAG dwStreamFlags, long llTimestamp, IMFSample pSample) { HResult hr = hrStatus; IMFMediaBuffer pBuffer = null; lock (this) { try { if (Succeeded(hr)) { if (pSample != null) { // Get the video frame buffer from the sample. hr = pSample.GetBufferByIndex(0, out pBuffer); // Draw the frame. if (Succeeded(hr)) { hr = m_draw.DrawFrame(pBuffer); } } } // Request the next frame. if (Succeeded(hr)) { // Ask for the first sample. hr = m_pReader.ReadSample((int)MF_SOURCE_READER.FirstVideoStream, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); } if (Failed(hr)) { NotifyError(hr); } } finally { //SafeRelease(pBuffer); SafeRelease(pSample); } } return(hr); }
private void invokeDecodeComplete(IMFMediaBuffer buffer, int bufferLen) { if (buffer == null) { return; } int len = 0; buffer.GetCurrentLength(out len); if (bufferLen != len) { //todo: throw invalid data exception. return; } invokeDecodeCompleteEvent(buffer); }
// Get the buffers and sizes to be modified, then pass them // to the textwrite routine. private void DoWork(IMFMediaBuffer pIn) { IntPtr pSrc = IntPtr.Zero; // Source buffer. int lSrcStride; // Source stride. IMF2DBuffer pIn2D = null; // Lock the input buffer. Use IMF2DBuffer if available. Lockit(pIn, out pIn2D, out lSrcStride, out pSrc); try { WriteIt(pSrc); } finally { UnlockIt(pSrc, pIn2D, pIn); } }
private int ReadFromTransform() { MFT_OUTPUT_DATA_BUFFER[] array = new MFT_OUTPUT_DATA_BUFFER[1]; IMFSample iMFSample = MediaFoundationApi.CreateSample(); IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(this.outputBuffer.Length); iMFSample.AddBuffer(iMFMediaBuffer); iMFSample.SetSampleTime(this.outputPosition); array[0].pSample = iMFSample; _MFT_PROCESS_OUTPUT_STATUS mFT_PROCESS_OUTPUT_STATUS; int num = this.transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None, 1, array, out mFT_PROCESS_OUTPUT_STATUS); if (num == -1072861838) { Marshal.ReleaseComObject(iMFMediaBuffer); Marshal.ReleaseComObject(iMFSample); return(0); } if (num != 0) { Marshal.ThrowExceptionForHR(num); } IMFMediaBuffer iMFMediaBuffer2; array[0].pSample.ConvertToContiguousBuffer(out iMFMediaBuffer2); IntPtr source; int num2; int num3; iMFMediaBuffer2.Lock(out source, out num2, out num3); this.outputBuffer = BufferHelpers.Ensure(this.outputBuffer, num3); Marshal.Copy(source, this.outputBuffer, 0, num3); this.outputBufferOffset = 0; this.outputBufferCount = num3; iMFMediaBuffer2.Unlock(); this.outputPosition += MediaFoundationTransform.BytesToNsPosition(this.outputBufferCount, this.WaveFormat); Marshal.ReleaseComObject(iMFMediaBuffer); iMFSample.RemoveAllBuffers(); Marshal.ReleaseComObject(iMFSample); Marshal.ReleaseComObject(iMFMediaBuffer2); return(num3); }
protected override int OnFrame(IMFSample pSample, IMFMediaBuffer pBuffer, long llTimestamp, string ssFormat) { int hr; if (IsCapturing()) { if (BFirstSample) { LlBaseTime = llTimestamp; BFirstSample = false; } // re-base the time stamp llTimestamp -= LlBaseTime; hr = pSample.SetSampleTime(llTimestamp); //if (Succeeded(hr)) //{ // var displayTask = Task<int>.Factory.StartNew(() => Draw.DrawFrame(pBuffer)); // var recordTask = Task<int>.Factory.StartNew(() => PWriter.WriteSample(0, pSample)); // Task.WaitAll(displayTask, recordTask); // hr = displayTask.Result; // if (Succeeded(hr)) // hr = recordTask.Result; //} //Parallel.Invoke(()=>Draw.DrawFrame(pBuffer),()=> PWriter.WriteSample(0, pSample)); if (Succeeded(hr)) { hr = Draw.DrawFrame(pBuffer, !string.IsNullOrEmpty(ssFormat), ssFormat); } if (Succeeded(hr)) { hr = PWriter.WriteSample(0, pSample); } } else { hr = Draw.DrawFrame(pBuffer, !string.IsNullOrEmpty(ssFormat), ssFormat); } return(hr); }
protected override int OnFrame(IMFSample pSample, IMFMediaBuffer pBuffer, long llTimestamp, string ssFormat) { int hr; if (IsCapturing()) { if (BFirstSample) { LlBaseTime = llTimestamp; BFirstSample = false; } // re-base the time stamp llTimestamp -= LlBaseTime; hr = pSample.SetSampleTime(llTimestamp); //if (Succeeded(hr)) //{ // var displayTask = Task<int>.Factory.StartNew(() => Draw.DrawFrame(pBuffer)); // var recordTask = Task<int>.Factory.StartNew(() => PWriter.WriteSample(0, pSample)); // Task.WaitAll(displayTask, recordTask); // hr = displayTask.Result; // if (Succeeded(hr)) // hr = recordTask.Result; //} //Parallel.Invoke(()=>Draw.DrawFrame(pBuffer),()=> PWriter.WriteSample(0, pSample)); if (Succeeded(hr)) hr = Draw.DrawFrame(pBuffer, !string.IsNullOrEmpty(ssFormat), ssFormat); if (Succeeded(hr)) hr = PWriter.WriteSample(0, pSample); } else hr = Draw.DrawFrame(pBuffer, !string.IsNullOrEmpty(ssFormat), ssFormat); return hr; }
///////////////////////////////////////////////////////////////////// // Name: ReadDataIntoBuffer // // Reads data from a byte stream and returns a media buffer that // contains the data. // // pStream: Pointer to the byte stream // cbToRead: Number of bytes to read // ppBuffer: Receives a pointer to the buffer. ///////////////////////////////////////////////////////////////////// void ReadDataIntoBuffer( IMFByteStream pStream, // Pointer to the byte stream. int cbToRead, // Number of bytes to read out IMFMediaBuffer ppBuffer // Receives a pointer to the buffer. ) { IntPtr pData; int cbRead; // Actual amount of data read int iMax, iCur; // Create the media buffer. This function allocates the memory. int hr = MFExtern.MFCreateMemoryBuffer(cbToRead, out ppBuffer); MFError.ThrowExceptionForHR(hr); // Access the buffer. hr = ppBuffer.Lock(out pData, out iMax, out iCur); MFError.ThrowExceptionForHR(hr); try { // Read the data from the byte stream. hr = pStream.Read(pData, cbToRead, out cbRead); MFError.ThrowExceptionForHR(hr); } finally { hr = ppBuffer.Unlock(); MFError.ThrowExceptionForHR(hr); pData = IntPtr.Zero; } // Update the size of the valid data. hr = ppBuffer.SetCurrentLength(cbRead); MFError.ThrowExceptionForHR(hr); }
//------------------------------------------------------------------- // DrawFrame // // Draw the video frame. //------------------------------------------------------------------- public int DrawFrame(IMFMediaBuffer pCaptureDeviceBuffer) { if (m_convertFn == null) { return MFError.MF_E_INVALIDREQUEST; } int hr = S_Ok; IntPtr pbScanline0; int lStride = 0; Result res; Surface pSurf = null; Surface pBB = null; if (m_pDevice == null || m_pSwapChain == null) { return S_Ok; } // Helper object to lock the video buffer. using (VideoBufferLock xbuffer = new VideoBufferLock(pCaptureDeviceBuffer)) { hr = TestCooperativeLevel(); if (Failed(hr)) { goto done; } // Lock the video buffer. This method returns a pointer to the first scan // line in the image, and the stride in bytes. hr = xbuffer.LockBuffer(m_lDefaultStride, m_height, out pbScanline0, out lStride); if (Failed(hr)) { goto done; } // Copy in bitmap if (m_Data != IntPtr.Zero) { unsafe { byte *ipSource = (byte *)m_Data; byte *ipDest = (byte *)pbScanline0; for (int x = 0; x < m_LogoHeight; x++) { CopyMemory(ipDest, ipSource, (uint)m_LogoStride); ipDest += lStride; ipSource += m_LogoStride; } } } // Get the swap-chain surface. pSurf = m_pSwapChain.GetBackBuffer(0); // Lock the swap-chain surface and get Graphic stream object. DataRectangle dr = pSurf.LockRectangle(LockFlags.NoSystemLock); try { using (dr.Data) { // Convert the frame. This also copies it to the Direct3D surface. m_convertFn(dr.Data.DataPointer, dr.Pitch, pbScanline0, lStride, m_width, m_height); } } finally { res = pSurf.UnlockRectangle(); MFError.ThrowExceptionForHR(res.Code); } } // Color fill the back buffer. pBB = m_pDevice.GetBackBuffer(0, 0); m_pDevice.ColorFill(pBB, Color.FromArgb(0, 0, 0x80)); // Blit the frame. Rectangle r = new Rectangle(0, 0, m_width, m_height); res = m_pDevice.StretchRectangle(pSurf, r, pBB, m_rcDest, TextureFilter.Linear); hr = res.Code; if (res.IsSuccess) { // Present the frame. res = m_pDevice.Present(); hr = res.Code; } done: SafeRelease(pBB); SafeRelease(pSurf); return hr; }
protected abstract int OnFrame(IMFSample pSample, IMFMediaBuffer pBuffer, long llTimestamp, string ssFormat);
//------------------------------------------------------------------- // DrawFrame // // Draw the video frame. //------------------------------------------------------------------- public int DrawFrame(IMFMediaBuffer pCaptureDeviceBuffer, bool snap, string snapFormat=null) { if (m_convertFn == null) { return MFError.MF_E_INVALIDREQUEST; } var hr = S_Ok; Result res; Surface pSurf; if (pDevice == null || pSwapChain == null) { return S_Ok; } var r = new Rectangle(0, 0, width, height); // Helper object to lock the video buffer. using (var xbuffer = new VideoBufferLock(pCaptureDeviceBuffer)) { IntPtr pbScanline0; int lStride; try { hr = TestCooperativeLevel(); if (Failed(hr)) throw new InvalidOperationException(); // Lock the video buffer. This method returns a pointer to the first scan // line in the image, and the stride in bytes. hr = xbuffer.LockBuffer(lDefaultStride, height, out pbScanline0, out lStride); if (Failed(hr)) throw new InvalidOperationException(); } catch (InvalidOperationException) { return hr; } // Get the swap-chain surface. pSurf = pSwapChain.GetBackBuffer(0); // Lock the swap-chain surface and get Graphic stream object. try { DataRectangle dr; if (offScreenSurface == null) { dr = pSurf.LockRectangle(LockFlags.NoSystemLock); // Convert the frame. This also copies it to the Direct3D surface. m_convertFn(dr.Data.DataPointer, dr.Pitch, pbScanline0, lStride, width, height); } else { var off = offScreenSurface.LockRectangle(LockFlags.NoSystemLock); MFExtern.MFCopyImage(off.Data.DataPointer, off.Pitch, pbScanline0, lStride, width * offScreenCoeffN / offScreenCoeffD, height); offScreenSurface.UnlockRectangle(); pDevice.StretchRectangle(offScreenSurface, pSurf, TextureFilter.Linear); dr = pSurf.LockRectangle(LockFlags.NoSystemLock); } if (snap) ImageHelper.SnapShot(dr.Data.DataPointer, dr.Pitch, width, height, snapFormat); } finally { res = pSurf.UnlockRectangle(); MFError.ThrowExceptionForHR(res.Code); } } // Color fill the back buffer. var pBB = pDevice.GetBackBuffer(0, 0); pDevice.ColorFill(pBB, DefaultBackColor); // Blit the frame. res = pDevice.StretchRectangle(pSurf, r, pBB, rcDest, TextureFilter.Linear); hr = res.Code; if (res.IsSuccess) { // Present the frame. res = pDevice.Present(); hr = res.Code; } SafeRelease(pBB); SafeRelease(pSurf); return hr; }
protected override int OnFrame(IMFSample pSample, IMFMediaBuffer pBuffer, long llTimestamp, string ssFormat) => Draw.DrawFrame(pBuffer, !string.IsNullOrEmpty(ssFormat), ssFormat);