override protected void OnProcessSample(IMFSample pInputSample, bool Discontinuity, int InputMessageNumber) { MFError throwonhr; IMFMediaBuffer pInput; // While we accept types that *might* be interlaced, if we actually receive // an interlaced sample, reject it. if (m_MightBeInterlaced) { int ix; // Returns a bool: true = interlaced, false = progressive throwonhr = pInputSample.GetUINT32(MFAttributesClsid.MFSampleExtension_Interlaced, out ix); if (ix != 0) { SafeRelease(pInputSample); return; } } // Set the Discontinuity flag on the sample that's going to OutputSample. HandleDiscontinuity(Discontinuity, pInputSample); int i = MFExtern.MFGetAttributeUINT32(Attributes, ClsidRotate, 0); bool IsOdd = (i & 1) == 1; // Does the specified rotation give a different orientation than // the old one? if (IsOdd != m_WasOdd) { // Yes, change the output type. OutputSample(null, InputMessageNumber); m_WasOdd = IsOdd; } // 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. throwonhr = pInputSample.ConvertToContiguousBuffer(out pInput); try { // Process it. DoWork(pInput, (RotateFlipType)i); // Send the modified input sample to the output sample queue. OutputSample(pInputSample, InputMessageNumber); } 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); } }
protected override void OnProcessSample(IMFSample pInputSample, bool Discontinuity, int InputMessageNumber) { MFError throwonhr; // While we accept types that *might* be interlaced, if we actually receive // an interlaced sample, reject it. if (m_MightBeInterlaced) { int ix; // Returns a bool: true = interlaced, false = progressive HResult hr = pInputSample.GetUINT32(MFAttributesClsid.MFSampleExtension_Interlaced, out ix); // Can be S_False. if (hr != HResult.S_OK || ix != 0) { throw new COMException("Interlaced", (int)HResult.E_FAIL); } } IMFMediaBuffer pInput = null; IMFMediaBuffer pOutput = null; IMFSample pOutSample = null; // 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. throwonhr = pInputSample.ConvertToContiguousBuffer(out pInput); try { // Make a duplicate of the input sample DuplicateSample(pInputSample, out pOutSample); // Set the Discontinuity flag on the sample that's going to OutputSample. HandleDiscontinuity(Discontinuity, pOutSample); throwonhr = pOutSample.ConvertToContiguousBuffer(out pOutput); // Process it. DoWork(pInput, pOutput); // Send the new output sample to the output sample queue. OutputSample(pOutSample, InputMessageNumber); } catch { SafeRelease(pOutSample); throw; } 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); SafeRelease(pOutput); SafeRelease(pInputSample); } }
protected void ClearDesiredSampleTime(IMFSample pSample) { if (pSample == null) { throw new COMException("ClearDesiredSampleTime", E_Pointer); } IMFDesiredSample pDesired = null; object pUnkSwapChain = null; // We store some custom attributes on the sample, so we need to cache them // and reset them. // // This works around the fact that IMFDesiredSample::Clear() removes all of the // attributes from the sample. int counter; int hr; hr = pSample.GetUINT32(MFSamplePresenter_SampleCounter, out counter); MFError.ThrowExceptionForHR(hr); try { Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); hr = pSample.GetUnknown(MFSamplePresenter_SampleSwapChain, IID_IUnknown, out pUnkSwapChain); MFError.ThrowExceptionForHR(hr); } catch { } pDesired = (IMFDesiredSample)pSample; pDesired.Clear(); hr = pSample.SetUINT32(MFSamplePresenter_SampleCounter, counter); MFError.ThrowExceptionForHR(hr); if (pUnkSwapChain != null) { hr = pSample.SetUnknown(MFSamplePresenter_SampleSwapChain, pUnkSwapChain); MFError.ThrowExceptionForHR(hr); } SafeRelease(pUnkSwapChain); //SafeRelease(pDesired); }